I have created an application that accesses the Exchange Server through MAPI. A Tray app is used to start, stop and configure the application. I have put all of the communication and processing logic into a separate library which processes mail on a timer. When running in Debug mode, the library is accessed directly from the Tray app, but when running in release mode, it is being called by a service installed at the User level. See the diagram below.
I have everything configured to run using an x64 bit version of Outlook 2010. The issue I am having is that when I build and install in Debug (access the library directly), everything works properly. If I install the Release build and run as a service, the MAPI connection is not initializing.
I seem to be accessing the COM object, since I am getting a return value from the method I call rather than an exception. I have set the User account to my own login for the time, so I should have permission to access the profile. Although I could post the initialization code, but I don't believe it will help. I am thinking the issue has more to do with permissions. I have tried running a test install under each of the 4 account types associated with a service, and none of them work. Is it possible that my user account does not have access to my mail profile?
If anyone has any ideas on what I may be doing wrong, I would appreciate the insight.
EDIT
I am getting the HRESULT Cannot change thread mode after it is set.
I was setting thread mode to false initially, but tried changing it to see if it would resolve the issue. Unfortunately it did not. I've added a code snippet below in case someone might find it helpful.
DWORD dwFlags=0;
if(bMultiThreadedNotifications) dwFlags|=MAPI_MULTITHREAD_NOTIFICATIONS;
if(bInitAsService) dwFlags|=MAPI_NT_SERVICE;
if(dwFlags)
{
MAPIINIT_0 MAPIInit={ MAPI_INIT_VERSION, dwFlags };
lastErrorCode = MAPIInitialize(&MAPIInit);
//if(lastErrorCode!=S_OK) return FALSE;
if(FAILED(lastErrorCode)) result = FALSE;
}
else
{
lastErrorCode = MAPIInitialize(NULL);
//if(lastErrorCode!=S_OK) return FALSE;
if(FAILED(lastErrorCode)) result = FALSE;
}