How to start or attach to Outlook using Interop C#? - c#

I'm trying to write a C# program that will either start a new instance of Outlook if none are running, or attach to the first instance if it happens to be running already.
I've found a previous discussion already that pretty much identifies what I'm trying to achieve. The problem with the Microsoft Solution is that some of my Outlook Plugins/Add-ins don't work properly, for example, iManage Filesite/Worksite. The plugin appears to be in the ribbon when Outlook starts, but some functionality is missing and if I try a search etc. Outlook stops responding and crashes. The plugins work properly if outlook is started from the console or like:
System.Diagnostics.Process.Start(#"OUTLOOK.exe");
But then I can never attach to the running Outlook instance because
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
Fails with a COM error (0x800401E3 MK_E_UNAVAILABLE). I can only get around this error if I debug the application and step through it. I've tried allowing time for Outlook to start, switching the active window (changing focus), but none of these options work.

The error message from GetActiveObject most likely means your code and Outlook are running in different security contexts. Make sure neither apps (or both) are running with elevated privileges (Run As Administrator).

Related

Getting error "Cannot create Active X component" from Windows service but not console Application

I have a Windows service written in c# which keeps listening to one Event Hub in Azure. As soon as a message is received, the service processes the message and does some execution and calculation.
As part of the execution, it launches a application called AutoCal (company's own window's application), which is COM component similar to that of Excel.
Earlier I had a web api which does the same calculation/execution. Upon every request it opens AutoCal and does some processing. I have added the AutoCal DLL as reference in the project.
The code to open AutoCal is something similar:
(AutoCal.Application)Interaction.CreateObject("AutoCal.Application.NewInstance").
When I tested this locally, it has perfectly as expected. But once I hosted this on the server, it has thrown an error saying "Cannot create ActiveX component". To rectify this, I have given permission to open COM components to Application Pool of IIS. This has resolved my issue.
Now that I have a windows service which also open the AutoCal, from where do I give CO component permissions. I have searched for it, but everywhere the solution is for ASP.net only.
How can I rectify this issue for Windows service?
PS: When I have written same code in console application, it is working fine.
Without having exact error logs (can you try looking for related errors in the EventViewer?) it's hard to tell what the problem is.
But I would try the following:
In the start menu type Component services and open it (right click - as admin!)
Go to Component services -> My Computer -> DCOM Config folder
You'll see something like this
Find your COM Application in the tree.
Right click it, open properties, go to Security Tab
It will look like this (never mind the title of the tab in the picture, in your case it should be something like AutoCal):
If it's grayed out, like in my case, you can use the following procedure to change the settings on your system, and make this tab configurable:
Go to Start > Run. Enter regedit
Go to the key that is associated with the DCOM component you want to manage: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
Right click on it. Select Permissions
Click Advanced
Change the owner to Administrator or your user account
Click OK
Select Full Control for the Administrators group and owner you selected
Go to Start > Run. Search for services.
Find COM+ System Application. Right click on the service, then click Restart
Once you have the Security tab enabled, you can change the permissions for your COM object. For example - you can allow the user, under which your service runs, to access or activate this COM object.
I hope this helps you, but again, without any additional error info - it's a long shot.
You will want to run it under NETWORK SERVICE, but that's not the problem.
What you're experiencing is all summarised under KB257757.
Considerations for server-side Automation of Office
Your best bet is rewrite it in .Net. If its basic and you're NOT using XML, it might be worth giving that format a go. Back in the day we had to make sure everyone (all our customers) were on MS Office 2003 (turned out IBM were the only ones on 2002 and there's a plugin for 2002 to read 2003).
I know this is not good and I'm sorry to be the bearer of bad news.
Microsoft's stance:
Most server-side Automation tasks involve document creation or editing. Office 2007 supports new Open XML file formats that let developers create, edit, read, and transform file content on the server side. These file formats use the System.IO.Package.IO namespace in the Microsoft .NET 3.x Framework to edit Office files without using the Office client applications themselves. This is the recommended and supported method for handling changes to Office files from a service.

Creating Microsoft Word objects in an ASP.NET Application

I have an IIS 7.5 on a 2008 R2 server running an application using ASP.NET with framework 4.0. The application creates a word report, first it opens an HTML web page, selects all of the content and copies it to a word template and then it saves it in a location. If I run the application form Visual Studio Express 2010, the application runs fine and does everything it should. But when I run it from IIS the application hangs. I have the InternetExplorer object and the Word object set to visible so I can see what's happening (normally is set to false), and no Internet Explorer is visible or Word even though I can see in the task manager that the processes are up and running. If I let it run an exception will be thrown that says:
"This command is not available because no document is open"
When the first action is made with the code is a word.ActiveDocument.Select(); this is after word.Documents.Open(); If I put a word.Activate(); before a word.Documents.Open();another exception will be thrown that says:
"Cannot activate application"
our AppPool is set to our local user with Super Admin rights, the folders have both users, the AppPool and the local user, with all rights, I have done the DCOM Setting to defaults and added missing users. I do know that Microsoft advises against Office Automation but for now we are using this.
I guess the problem is with some permissions but I don't know where else to look. Also it's very strange that the applications are set to visible and the processes are shown in the Task Manager to be up and running but not even the IE window is shown.
EDIT :
I will change the code to use OpenXML SDK as all the information that I've encountered and comments leads to this, but I will leave the question open to see if anyone has more information. Also the other part of the question was that the IE Object is created, initialized and the process is up, but no window is visible even though the object is set to visible anyone can shine some light on this?
I'm using the
InternetExplorer Class.

