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

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:
Swap out the COM component with a
.NET WCF Client that runs in the CCW
(.NET pretending to be COM)
This COM component calls a WCF
service running as a 64bit process, using the netTcpBinding.
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:
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.
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.

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

Related

ClickOnce winform does not open from start menu, after windows udates, starts working again after one/multiple computer restarts

Since some time the vb.net application I developed stops working for some users, usually after windows 10 updates. It starts working again after restarting computer one or more times, sometimes it takes few days for it to start.
When user tries to reinstall it, it is installed but throws following error:
Retrieving the COM class factory for component with CLSID {X} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
I'm assuming that it has something to do with a Outlook Interop reference in the project.
When outlook is closed and I run this application as admin I am able to start it, when outlook is open I am not able to do it.
When both outlook and the application are open with admin privilegesit works correctly.
I understand that Outlook and the application should run with the same security level, but I'm not running outlook as admin so I'm confused why I need to run the app as admin.
The target CPU is set to 'Any CPU', should I maybe try changing it to 'X86'?
Office version is Office365 Pro
You need to run both applications under the same security context. If both are run under the same user - everything should work correctly.
However, the following error may indicate that Office applications are automated from a service:
80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
The Considerations for server-side Automation of Office article states the following for such errors:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.

Log into Outlook via Process without Dialog for password

When I try to run Outlook via Interop using the profile name it opens a dialog for the password. This script is running from Windows Task Scheduler Task. Does it use the admin account when running these tasks? The profile been made and my email account is the only one loaded in here.
The Always prompt for login credentials is unchecked for the account listed in the profile.
This is a network computer in domain. Outlook 2010.
Profile Switch(link):
Process.Start("Outlook", "/profile profilename")
'logs in with a prompt for the password
How can I pass the password in code and avoid the dialog?
Alternatively, I have a macro that does what I need, but I have not been able to get it to run when the profile loads. This would solve the problem as well. Macros enabled is checked in the Trust Center.
Thanks
First, you need to run both application under the same security context to be able to automate one from another.
This app is being launched from Windows Task Scheduler
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution. Read more about that in the Considerations for server-side Automation of Office article.
As a workaround, you may consider usign a low-level API on which Outlook is based on - Extended MAPI. Or any third-party wrapper around that API such as Redemption.

MAPIInitialize fails when running as a service and when Outlook is open

We have an application that can run as a Windows service (or as a user mode app). As part of it's processing, it launches a second executable that interacts with MAPI to read the contents of an MSG file. The executable is 32 bit. Office is 32 bit. So far, we've only tested using Outlook 2013.
This has worked fine for quite some time, but we've recently discovered a corner case where things do not work.
When we run as a Windows Service, and Outlook is not running in the user's session, then the application runs properly. However, if we launch Outlook, then MAPIInitialize fails with a return code of -7 (0xfffffffd).
I've tried calling with and without the MAPI_NT_SERVICE flag added (honestly, I can't figure out what that flag actually does), but it makes no difference.
So far in our testing, the Windows service account has been the same as the user logged into the Windows session that has Outlook installed - not sure if that might be important or not.
I can't for the life of me figure out how a process running under one session could interfere with a process running in another session.
I found this post a few minutes ago: https://social.msdn.microsoft.com/Forums/office/en-US/7a9cc40a-ffd6-4f83-9973-5410615b4df4/mapi-working-when-accessed-from-normal-application-but-not-from-the-service?forum=outlookdev
I'll give that a shot, but it seems super unlikely that this could be the issue (it's not like we do anything different with COM initialization, and certainly that wouldn't have anything to do with whether Outlook was running or not).
Can anyone point me in direction(s) to pursue this?
=============
More interesting information:
This appears to only happen with Outlook 2013. It definitely does not happen with Outlook 2010.

How to code vb.net for website? I want the UI embedded within the web page of my browser

