I am attempting to utilize Office interop with C#, but I'm having some difficulties. Executing a test like the one I included below seems to work insofar as it launches Outlook and seems to connect with it. The issue is that if I then try to open the Outlook window (it starts hidden in the tray) I get an error message from Outlook saying The application was unable to start correctly (0xc0000142). I do not get this error if Outlook was already running before I started my application. Am I doing something incorrectly or is something broken?
using System;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookInteropTest1
{
class Program
{
static void Main(string[] args)
{
var app = new Outlook.Application();
Console.ReadKey();
}
}
}
Visual Studio Community 2017 Version 15.2
Office 360 - Outlook Version 1804 Build 9226.2156
Windows 10 Build 17115.1
EDIT: Tested this on Windows 7 and could not reproduce crash. I know that I had this working in Windows 10 at some point. I reinstalled my OS and it still crashes. I'm chocking this up to the typical Microsoft user experience unless anyone has any ideas on how to fix it.
Outlook is a singleton, so creating a new object will return the existing object if Outlook is already running.
In your case you also need to provide namespace to it
olApp = new Outlook.Application();
Outlook.Namespace ns = olApp.GetNamespace("MAPI");
ns.Logon();
I know this is old, but I was having the same issue and perhaps it will help someone in the future:
As IAmRajshah mentioned, only one istance of outlook can run, so, if Outlook is open your code olApp = new Outlook.Application();will crash, you need to "connect" to the active instance of outlook with somenthing like this Oulook.Application olApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application; The link below has a good example of this:
Get and sign in to an instance of Outlook
Related
I am new to Visual Studio 2017 and c#.
My goal is to open a new Outlook window by clicking a button in a small program I wrote for learning reasons.
The problem is that, as far as I know, the Office API look here does not support Office 2016, or better said, any Framework over 2.0
I only found this slightly helpful comment by a user on this side, but they also suggest the Office API which doesn't work anymore.
I am very thankful for every helpful comment!
It doesn't matter which Office interop files are used (to which Office version they belong) - you can still automate Office applications from .Net applications. So, just add a COM reference (for Microsoft Office Outlook) to your application and use the following code:
using System;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
namespace FileOrganizer
{
class Program
{
private void CreateMailItem()
{
Outlook.Application app = new Outlook.Application();
Outlook.MailItem mailItem = app.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = "This is the subject";
mailItem.To = "someone#example.com";
mailItem.Body = "This is the message.";
mailItem.Display(false);
}
}
}
I am trying to get an Outlook Application object in my add-in for Excel.
If there's a running Outlook instance, it should get that, if there isn't any, it should create one, using the Outlook object model.
This is the code I have right now:
public static Outlook.Application GetApplicationObject()
{
Outlook.Application application = null;
if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
application = new Outlook.Application();
}
return application;
}
My problem: it finds Outlook processes, but can't get them, throwing the following error message:
Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))
I tried debugging it step by step, and monitored the task manager. I could see that I have an Outlook instance, but it's only an icon in the right side of the taskbar. Does this mean, that the instance is not fully loaded yet, and it can't be accessed, to get the Application object from it?
I ended up modifying my code, and separating the if-else into 2 try-catches, with their own returns, but I still think that the code above should be usable.
Outlook is a singleton, so new Outlook.Application() will always work - if it is already running, you will get that running object.
Make sure both apps (Excel and Outlook) are running in the same security context. Is either app running with elevated privileges (Run As Administrator)?
I'm writing a console application, which checks the contents of an outlook mailbox, in order to read the contents of specific emails into a database.
This application works fine within Visual studio, whether or not Outlook is open.
If I build the application and run it from the exe it only works when Outlook is open, which isn't really a problem.
However, I need to run it from a scheduled task as it has to run every few minutes. This will not work at all.
I'm using the following code:
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("OUTLOOK");
int collCount = processes.Length;
if (collCount != 0)
{
OutlookApp = Marshal.GetActiveObject("Outlook.Application") as Application;
}
else
{
OutlookApp = new Application();
}
The error message I'm getting is:
System.Runtime.InteropServices.COMException (0x800401E3): Operation
unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))
at System.Runtime.InteropServices.Marshal.GetActiveObject(Guid&
rclsid, IntPtr reserved, Object& ppunk) at
System.Runtime.InteropServices.Marshal.GetActiveObject(String progID)
at ImportCruiseEmails.Program.Main()
On the line :
Marshal.GetActiveObject("Outlook.Application") as Application;
Both Outlook and the console application are running under my user account, which has administrator permissions. I've been pulling my hair out with this all afternoon. Can anybody please shed any light on it? Cheers!
Even through the user accounts are the same, security contexts are different since the scheduler runs as a service. And no Office app can be used in a service.
Your options are
In case of an Exchange Server, use EWS to access the mailbox.
Extended MAPI (C++ or Delphi only)
Redemption (I am its author, any language) - it wraps Extended MAPI and its RDO family of objects can be used from a service.
Does anybody know how to programmatically enable/disable the actual state of the out-of-office auto-responder in Outlook 2007?
Already searched the object browser in VS 2008 and found the enumeration Microsoft.Office.Interop.Outlook.OlBusyStatus but i didn't find any class or anything else using this.
Any idea is appreciated, thanks and regards
UPDATE: Updated the code below using sample code adapted from this blog post which will work better in a wider variety of Outlook installations (e.g. ones using both Exchange and PST or accessing multiple Exchange mailboxes).
Here's code which worked for me on Outlook 2007, to set the OOF status from an external (to Outlook) EXE:
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.ApplicationClass();
Microsoft.Office.Interop.Outlook.NameSpace ns = app.Session;
foreach (Microsoft.Office.Interop.Outlook.Store store in ns.Stores)
{
if (store.ExchangeStoreType == Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olPrimaryExchangeMailbox)
{
store.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x661D000B", true); // false to turn off OOF
break;
}
}
Make sure you're not running that code as Administrator and outlook as non-Administrator-- otherwise you may get a security-related error on Vista.
Note that it will pop up security dialogs inside Outlook to ensure the user is OK with you accessing the Outlook object model. This is normal when outlook object model is accessed from an external EXE.
If, however, you're accessing the object model from an add-in, the code above isn't fully correct: instead of creating a new Outlook.Application object via the constructor, you you need to get a reference to the trusted Outlook.Application object from inside your add-in, like this:
Microsoft.Office.Interop.Outlook.NameSpace ns = this.Application.Session;
foreach (Microsoft.Office.Interop.Outlook.Store store in ns.Stores)
{
if (store.ExchangeStoreType == Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olPrimaryExchangeMailbox)
{
store.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x661D000B", true); // false to turn off OOF
break;
}
}
BTW, there's a good MSDN article on security for add-ins, which may be useful if you run into security dialogs or errors.
I have a requirement where I need to get the data from a folder called "Public folder" which contains global information like book rooms for discussions / meetings etc and this folder is in server and I am able to access this through outlook. How do I access the same programmatically, C# ?
If you're solely on the client use COM via Outlook.
Or use WebDav against Exchange 2003, or check out the new webservices for Exchange 2007.
It all depends where your code will execute and/or the version of Exchange running before deciding the way to go.
You just have to make sure the application is running as a user with permissions to Exchange.
I know you said C#, but if you're willing to experiment a bit, here's a Perl solution I've used successfully in the past:
http://rasterweb.net/raster/code/src/vcalxical_pl.txt
You need IMAP enabled on the Exchange server and this will only work with 2003. In Exchange 2007 calendar information is no longer stored in folders, so this will break. You also said you just needed to get the data, not modify it.
This solution will work with Exchange 2007:
http://blogs.msdn.com/exchangedev/archive/2009/02/05/quick-and-dirty-unix-shell-scripting-with-ews.aspx
Ksempac, look here for a way forward:
http://msdn.microsoft.com/en-us/library/ms268893(VS.80).aspx
The Microsoft.Office.Interop.Outlook namespace is horrible to work with, but with a bit of Googling you can do some cool stuff.
In the past we used Outlook Redemption. It works through extended MAPI so it has more features then Outlook provides with Microsoft.Office.Interop.Outlook
There is also another useful tool - Outlook Spy that allow you to discover Outlook object model in run time.
I modified the code to loop through sub folders, sorry for the delayed response
using System;
using OutLook = Microsoft.Office.Interop.Outlook;
class OutlookFolders
{
static void Main(string[] args)
{
OutLook.Application outlookObj = new OutLook.Application();
GetSubFolders(outlookObj.Session.Folders);
}
private static void GetSubFolders(OutLook.Folders folders)
{
foreach (OutLook.MAPIFolder f in folders)
{
Console.WriteLine(f.Name);
GetSubFolders(f.Folders);
}
}
}