How To Determine If Outlook Is Fully Launched from my C# Add-In?

Windows users can right-click on any file in explorer and go to Send to > Mail recipient
This launches a new message in a compose inspector with the file attached and some pre-populated text. However, it does not seem to fully launch the Outlook application.
This causes problems when my Add-In tries to close the inspector and run some cleanup code (which it does successfully when Outlook is fully launched). The Add-In suspends and crashes Outlook when trying to run the clean up code because closing the inspector is trying to close Outlook.
Is there a way using C# to determine whether Outlook is fully launched or just in this compose-only mode?
What is the problematic snippet of your code?
You can check if there are any open explorers by checking the Application.Explorers.Count property.

Can an Outlook add-in be tested on a remote machine without registry entries?

I've written solution that consists of outlook 2010 add-in which will serialize an email and moves it to a folder where the server app detects, deserializes it and takes over.
We're getting ready to do some preliminary testing on a remote machine that doesn't have Visual Studio installed
For the server app, I know I can avoid registering the dll's by making sure that they're are in the server executable directory...
Is there anyway, we can avoid messing with the registry for the outlook plug-in, to get this initial testing done. According to this: http://msdn.microsoft.com/en-us/library/vstudio/bb386106(v=vs.100).aspx "You must create a specific set of registry entries when you deploy add-ins"
Are there any tricks to get around this?
Thanks
No, Outlook reads the class name of your addin from the Outlook\Addins key in the registry, then uses that class name to create an instance of the COM object representing your addin.
There is no way to force Outlook to do anything else.

Cannot access excel file

I'm developing a windows service, generating a report. This report has a template. This template is prepared in an excel file. This file is copied to the output folder.
While developing I launched the service like a console application and had no problems accessing this file.
Then I prepared a service installer. The service is installed under Local System account. So this excel template file is marked as content and copied to the installation directory together with the executable as well.
But when the service is launched excel appears to have no access to this file. The service is installed to c:\Program Files (x86)\Our Company\Service Name\. The target OS is Windows Server 2008. While testing I use Windows 7 and run into the same issue.
I use the following code to access excel.
using Excel = Microsoft.Office.Interop.Excel;
//...
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
//the following line throws an exception
Excel.Workbook xlWorkBook = xlApp.Workbooks.Open(#"path");
I also tried to copy the excel template file to some temporary directory (where the service has the right to write - this is tested) and tryed to open it from there, but to no success (while this variant works good in a console application as well).
The error message sais:
Microsoft Office Excel cannot access the file /path/.
There are several possible reasons:
1. The file name or path does not exist.
2. The file is being used by another program.
3. The workbook you are trying to save has the same name as a currently open workbook.
How can I make the windows service access this excel template file? Or is there another alternative?
To safety run Office applications (Excel and others) under user service with Local system account you must know two important things:
1) In Windows Server 2008/2008 R2 you must manually create two folders:
C:\Windows\system32\config\systemprofile\desktop
C:\Windows\SysWow64\config\systemprofile\desktop (for x64 version only)
Without this folders you cannot correct run office Applications from Local SystemAccount
2) If you service is configured without desktop interaction then in the first time launched office application (Excel for example) freeze on user credentials dialog - you cannot see this window in this mode - to resolve this enable desctop interacting, switch to office window after you service run it and manually enter credeentials.
Other information there(use google translater to read).
There is a detailed MS knowledge base article titled Considerations for server-side Automation of Office. Some key excerpts:
User Identity: Office applications assume a user identity when the applications are run, even when Automation starts the
applications. The applications try to initialize toolbars, menus,
options, printers, and some add-ins based on settings in the user
registry hive for the user who launches the application. Many services
run under accounts that have no user profiles (such as the SYSTEM
account or the IWAM_[servername] accounts). Therefore, Office may not
initialize correctly on startup. In this situation, Office returns an
error on the CreateObject function or the CoCreateInstance function.
Even if the Office application can be started, other functions may not
work correctly if no user profile exists.
Interactivity with the desktop: Office applications assume that they are being run under an interactive desktop. In some
circumstances, applications may need to be made visible for certain
Automation functions to work correctly. If an unexpected error occurs,
or if an unspecified parameter is needed to complete a function,
Office is designed to prompt the user with a modal dialog box that
asks the user what the user wants to do. A modal dialog box on a
non-interactive desktop cannot be dismissed. Therefore, that thread
stops responding (hangs) indefinitely. Although certain coding
practices can help reduce the likelihood of this issue, these
practices cannot prevent the issue entirely. This fact alone makes
running Office Applications from a server-side environment risky and
unsupported.
Obviously, as has been pointed out in the comments, using the SYSTEM account is a mistake. You would need to run the service under an account that has a user profile.
But even when you fix that, the other bullet point will kill you. Office applications do indeed assume they are running under an interactive desktop. My advice is to abandon attempting to automate Office from a service. Use a library like Aspose instead. Or run the process on an interactive desktop.
I just faced the same problem.
I have made a .bat file where I called the .exe file.
finally, I called the .bat file from the task scheduler actions.
It just works fine.

Categories

Resources