开发者

32bit VB6 application needs to automate 64bit Outlook to send an email without prompting the user

开发者 https://www.devze.com 2023-01-30 06:39 出处:网络
I have a 32bit legacy VB6 application that uses a COM component to automate Outlook to send an email. The requirement is that the email needs to appear in the Sent Items folder in Outlook. To make mat

I have a 32bit legacy VB6 application that uses a COM component to automate Outlook to send an email. The requirement is that the email needs to appear in the Sent Items folder in Outlook. To make matters worse the application is not allowed to pop up the usual security, warning or confirmation messages.

This application was working without any issues until 64bit Office came along. There is no way for a 32bit process to automate a 64bit Outlook.

The idea I came up with was the following:

  1. Swap out the COM component with a .NET WCF Client that runs in the CCW (.NET pretending to be COM)

  2. This COM component calls a WCF service running as a 64bit process, using the netTcpBinding.

  3. The WCF service (running as LOCAL SYSTEM) then launches a 64bit Console application as the user, and makes use of the Extended MAPI library to send the email.

The reason for the 3rd step is two-fold:

  1. MAPI will ask for confirmation if you tell it to send an email. Extended MAPI does not. This meant we had to compile a C++ Extended MAPI library with the correct 64bit header files from Microsoft, and "invoke" that from our .NET code.

  2. Impersonating (term used loosely) the user in WCF results in the incorrect Registry hive loading. In other words when Extended MAPI tries to load the profile from HKCU it fails. This meant we had to laun开发者_如何学运维ch a new process to essentially "RunAs" the correct user.

This all actually works in practice, but I need some explanations for the following:

If I run the Console application with all the information it needs in command line parameters, MAPI fails to login. However, if I compile this same code as a Windows application with 1 Form, with exactly the same code in the form's OnLoad( ) method, then it succeeds. Can anyone explain why?

To run the "WinForms" application from the WCF service as the currently logged on user (not LOCAL SYSTEM) I did the following to get the correct token:

sessionID = (int)WTSGetActiveConsoleSessionId();
ret = WTSQueryUserToken(sessionID, out currentToken);

Is there any way around this? Surely it would be better to use WCF's built-in impersonation.


There is no way for a 32bit process to automate a 64bit Outlook

Not entirely true, if you can create the COM object out of process it will work. Options include creating a small .exe that services as a factory for your COM objects.

See this SO post

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号