I have made an exe program using vb.net but I want to make a webpage on which that exe is embedded.
Like the way this site has done.
You already have the source code for your VB.NET application, the path of least resistance is to factor out the desired functionality into a library DLL. Your web server presumably runs Windows and so will probably have ASP.NET capability. Just reference the DLL in your ASP.NET project and call into that instead.
My advice is don't make a rod for your own back by creating your own CGI binaries:
With a CGI application you'll have to generate all of the response headers and markup by yourself, you'll also have to parse any inbound headers, cookies etc yourself. It's a lot of work to replicate functionality already present in ASP.NET
Enabling CGI executables on your web server increases the risk of a security compromise, either through a mistake in your VB.NET executable, or because via some other vector an attacker has been able to upload a malicious executable and run that.

How to develop (NPAPI) COM plugin for Chrome, Firefox, Safari [duplicate]

This question already has answers here:
How to write a browser plugin?
(4 answers)
Closed 9 years ago.
In my legacy web application I need to read user system registry from JS and do some other stuff. I cannot not use ActiveX for security reasons so I have written a plugin. My Plugin consists of a DLL file which is a COM component. This COM component exposes few functions which I call from Java Script code.
In IE I package my DLL in a CAB file and install it, say it's test.dll, in the following way:
<object classid="clsid:some class id here" codebase="test.cab" height="0" width="0" onError="testInstalled=false; return true;" id="testComp"></object>
The above HTML tag install the COM component as plugin in IE and Im able to access the exposed functions of the same from my JS code:
var testCompApp = document.testComp;
testCompApp.callSomeFunction();
It works fine in IE. I need the same functionality in other browsers(Chrome,Firefox, Safari)
Can you pls suggest how to develop plugins for other browsers using my DLL file?
Thanks,
I don't get it: First you say "I can't use ActiveX for security reasons", and then you do the same bad things that ActiveX does in all its dangerous glory: a CAB-packaged COM object running unrestricted native Win32.
How does doing that solve your security concerns with ActiveX?
Leaving aside for a minute the question of "security": if you are not doing "ActiveX" already, you're pretty close. I don't remember off the top of my head all the details of what goes into [the-IE-plug-in-architecture-that-shares-with-other-stuff-the-marketing-moniker-of] "ActiveX", but I think all you are missing to be called "ActiveX" is a few interfaces you must implement. I also suspect that by being shy of "ActiveX" you don't even get to sign your CAB with Authenticode, which would provide your users with a modicum of confidence (assuming you maintain proper controls and key management, and that your users trust you enough to allow your native code to run on their computers).
In any case, that DLL you wrote will only ever run in IE. There is no other browser that supports Win32 native COM objects (whether you choose to follow the ActiveX specification to the letter or not). If you want to do the same thing in other browsers, you are going to have to rewrite it with something else.
I think you have (at most) two options for doing what you want to do:
COM/ActiveX: Native Win32 code in a COM object. What you are doing now. This only works on IE and it's extremely dangerous for users, unless it's done in a controlled environment (e.g. if this is a commercial product to be distributed by an enterprise customer's IT department, or if you have an established presence and a reputation, like some large companies do).
Java:. This would run on all browsers assuming your users have the proper runtime installed and enabled. But it will only work for you if Java allows access to the information you seek via a sandbox-authorized method, because you can't call registry API's from the Java sandbox. The same goes for "the other stuff" you need the plug-in to do.
Ok, so you have a third option:
Reimplement the whole thing in something that is not tied to the browser: a native Windows executable; maybe in a downloadable installer or maybe a .NET program deployed via ClickOnce.
You are in a pickle: You are saying "I have security concerns with running ActiveX but I need to do something dangerous". Any piece of code downloadable and runnable by a web browser that is able to access the registry directly is - necessarily - a dangerous piece of code. Any conceivable technology that allows you to run such code from a browser will immediately elicit the very same security concerns that ActiveX elicits.
Indiscriminate access to the registry is out of the question from a modern browser sandboxed environment, so you either have to find a different source for the specific information you want, or you have to use ActiveX/COM running under IE.