TWilbert
asked on
Sending an email with attachment w/o mapi
I would like to send an email with an attachment from a client PC which has access to the internet but the logon id used on that PC doesn't have rights to the mail server. Can this be accomplished without using the mapi control? Please supply code.
ASKER
The reason I don't want to send it through a user account is because the application will send an email to individual clients when it has processed their file successfully. I would like for it to come from a "Production account" instead of an individual. It sounds like what I'm looking for is impossible due to security issues. I will settle for an example of using a user account. I have my profile setup in exchange on that PC as well as others. Please provide me with an example that will prevent a logon box from appearing. Last time I tried it the logon box kept appearing asking for a domain name, user id, and password, eventhough I was passing my user name and password.
That logon box is for network access from that machine/user account. It has nothing to do with the e-mail account at all.
Is the client mailbox on a different mail server than the account you want to use?
If it is ...
You can use the WNetAddConnection2 API to log on to a network resource in your program.
Here is something to get you started.
CONSTANTS Needed
Public Const RESOURCETYPE_ANY = &H0
Public Const RESOURCETYPE_DISK = &H1
Public Const RESOURCETYPE_PRINT = &H2
Public Const CONNECT_UPDATE_PROFILE = &H1
TYPE needed
Public Type NETRESOURCE
dwScope As Long
dwType As Long
dwDisplayType As Long
dwUsage As Long
lpLocalName As String
lpRemoteName As String
lpComment As String
lpProvider As String
End Type
DECLARES needed
Public Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" (lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUserName As String, ByVal dwFlags As Long) As Long
Public Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias "WNetCancelConnection2A" (ByVal lpName As String, ByVal dwFlags As Long, ByVal fForce As Long) As Long
Dim NetRes As NETRESOURCE
NetRes.dwType = RESOURCETYPE_DISK
NetRes.lpLocalName = "D:"
NetRes.lpRemoteName = "\\server\share"
NetRes.lpProvider = ""
lpLocalName
Drive letter to Map
Set lpLocalName = "" to NOT map a drive
lpRemoteName
Substitute your remote share path
lpProvider
Set to "" to let the operating system choose the correct provider
RetCode = WNetAddConnection2( NetRes, "password", "username", 0)
If the username you want to connect with is in a different domain use the following format: "domain\username"
The last parameter - 0 above - can also be CONNECT_UPDATE_PROFILE but only if you are mapping a drive to a share (lpLocalName) and you want the connection to be restored. In your case I would think you wouldn't need CONNECT_UPDATE_PROFILE.
RetCode will return 0 if it succeeds.
To disconnect from the resource use:
RetCode = WNetCancelConnection2("ser ver\share" , 0, TRUE)
Substitute the share path from the WNetAddConnection2 call.
The dwFlags parameter - 0 - can also be set to CONNECT_UPDATE_PROFILE. This will remove the "restore connection" setting (if it was used in the WNetAddConnection2 call or if you there already was a restorable connection to the share. In your case I would think you wouldn't need CONNECT_UPDATE_PROFILE.
The fForce parameter - TRUE - will force the connection to close even if there are open files or jobs on the connection. If you use FALSE, the function will fail if there are any open files or jobs.
Check out the documentation for WNetAddConnection2 and WNetCancelConnection2 for more information.
Let me know if this has been helpful.
Is the client mailbox on a different mail server than the account you want to use?
If it is ...
You can use the WNetAddConnection2 API to log on to a network resource in your program.
Here is something to get you started.
CONSTANTS Needed
Public Const RESOURCETYPE_ANY = &H0
Public Const RESOURCETYPE_DISK = &H1
Public Const RESOURCETYPE_PRINT = &H2
Public Const CONNECT_UPDATE_PROFILE = &H1
TYPE needed
Public Type NETRESOURCE
dwScope As Long
dwType As Long
dwDisplayType As Long
dwUsage As Long
lpLocalName As String
lpRemoteName As String
lpComment As String
lpProvider As String
End Type
DECLARES needed
Public Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" (lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUserName As String, ByVal dwFlags As Long) As Long
Public Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias "WNetCancelConnection2A" (ByVal lpName As String, ByVal dwFlags As Long, ByVal fForce As Long) As Long
Dim NetRes As NETRESOURCE
NetRes.dwType = RESOURCETYPE_DISK
NetRes.lpLocalName = "D:"
NetRes.lpRemoteName = "\\server\share"
NetRes.lpProvider = ""
lpLocalName
Drive letter to Map
Set lpLocalName = "" to NOT map a drive
lpRemoteName
Substitute your remote share path
lpProvider
Set to "" to let the operating system choose the correct provider
RetCode = WNetAddConnection2( NetRes, "password", "username", 0)
If the username you want to connect with is in a different domain use the following format: "domain\username"
The last parameter - 0 above - can also be CONNECT_UPDATE_PROFILE but only if you are mapping a drive to a share (lpLocalName) and you want the connection to be restored. In your case I would think you wouldn't need CONNECT_UPDATE_PROFILE.
RetCode will return 0 if it succeeds.
To disconnect from the resource use:
RetCode = WNetCancelConnection2("ser
Substitute the share path from the WNetAddConnection2 call.
The dwFlags parameter - 0 - can also be set to CONNECT_UPDATE_PROFILE. This will remove the "restore connection" setting (if it was used in the WNetAddConnection2 call or if you there already was a restorable connection to the share. In your case I would think you wouldn't need CONNECT_UPDATE_PROFILE.
The fForce parameter - TRUE - will force the connection to close even if there are open files or jobs on the connection. If you use FALSE, the function will fail if there are any open files or jobs.
Check out the documentation for WNetAddConnection2 and WNetCancelConnection2 for more information.
Let me know if this has been helpful.
ASKER
Mark2150 responded to a question on January 1st entitled: "Can my app e-mail a file ?" In which he provided the following answer...
' Initially we'd get a login failure with .LogonUI = False. Changing it to .True produced a
' cc:Mail login that did NOT show a password even tho we're quite clearly setting it below.
' If I entered the password manually the process would work.
'
' The cc:Mail login dialog had a check box "Remember Password". Once this box was checked
' even with LoginUI = True, there was no display of the dialog box. Finally setting LoginUI
' = False, we get silent operation.
This is the exact problem I'm having. We're using Outlook at our shop. Is there not an equivalent solution for non-ccmail users?
' Initially we'd get a login failure with .LogonUI = False. Changing it to .True produced a
' cc:Mail login that did NOT show a password even tho we're quite clearly setting it below.
' If I entered the password manually the process would work.
'
' The cc:Mail login dialog had a check box "Remember Password". Once this box was checked
' even with LoginUI = True, there was no display of the dialog box. Finally setting LoginUI
' = False, we get silent operation.
This is the exact problem I'm having. We're using Outlook at our shop. Is there not an equivalent solution for non-ccmail users?
The problem you described initially is not the same as you referenced from Mark2150. You specifically mentioned that one the things mentioned in the dialog that pops up is DOMAIN.
If the dialog is asking for a Domain then you have a Network logon that is being requested, not a mailbox logon.
Your users PCs must have access to the
mailbox server (or Exchange) or you must attain the resource through your program as I mentioned in my previous reply. You can supply a username and password programmatically to WNetAddConnection2 that does have rights to the mail server. This doesn't have to be the user's account it can be any account.
Once you have established access to the mailserver through WNetAddConnection2, you should be able to use the MAPI control to send the e-mail.
I wish I could be of more help. (and you probably do too!)
If the dialog is asking for a Domain then you have a Network logon that is being requested, not a mailbox logon.
Your users PCs must have access to the
mailbox server (or Exchange) or you must attain the resource through your program as I mentioned in my previous reply. You can supply a username and password programmatically to WNetAddConnection2 that does have rights to the mail server. This doesn't have to be the user's account it can be any account.
Once you have established access to the mailserver through WNetAddConnection2, you should be able to use the MAPI control to send the e-mail.
I wish I could be of more help. (and you probably do too!)
ASKER
I apologize if I'm coming across as being difficult. That isn't my intention. Maybe I'm not explaining the problem well enough. Yes, I'm getting a dialogue box with the heading "Enter Password". The User name field is blank, the Domain field is prefilled, and the password field is blank. I'm passing the User name and password but its not appearing in the boxes. The command buttons that are showing are ...OK Cancel Change Password. If I manually enter the user name and password the email is sent without a problem.
This is you Network Resource authententication dialog.
You need to call WNetAddConnection2 in your code before you attempt your MAPI session. Note that the 2 at the end of the function is important as there are such beasts as WNetAddConnection and WNetAddConnection3.
If you have made the call to WNetAddConnection2 does it fail with an error code?
You need to call WNetAddConnection2 in your code before you attempt your MAPI session. Note that the 2 at the end of the function is important as there are such beasts as WNetAddConnection and WNetAddConnection3.
If you have made the call to WNetAddConnection2 does it fail with an error code?
ASKER
It fails with an error code 67. I'm sure it is because I haven't substituted lpRemoteName with my remote share path. Where do I get this information from?
ASKER
I've resolved the Return code 67 I was getting when calling WNetAddConnection2! I'm one step closer to accomplishing this! I'm now getting a Return code 1244 when calling WNetCancelConnection2.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Wylliker, you have assisted me tremendously! Thank you.
That said, once you have access to the mail server and an account on the mail server then you can get away with using the simple MAPI functions instead of using the MAPI control.
Is there a reason to not send it through a users account?
If so, then you can have an account set up on the mail server that the application knows about and the application can easily use that account.
If this application will only run within your company the above should not be a problem.
If this application will be outside of your company then you would want to make sure that you have users permission, as part of the user agreement/contract before attempting to do this. There could be complications with firewall/proxy blocking and privacy issues as well.