开发者

How to detect if a user is accessing an outlook process, that I have started?

I have a C# application, in which I access outlook through the Office PIAs in order to parse appointments. In my application, when I create my outlook object, a new outlook process is created in the开发者_JAVA百科 task manager. When I close my application, I also quit the outlook object. This shuts down the outlook process in my task manager.

My problem is, when the user is also interacting with outlook. Specifically, if the user has outlook opened, when my program closes, my program also closes that user's outlook program. Experimenting with opening outlook both manually and with my program, while watching the task manager, it seems that only one instance of outlook can ever be running at the same time, and both the user and my program then accesses that same instance, so when I close outlook from my program, I also shut down the user's program.

Strangely enough, the reverse is not the case. If the user shuts down outlook, while my program runs, his window will disappear, but the outlook process will not shut down, and my program can still continue. It is as if the window is only a client of the outlook process, although there is no separate process for the window. Is there a way for me to see, if my program is the only one using the outlook process, or if there are any "user window clients" open, so I can avoid shutting down outlook, when it is still in use?


I found a solution myself. I turns out that outlook keeps track of how many explorers are open on it. Reaching zero explorers does not cause a shutdown of the process, but it indicates that no user has any normal outlook window open, so the process can be safely shut down. In my project I have a single class which accesses outlook. My solution is to test for zero explorers in the destructor of that class (the following code assumes "using Outlook = Microsoft.Office.Interop.Outlook;"):

~OutlookAccessor()
{
    try
    {
        Outlook.Application app = new Outlook.Application();
        if (app.Explorers.Count == 0)
        {
            ((Outlook._Application)app).Quit();
        }
        System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
    }
    catch (System.Runtime.InteropServices.COMException)
    {
        ; // nevermind, we're only trying to free the Outlook COM object, and the most probable cause for this exception is that office is not installed.
    }
}

Of course, you have to be careful to close all explorers you use in your code, or the solution will not work, e.g.:

private void AccessOutlook(Outlook.MAPIFolder topfolder)
{
    Outlook.Explorer explorer = null;
    try
    {
        explorer = topFolder.GetExplorer();
        ... // do stuff with the explorer
    }
    finally
    {
        if (explorer != null)
        {
            ((Outlook._Explorer)explorer).Close();
        }
    }
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