1

This is my Visual C++ wrapper that initialises own DLL library:

void COutlookManagerEx::Init()
{
    throw_if_fail(m_pInterface.CreateInstance(__uuidof(PTSOutlookLibrary::PTSOutlookLibraryClass)));
    if (IsValid())
        m_pInterface->ShowMicrosoftOutlook();
}

The C# constructor:

public PTSOutlookLibraryClass()
{
    try
    {
        _OutlookApp = new Outlook.Application();
    }
    catch(Exception /* e */)
    {

    }
}

The C# method to display Outlook:

public void ShowMicrosoftOutlook()
{
    // Show Outlook
    if (_OutlookApp.Explorers.Count == 0)
    {
        Outlook.MAPIFolder oFolder = _OutlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
        oFolder.Display();
    }
}

My COutlookManagerEx is a member variable of a CDialog:

private:
    COutlookManagerEx m_OutlookManager;

For some reason, when I close my CDialog object Microsoft Outlook stays open.

Update

Based on similar questions I have tried:

   public void Terminate()
    {
        try
        {
            Marshal.ReleaseComObject(_OutlookApp);
        }
        catch
        {

        }
        finally
        {
            _OutlookApp = null;
        }
    }

And adding my own wrapper and then calling Terminate when my dialog closes but Outlook is still visible.

Community
  • 1
  • 1
Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164

2 Answers2

1

Are you running any VBA macros in Outlook when you instantiate it? Is VBA an option for you? I do automation in Excel in the background, and I've found that I get the most reliable results when I instantiate the program using VB Script and then execute VBA either from inside Excel or through the VB Script interface. That way, I can run the VBS script in the background, and I can leverage VBA commands like DisplayAlerts and Quit to hide things or exit the software. I can also get around user access issues by leveraging a credentials store and executing the VBS as a user with required permissions to access the files (as VBS will start the COM object with the credentials provided at it's own execution time.)

But whatever wrapper you choose to use, you should be sending a quit command to outlook before you close the COM object. I've found that if I don't quit Excel first, and then close the COM object, there's a chance that the software just stays open, especially if it's expecting user input of some kind (IE: "Are you sure you want to quit?"). And of course, on the other end of the spectrum, if you call 'Quit' but don't kill your COM object, you'll have a hanging process.

The order of operations to quit should be from the bottom up. Quit Outlook, then kill the COM object, then end your program.


All that being said:

Automation of Outlook, Excel, and all other office suite programs is unsupported. Unless you're automating some kind of legacy script, or working with people uncomfortable (or unfamiliar) with writing software, you should probably be leveraging the fact that Microsoft Office now follows the open office suite standard:

https://support.microsoft.com/en-us/help/257757/considerations-for-server-side-automation-of-office

You're comfortable with C#, and all office documents are XML files. If you're sending or receiving E-Mails, you could probably use SMTP clients built into C#, or implement something that gets done what you need. If you're building something new, I'd strongly recommend staying away from Office Automation.

  • If you elect to use VBS to run your office suite programs and run VBA inside the VB Script, remember that you may have to deal with late binding! https://support.microsoft.com/en-us/help/245115/using-early-binding-and-late-binding-in-automation – Philippe Haussmann May 06 '19 at 19:42
  • I am afraid I am not in a position to use VBA or any other approach. I have tried `Quit` and it still doesn't work. The only time is works is when I actually close my own application and not just the dialog. Then the entry goes from the processes list. – Andrew Truckle May 06 '19 at 20:17
  • See: https://blogs.msdn.microsoft.com/deva/2010/01/07/best-practices-how-to-quit-outlook-application-after-automation-from-visual-studio-net-client/ – Andrew Truckle May 06 '19 at 20:20
  • 2
    Try calling _OutlookApp.Quit() before calling Terminate(), that should produce the same behavior as closing your application. – Philippe Haussmann May 06 '19 at 20:28
  • 1
    That seemed to do it. – Andrew Truckle May 06 '19 at 20:33
0

Outlook closes when its last window is closed. Your code explicitly displays the Inbox folder in an Explorer. Outlook will stay open until that window is closed.

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
  • But even if I comment out that code and don't display the inbox folder, so that all we do is create the object and do our stuff with no GUI on screen and terminate, Outlook is still running as a process. – Andrew Truckle May 06 '19 at 20:06
  • Yes, that worked. It was suggested in the other answer. – Andrew Truckle May 07 '19 at 04:06