Solved

Sending mail trough ShellExecute

Posted on 2001-09-12
18
487 Views
Last Modified: 2013-11-13
My strings question has transformed into:

I need to send an e-mail trough outlook(express), or whatever e-mail prog the user is using.
So i cannot use winsock to send it out directly.
I used shellexecute in the followin way:

strMailTo = "mailto:" & tmpTo & tmpBody & tmpCC & tmpSubject ' & tmpBCC
'this will launch the statement from the
'     default mail handler
Call ShellExecute(0&, vbNullString, strMailTo, vbNullString, vbNullString, vbNormalFocus)

Now, the problem is that shellexecute does not seem to accept messages longer than 256 bytes (?). And i need to send messages up to 2K. (And if posible with images attached, but i have no idea - apart from contructing a mime mail message wich will be 50k or so- how to do that trough shellexecute.

Any ideas ?

0
Comment
Question by:lobbezoo
18 Comments
 
LVL 69

Accepted Solution

by:
Éric Moreau earned 0 total points
ID: 6477281
mailto will only works if Outlook or Express are properly configured. You better use the free vbSendMail component (http://www.freevbcode.com/ShowCode.Asp?ID=109) that is using SMTP to send e-mails and attachment.
0
 

Author Comment

by:lobbezoo
ID: 6477317
Thanks, but
mailto: works quete well, outlook and outlook express are correctly configured.
I need to go trough them, since the users want the mails i'm sending in their standard mail-app.
They will be given the opportunity to change something (free's me of writing a html-textprocessor), and the messages will be stored in their outbox (send mail).
This is crucial.

So i cannot use any component, plus that i know how to send mail directly trough winsock, that's easy!

Steven
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 6477382
See what I got from VBPJ 101 techtips 10th edition:


Fill In the E-Mail Fields
ShellExecute is one of the most flexible Win32 APIs. Using ShellExecute, you can pass any filename, and if the file?s extension is associated to a registered program on the user?s machine, the correct application opens and the file is played or displayed.
     In the February 1998 101 Tech Tips supplement, Jose Rodriguez Alvira showed ShellExecute?s Internet power (<Create Internet-Style Hyperlinks>). If you pass an HTTP URL, the user?s default 32-bit Web browser opens and connects to the site. If you pass an e-mail address that has been prefaced with <mailto:>, the user?s default 32-bit e-mail client opens a new e-mail note with the address filled in.
     Here?s how to automatically get a lot more than just the e-mail addresses filled in. If you want to include a list of CC recipients, BCC recipients, or your own subject text or body text, you can create a string variable, add the list of primary addresses (separated by semicolons), then a question mark character and element strings prefaced like this:

For CCs (carbon copies): &CC= (followed by list)
For blind CCs: &BCC= (followed by list)
For subject text: &Subject= (followed by text)
For body text: &Body= (followed by text)
To add an attachment: &Attach= (followed by a valid file path within chr(34)?s)

To use this trick, create a new VB project, add a form, and add six textboxes and a button (cmdSendIt). Paste this into the form?s Declarations section:

Private Declare Function ShellExecute Lib "shell32.dll" _
     Alias "ShellExecuteA" (ByVal hWnd As Long, _
     ByVal lpOperation As String, ByVal lpFile As String, _
     ByVal lpParameters As String, ByVal lpDirectory _
     As String, ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL = 1

Paste this code into the button?s Click event:

Private Sub cmdSendIt_Click()
     Dim sText As String
     Dim sAddedText As String
     If Len(txtMainAddresses) Then
          sText = txtMainAddresses
     End If
     If Len(txtCC) Then
          sAddedText = sAddedText & "&CC=" & txtCC
     End If
     If Len(txtBCC) Then
          sAddedText = sAddedText & "&BCC=" & txtBCC
     End If
     If Len(txtSubject) Then
          sAddedText = sAddedText & "&Subject=" & txtSubject
     End If
     If Len(txtBody) Then
          sAddedText = sAddedText & "&Body=" & txtBody
     End If
     If Len(txtAttachmentFileLocation) Then
          sAddedText = sAddedText & "&Attach=" & _
               Chr(34) & txtAttachmentFileLocation & Chr(34)
     End If
     sText = "mailto:" & sText
     ' clean the added elements
     If Len(sAddedText) <> 0 Then
          ' there are added elements, replace the first
          ' ampersand with the question character
          Mid$(sAddedText, 1, 1) = "?"
     End If
     sText = sText & sAddedText
     If Len(sText) Then
          Call ShellExecute(Me.hWnd, "open", sText, _
               vbNullString, vbNullString, SW_SHOWNORMAL)
     End If
End Sub

You can?t have spaces between the ampersands and tags, or between the tags and the equal signs. You don?t have formatting options, so body text will be one paragraph. However, when you use this technique, program errors are e-mailed to you with full details, and you can create real e-mail applets in a just a few seconds. It beats automating a full e-mail program.
     In addition, almost all this functionality is possible in HTML MailTo tags. Here is a sample:

feedback@smithvoice

I have yet to get HTML to do the attachments, but attachments are no problem in VB.

Editor?s Note: The full functionality of these extra fields is available in e-mail clients that are totally Exchange-compliant. Some or all of the extra fields might not work with noncompliant e-mail clients.


0
 

Author Comment

by:lobbezoo
ID: 6477735
That's a very interesting article.
however, it does not respond my question.
Also: I tried to do attachements: does not work.

may what i want is not possible ?
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 6477788
You may have a problem with your code because I can send more then 255 characters. I just test it with 300 without problems.

Have you read the notes at the bottom of the message?
0
 

Author Comment

by:lobbezoo
ID: 6477845
I tested exactly :
464 Characters = OK, 465 = Not OK
Yeah i've red those words.
I'm testing with Outloo Express 5 on a WIN98 machine.
You cannot find more standard.
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6477914
Hearing...
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 6478233
I persist to say that you have a problem with your code or with the text that you are trying to send.

This is my shorten test code:

Private Declare Function ShellExecute Lib "shell32.dll" _
    Alias "ShellExecuteA" (ByVal hWnd As Long, _
    ByVal lpOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory _
    As String, ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL = 1

Private Sub Command1_Click()
Dim sText As String
Dim sAddedText As String

    sText = "<youremail@x.com>"
    sAddedText = sAddedText & "&Subject=Test"
    sAddedText = sAddedText & "&Body=" & Text1.Text
    sText = "mailto:" & sText
    ' clean the added elements
    If Len(sAddedText) <> 0 Then
         ' there are added elements, replace the first
         ' ampersand with the question character
         Mid$(sAddedText, 1, 1) = "?"
    End If
    sText = sText & sAddedText
    If Len(sText) Then
         Call ShellExecute(Me.hWnd, "open", sText, _
              vbNullString, vbNullString, SW_SHOWNORMAL)
    End If
End Sub


And this is the content of text1:

Text1
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
fin
0
 
LVL 27

Expert Comment

by:planocz
ID: 6478351
Hi lobbezoo,

Here is some code that you might try in place of the shell...
It seems to work better than the shell.

'Place this code in your module

Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&

Public Type STARTUPINFO
       cb              As Long
       lpReserved      As String
       lpDesktop       As String
       lpTitle         As String
       dwX             As Long
       dwY             As Long
       dwXSize         As Long
       dwYSize         As Long
       dwXCountChars   As Long
       dwYCountChars   As Long
       dwFillAttribute As Long
       dwFlags         As Long
       wShowWindow     As Integer
       cbReserved2     As Integer
       lpReserved2     As Long
       hStdInput       As Long
       hStdOutput      As Long
       hStdError       As Long
End Type

Public Type PROCESS_INFORMATION
       hProcess    As Long
       hThread     As Long
       dwProcessID As Long
       dwThreadID  As Long
End Type

Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
       hHandle As Long, ByVal dwMilliseconds As Long) As Long

Public Declare Function CreateProcessA Lib "kernel32" (ByVal _
       lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
       lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
       ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
       ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
       lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long

Public Declare Function CloseHandle Lib "kernel32" _
       (ByVal hObject As Long) As Long

Public Declare Function GetExitCodeProcess Lib "kernel32" _
       (ByVal hProcess As Long, lpExitCode As Long) As Long

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'*********************************************************8

Public Function ExecCmd(cmdline$)

  Dim proc As PROCESS_INFORMATION
  Dim Start As STARTUPINFO
  Dim appname As String
  Dim ret As Long
 
  ' Initialize the STARTUPINFO structure: make dos window not flash
  With Start
      .cb = CLng(Len(Start))
      .wShowWindow = 0
      .dwFlags = 1&
      .lpReserved = ""
      .lpDesktop = ""
      .lpTitle = ""
      .cbReserved2 = 0
      .lpReserved2 = 0&
 End With

' Start the shelled application:
    ret = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
          NORMAL_PRIORITY_CLASS, 0&, 0&, Start, proc)

 DoEvents
 Sleep 3500
 
  ' Wait for the shelled application to finish:
  ret& = WaitForSingleObject(proc.hProcess, INFINITE)
  Call GetExitCodeProcess(proc.hProcess, ret&)
  Call CloseHandle(proc.hProcess)
  ExecCmd = ret&

End Function

'Place this code in your code  like example Form1
'with a command button for testing

Private Sub Command1_Click()
'********* code in the rest of your project **********
 Dim retval As Long
 Dim cmdline As String
 
 'CHANGE THE CODE TO FIT YOUR NEEDS
strMailTo = "mailto:" & tmpTo & tmpBody & tmpCC & tmpSubject ' & tmpBCC
retval = ExecCmd(strMailTo)  
'*********************

End Sub
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:lobbezoo
ID: 6485699
Hi,

I'm sorry for the delay, but my wife had to go to the
hospital unexpectetly.
Now that all is in order:

I tested again the code from emoreau in a new project.
I get the same error, so maybe there is a difference in version for the dll that has shellexec ?

I have win98 , dll version : 4.72.3612.1700

I'll now start trying the solution of planosz.
0
 

Author Comment

by:lobbezoo
ID: 6485740
To Planosz:
The CreateProcess command does not
know what to do with "mailto:xxx@q.l"
It only reacts to the full executable filename.

I'm still testing if i cann use it, since it's not
to hard to find the exe name of the mail client in the
registry.

I'll get back to you guy's.
0
 

Author Comment

by:lobbezoo
ID: 6485825
To Planosz:
The CreateProcess command does not
know what to do with "mailto:xxx@q.l"
It only reacts to the full executable filename.

I'm still testing if i cann use it, since it's not
to hard to find the exe name of the mail client in the
registry.

I'll get back to you guy's.
0
 

Author Comment

by:lobbezoo
ID: 6488300
Hi,
I did all the testing and still it does not work.
When I use the routine from Planosz, i cannot get a mail command running.
I can start OE, but without any further commands.

Any ideas ?
0
 

Author Comment

by:lobbezoo
ID: 6514831
here's the solution (if anyone is interested)

You make an mime mail message with
html, images, sound, whatever
into a file called x.eml
In it you should set X-Unsent: 1
Then you start Outlook express with param: /eml:x.eml
via shellexec ou just shell, whatever you like.
And there you go!
Works as a charm.

Steven
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 6521926
Ask the community support to gives you your points back and move this question to PAQ.
0
 

Author Comment

by:lobbezoo
ID: 6524073
Ok, but how do i do that, and what's PAQ ?
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 6524211
>>Ok, but how do i do that

Ask a 0 point question at http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt

>>and what's PAQ

Previously Ask Question
0
 
LVL 3

Expert Comment

by:modder
ID: 6526919
Refunded your points and force accepted first comment posted to make this a PAQ
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Having just graduated from college and entered the workforce, I don’t find myself always using the tools and programs I grew accustomed to over the past four years. However, there is one program I continually find myself reverting back to…R.   So …
This article will show, step by step, how to integrate R code into a R Sweave document
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now