Results 1 to 15 of 15

Thread: SMTP mail program refuses to work unless VB is installed

  1. #1

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8

    SMTP mail program refuses to work unless VB is installed - Why????

    This code reads an input file to get the SMTP mail server, sender, recipient, subject, and message text. It then proceeds to send e-mail until end-of-file.

    The code runs perfectly on machines where VB has been installed. It refuses to run on machines where VB has not been installed. You can install VB on a "fresh" machine and immediately uninstall it and the code will still work fine.

    As information, I used the add-in package and deployment wizard to create an installation package. All the .DLLs needed to run VB programs are included in the package as well as winsock.

    The installation goes smoothly. When requested for a reboot (due to the VB support file garbage), I do so and run the setup app again (this installs the app on the second go-round). It completes normally.

    The code will run on non-VB machines, but for some reason either cannot connect with the server or cannot hear back from the server if VB has not been installed on the particular machine...Therefore, it just sits there.

    Again, install the app on a machine upon which VB has been installed in the past and, presto, it works flawlessly. What is it that VB installation does that allows this code to work?


    For the sample to work, you need to have a form and add a winsock control to it.


    Dim spacepos As Integer
    Dim Holder As String
    Dim txtServer As String
    Dim txtTo As String
    Dim txtFrom As String
    Dim txtSubject As String
    Dim txtText As String
    Dim sCommand As String
    Dim StrStatus As String
    Dim outtext As String
    Dim X As Long
    Dim I As Long
    Dim InputString(5000) As String * 500

    Private Sub Form_Load()
    Text1.Text = Now

    ' Open Input File
    Open "c:\InMsg.txt" For Input As #1

    If Err <> 0 Then
    Msg = "Error: Input file cannot be opened. Terminating Session"
    MsgBox Msg
    End If

    I = 1
    While Not EOF(1)
    Line Input #1, InputString(I)
    I = I + 1
    Wend

    ' Data is now in an array so we can close the input file.
    Close #1


    ' Open Output File
    Open "c:\outmsg.txt" For Output As #2

    If Err <> 0 Then
    Msg = "Error: Output file cannot be opened. Terminating Session"
    MsgBox Msg
    End If

    X = 1
    Getnext

    End Sub
    Sub Getnext()

    ' We'll check to see if the counter (X) = the number of records in the array. If so end
    ' as the last number in the array is a blank record. If we're not ready to end, call sendit.
    ' Sendit will send the message and increment the counter (X) by 1 and send the code back
    ' here to see if it needs to stop.

    If X >= I Then
    Close #2
    End
    Exit Sub
    End If

    sendit

    End Sub
    Sub sendit()

    ' This logic decodes the input file and initiates communication from the server. Then, the
    ' code will wait for a response from the server. See wsTCP_DataArrival.

    ' Yeah, this is a funky delimiter strategy
    txtServer = Left(InputString(X), InStr(InputString(X), "\-/") - 1)
    txtTo = Left(InputString(X), InStr(InputString(X), "\\-//") - 1)
    txtTo = Mid(txtTo, InStr(txtTo, "\-/") + 3)
    txtFrom = Left(InputString(X), InStr(InputString(X), "\\\-///") - 1)
    txtFrom = Mid(txtFrom, InStr(txtFrom, "\\-//") + 5)
    txtSubject = Left(InputString(X), InStr(InputString(X), "\\\\-////") - 1)
    txtSubject = Mid(txtSubject, InStr(txtSubject, "\\\-///") + 7)
    txtText = Mid(InputString(X), InStr(InputString(X), "\\\\-////") + 9)

    ' Replace spaces in From party with "_"
    Holder = txtFrom
    spacepos = InStr(Holder, Chr$(32))

    ' SMTP standards say the From party cannot have spaces in it. Replace them here.
    While spacepos > 0
    Mid(Holder, spacepos, 1) = "_"
    spacepos = InStr(Holder, Chr$(32))
    Wend

    txtFrom = Holder

    ' Start communicating with the server.
    Me.wsTCP.Close
    Me.wsTCP.RemotePort = 25
    Me.wsTCP.RemoteHost = txtServer
    Me.wsTCP.Connect

    End Sub

    Private Sub wsTCP_DataArrival(ByVal bytesTotal As Long)

    ' This logic waits on a reply from the server. Depending on the reply, the server will send
    ' farm out the response to subs. If a message is sent ok, or if there is an error, the code
    ' writes a log entry and loops back to check for the end of the input file.

    On Error Resume Next

    Dim MsgIn As String
    Dim sCode As Integer

    Me.wsTCP.GetData MsgIn
    sCode = Val(Left(MsgIn, 3))


    If sCode = 220 Then
    Send220
    Exit Sub
    End If

    If sCode = 250 Then
    send250
    Exit Sub
    End If

    If sCode = 354 Then
    send354
    Exit Sub
    End If

    If sCode = 221 Then
    outtext = "Message sent successfully." & " Server = " & txtServer & " Recipient = " & txtTo & " Sender = " & txtFrom & " Subject = " & txtSubject & " Message = " & txtText
    Print #2, outtext

    X = (X + 1)
    Getnext
    Exit Sub
    End If

    If sCode = 501 Then
    outtext = "Error occurred sending message." & " Server = " & txtServer & " Recipient = " & txtTo & " Sender = " & txtFrom & " Subject = " & txtSubject & " Message = " & txtText
    Print #2, outtext

    X = (X + 1)
    Getnext
    Exit Sub
    End If

    'If you got here, something bad and unexpected happened so exit the sub
    outtext = "Error occurred sending message." & " Server = " & txtServer & " Recipient = " & txtTo & " Sender = " & txtFrom & " Subject = " & txtSubject & " Message = " & txtText
    Print #2, outtext

    Getnext
    Exit Sub

    End Sub
    Private Sub Send220()
    Me.wsTCP.SendData "HELO " & txtServer & vbCrLf
    End Sub
    Private Sub send250()
    Select Case sCommand
    Case ""
    sCommand = "MAIL FROM:"
    Me.wsTCP.SendData sCommand & txtFrom & vbCrLf
    Case "MAIL FROM:"
    sCommand = "RCPT TO:"
    Me.wsTCP.SendData sCommand & txtTo & vbCrLf
    Case "RCPT TO:"
    sCommand = "DATA"
    Me.wsTCP.SendData sCommand & vbCrLf
    Case Else
    sCommand = ""
    StrStatus = "message sent"
    Me.wsTCP.SendData "QUIT" & vbCrLf
    End Select

    End Sub
    Private Sub send354()

    Me.wsTCP.SendData "DATE: " & Format(Now, "h:mm:ss") & vbCrLf _
    & "FROM: " & txtFrom & vbCrLf _
    & "TO: " & txtTo & vbCrLf _
    & "SUBJECT: " & txtSubject & vbCrLf & vbCrLf _
    & txtText & vbCrLf & "." & vbCrLf
    End Sub





  2. #2
    Lively Member
    Join Date
    Jun 1999
    Location
    Garden Grove, CA, USA
    Posts
    110

    SMTP server

    Are you sure the smtp server is correct? Your application doesn't have a Sub rotine to message the user if the smtp is correct if not it just gonna try to connect to the server and stop by itself... that's what i think is wrong...

  3. #3

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8

    SMTP Mail

    Yes, the SMTP server name is correct. All I have to do to get the code to work is install VB, uninstall VB and, everything works perfectly. I have no idea what VB changes, but it does something.

    Bill Adams

  4. #4
    Guest

    Yes, the SMTP server name is correct. All I have to do to get the code to work is install VB, uninstall VB and, everything works perfectly. I have no idea what VB changes, but it does something.

    Bill Adams
    Try checking the versions of the files you use(dll's ocx's(winsock.dll etc)), check the version on the target machine, and check the versions on your machine

  5. #5

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8
    I wrote a VB app that would get all the filenames of the .dlls in the system32 directory. I ran the app on a "fresh" machine. I then installed VB and uninstalled VB. I ran the VB app again to suck off the file names and compared the two listings. I found 16 files that VB left behind.

    I proceeded to copy the 16 .dlls to another "fresh" machine and tried to register them (some registered some would not). I then installed my SMTP app, but again, no success.

    To test for a problem with winsock, I created a VB chat application that uses winsock. I had no problem at all with that app functioning on a "fresh" machine. based on this, the problem does not appear to be related to winsock.

    In regards to checking the versions of .dlls, this is a good idea, but the only .dll that I am aware my SMTP application is using is winsock. I am distributing winsock in my installation package.

    At this point, I am really stumped! VB must do something behind the scenes in regards to communication enabling, parameter setting, etc.

  6. #6
    Guest
    What kind of error do you get(if you get an error at all).

    Try inserting some debug code(write somthing to a file at the start of every sub or something and look where it stops, compare the file with a file an a working machine)). Save all the data you send and receive to a file, etc.




  7. #7

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8
    The code completes the:

    ' Start communicating with the server.
    Me.wsTCP.Close
    Me.wsTCP.RemotePort = 25
    Me.wsTCP.RemoteHost = txtServer
    Me.wsTCP.Connect

    Therefore, I cannot tell whether the Me.wsTCP.Connect is being sent into oblivion or whether there is something preventing the data arrival of the "handshake" from the server. The code generates no error.

    Because the code never receives anything back it just sits there, waiting for a response from the server which doesn't come.

    We have Visual Studio and reportedly, there is a tracer utility (Spy++?) that shows windows processes that fire whenever anything happens. Apparently, you can selectively turn on the types of processes you want to monitor. Maybe this will help me trouble-shoot.

    Perhaps I can turn off reporting for everything except communications functions and see what the SMTP code does behind the scenes. Maybe this will give insight into which specific Windows components I need to worry about in the installation package.

    Has anyone used this before?

  8. #8
    Guest
    Are you trapping the error event of the winsock?

    You could also check the state of the winsock, maybe it stays on sckConnecting(6) or sckError(9)
    It should become sckConnected(7)



  9. #9

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8
    The code generates no error. I have not checked the state of the winsock control, however. I suppose I could put in a message box and a timer that would report the state.

    I would have to recompile the project and install on another "fresh" machine since the code runs flawlessly on my VB machine.

  10. #10
    Guest
    Actually Bill's method is better for he waits until the server is ready to receive a response.

  11. #11

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8
    Man do I feel like a dummy,...sort of.

    I tried running the above code on a non-VB machine again yeasterday and it DOES work in this form. BUT this was originally coded as a SMTP CONTROL. In that form, it DOES NOT work.

    As long as I have a form with a winsock control on it (compile as an .exe) the code will work. If I instantiate a winsock control (no form) and compile the code as a control (.ocx), the code only works if VB is installed. (I do register the SMTP control, etc., etc.).

    Following is the code for the control. It is courtesy of Igor Ostrovsky of Ostrosoft. I have made some modifications from the original code. Igor is distributing it as freeware at www.ostrosoft.com:

    Option Explicit

    Dim strServ As String
    Dim strTo As String
    Dim strFrom As String
    Dim strSubj As String
    Dim strMsg As String
    Dim strStatus As String
    Dim strwsStatus As String
    Dim J As Integer

    ' *****!!!!!*****
    ' Dim winsock control here
    Private WithEvents wsTCP As Winsock

    Public Event ConnectSMTP()
    Public Event SendSMTP()
    Public Event CloseSMTP()
    Public Event ErrorSMTP(ByVal Number As Integer, Description As String)

    Private sCommand As String

    Public Property Let Server(ByVal strTemp As String)
    strServ = strTemp
    PropertyChanged "Server"
    End Property

    Public Property Let SendTo(ByVal strTemp As String)
    strTo = strTemp
    PropertyChanged "SendTo"
    End Property

    Public Property Let MessageSubject(ByVal strTemp As String)
    strSubj = strTemp
    PropertyChanged "MessageSubject"
    End Property

    Public Property Let MessageText(ByVal strTemp As String)
    strMsg = strTemp
    PropertyChanged "MessageText"
    End Property

    Public Property Let MailFrom(ByVal strTemp As String)
    strFrom = strTemp
    PropertyChanged "MailFrom"
    End Property

    Public Property Get Server() As String
    Server = strServ
    End Property

    Public Property Get SendTo() As String
    SendTo = strTo
    End Property

    Public Property Get MessageSubject() As String
    MessageSubject = strSubj
    End Property

    Public Property Get MessageText() As String
    MessageText = strMsg
    End Property

    Public Property Get MailFrom() As String
    MailFrom = strFrom
    End Property

    Public Property Get Status() As String
    Status = strStatus
    End Property

    Public Property Get wsStatus() As String
    wsStatus = strwsStatus
    End Property

    Public Sub Connect()
    On Error Resume Next


    ' ******!!!!!*****
    ' Instantiation without a form

    Set wsTCP = New Winsock

    wsTCP.RemotePort = 25
    wsTCP.RemoteHost = strServ
    wsTCP.Connect

    strStatus = "Connecting to SMTP server"

    J = 1
    For J = 1 To 20
    Sleep 100
    strwsStatus = wsTCP.State
    DoEvents
    Next J

    If Err.Number > 0 Then
    RaiseEvent ErrorSMTP(Err.Number, Err.Description)
    Err.Clear
    End If
    End Sub

    Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    Server = PropBag.ReadProperty("Server")
    SendTo = PropBag.ReadProperty("SendTo")
    MailFrom = PropBag.ReadProperty("MailFrom")
    MessageSubject = PropBag.ReadProperty("MessageSubject")
    MessageText = PropBag.ReadProperty("MessageText")
    End Sub

    Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "Server", Server
    PropBag.WriteProperty "SendTo", SendTo
    PropBag.WriteProperty "MailFrom", MailFrom
    PropBag.WriteProperty "MessageSubject", MessageSubject
    PropBag.WriteProperty "MessageText", MessageText
    End Sub

    Private Sub wsTCP_Connect()
    strStatus = "Connected to SMTP server"
    End Sub

    Private Sub wsTCP_DataArrival(ByVal bytesTotal As Long)
    On Error Resume Next
    Dim MsgIn As String: Dim sCode As Integer
    wsTCP.GetData MsgIn
    sCode = Val(Left(MsgIn, 3))
    Select Case sCode
    Case 220
    RaiseEvent ConnectSMTP
    wsTCP.SendData "HELO " & strServ & vbCrLf
    Case 221
    wsTCP_Close
    Exit Sub
    Case 250
    Select Case sCommand
    Case "MAIL FROM:"
    sCommand = "RCPT TO:"
    wsTCP.SendData sCommand & strTo & vbCrLf
    Case "RCPT TO:"
    sCommand = "DATA"
    wsTCP.SendData sCommand & vbCrLf
    Case ""
    sCommand = "MAIL FROM:"
    wsTCP.SendData sCommand & strFrom & vbCrLf
    Case Else
    sCommand = ""
    strStatus = "Message sent"
    wsTCP.SendData "QUIT" & vbCrLf
    RaiseEvent SendSMTP
    End Select
    Case 354
    wsTCP.SendData "DATE: " & Format(Now, "h:mm:ss") & vbCrLf _
    & "FROM: " & strFrom & vbCrLf _
    & "TO: " & strTo & vbCrLf _
    & "SUBJECT: " & strSubj & vbCrLf & vbCrLf _
    & strMsg & vbCrLf & "." & vbCrLf
    Case Is > 400
    sCommand = ""
    strStatus = "SMTP session error"
    RaiseEvent ErrorSMTP(sCode, Mid(MsgIn, 5))
    wsTCP.SendData "QUIT" & vbCrLf
    End Select

    If Err.Number > 0 Then
    strStatus = "SMTP control error"
    RaiseEvent ErrorSMTP(Err.Number, Err.Description)
    Err.Clear
    End If
    End Sub

    Private Sub wsTCP_Error(ByVal Number As Integer, Description As String, ByVal sCode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
    strStatus = "SMTP connection error"
    RaiseEvent ErrorSMTP(ByVal Number, Description)
    wsTCP.Close
    End Sub

    Private Sub wsTCP_Close()
    wsTCP.Close
    strwsStatus = wsTCP.State
    Set wsTCP = Nothing
    strStatus = "SMTP session closed"
    RaiseEvent CloseSMTP
    End Sub



    Sorry guys for somewhat of a wild goose chase. I did not anticipate that the code would behave differently if the winsock control was instantiated within the SMTP code instead of being on a form.

    I still want to get this to work as a control, however, as it would be infinitely more portable. Do you have any suggestions that would get this code to work correctly on non-Vb machines as a .ocx?

    THANKS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  12. #12
    Lively Member
    Join Date
    Jun 1999
    Location
    Garden Grove, CA, USA
    Posts
    110

    Yes...

    It only works if the user have a winsock control which u call from when in VB. Remember u used that winsock control to create your control. it only work with out a control is only when you use raw API for the SMTP control that you created..

  13. #13

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8
    Why?

  14. #14
    Guest
    It will work, just make sure you distribute the winsock.ocx with your program.

    Build your ocx, create a dependency file(through the package and deployment wizard), this will create a file wich contains all the neccassery files for your ocx(winsock.ocx, vbdll's).

    Next create a setup for your program, include the ocx(now vb will see and read the dependecy file and notice that you use the winsock and it will add the winsock in your package.).

    Hope this helps.

  15. #15

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Location
    Richmond, VA
    Posts
    8
    I did create such an installation package that included winsock...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width