1

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 launch 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.

  • 1
    Choosing the 64-bit version of Office is asking for trouble. If compatibility is an issue go with the 32-bit version. 64-bit versions only give you an advantage when dealing with extremely large documents (spreadsheets in particular). 64 is not always better than 32. Also see http://blogs.technet.com/b/office2010/archive/2010/02/23/understanding-64-bit-office.aspx: "For these reasons, we recommend running 32-bit Office 2010 even on 64-bit Windows operating systems for better compatibility". Further information here: http://msdn.microsoft.com/en-us/library/ee691831%28office.14%29.aspx – Dirk Vollmar Dec 14 '10 at 13:58
  • You don't always get to choose what a user is running. – Joe Dec 14 '10 at 14:05
  • Joe is right. Our users get their computers pre-built from the dealers with whatever OS and version of Office they feel like pushing. We have no control over that. – CSharpDevCT Dec 14 '10 at 14:13
  • Outlook runs as an out-of-process COM server. A 32-bit app should not have any trouble using it, COM bridges the divide. Did you actually verify that your VB6 app no longer works? What kind of error code do you see? – Hans Passant Dec 14 '10 at 14:18
  • Hans: Outlook pops up a message saying that it is unable to open the profile for this user. – CSharpDevCT Dec 14 '10 at 14:36
  • Have you looked at REDEMPTION for outlook? It's a very handy COM component, works with .net and allows you to bypass many of the security prompts when working with Outlook. – DarinH Dec 14 '10 at 15:40
  • drventure: Redemption is a pain in the ass to work with. Also there will be no way for it to access the users 64-bit profile when running inside a 32-bit process. My limitation is that this 32-bit process is an old VB6 application that is very near end-of-life so there is no scope to migrate it to .NET. – CSharpDevCT Dec 15 '10 at 13:36

1 Answers1

1

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

Community
  • 1
  • 1
Hannes de Jager
  • 2,903
  • 6
  • 37
  • 57