none
Implement IMAPIStore.Advise in C# RRS feed

  • Question

  • For some reasons, I need subscribe MAPI Store events in C#. I can successfully get IMsgStore object. But the problem is when I call Advise method, I always get E_INVALIDARG error.

    I declared MAPI API in MAPINative class.

    namespace NetMAPI
    {
        public delegate void OnAdviseCallbackHandler(IntPtr pMAPI, uint cNotification, IntPtr lpNotifications);
        class MAPINative
        {
            [DllImport("MAPI32.dll")]
            internal static extern HRESULT MAPIInitialize(IntPtr lpMapiInit);

            [DllImport("MAPI32.dll")]
            internal static extern void MAPIUninitialize();

            [DllImport("MAPI32.dll")]
            internal static extern int MAPILogonEx(uint ulUIParam, [MarshalAs(UnmanagedType.LPWStr)] string lpszProfileName,
                    [MarshalAs(UnmanagedType.LPWStr)] string lpszPassword, uint flFlags, out IntPtr lppSession);
            
            [DllImport("MAPI32.dll")]
            internal static extern void MAPIFreeBuffer(IntPtr lpBuffer);

            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrAllocAdviseSink@12")]
            internal static extern void HrAllocAdviseSink(OnAdviseCallbackHandler lpfnCallback, IntPtr lpvContext, out IntPtr lppAdviseSink);


        }
    }

    I MAPISession interface defined as the below.


    [
           ComImport, ComVisible(false),
           InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
           Guid("00020300-0000-0000-C000-000000000046")
        ]

        public interface IMAPISession
        {
            HRESULT GetLastError(int hResult, uint ulFlags, out IntPtr lppMAPIError);
            HRESULT GetMsgStoresTable(uint ulFlags, out IntPtr lppTable);
            HRESULT OpenMsgStore(uint ulUIParam, uint cbEntryID, IntPtr lpEntryID, IntPtr lpInterface, uint ulFlags, out IntPtr lppMDB);
            HRESULT OpenAddressBook(uint ulUIParam, IntPtr lpInterface, uint ulFlags, out IntPtr lppAdrBook);
            HRESULT OpenProfileSection(ref Guid lpUID, ref Guid lpInterface, uint ulFlags, out IntPtr lppProfSect);
            HRESULT GetStatusTable(uint ulFlags, out IntPtr lppTable);
            HRESULT OpenEntry(uint cbEntryID, IntPtr lpEntryID, ref Guid lpInterface, uint ulFlags, out uint lpulObjType, out IntPtr lppUnk);
            HRESULT CompareEntryIDs(uint cbEntryID1, IntPtr lpEntryID1, uint cbEntryID2, IntPtr lpEntryID2, uint ulFlags, out uint lpulResult);
            HRESULT Advise(uint cbEntryID, IntPtr lpEntryID, uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);
            HRESULT Unadvise(uint ulConnection);
            HRESULT MessageOptions(uint ulUIParam, uint ulFlags, [MarshalAs(UnmanagedType.LPWStr)] string lpszAdrType, IntPtr lpMessage);
            HRESULT QueryDefaultMessageOpt([MarshalAs(UnmanagedType.LPWStr)] string lpszAdrType, uint ulFlags, out uint lpcValues, out IntPtr lppOptions);
            HRESULT EnumAdrTypes(uint ulFlags, out uint lpcAdrTypes, out IntPtr lpppszAdrTypes);
            HRESULT QueryIdentity(out uint lpcbEntryID, out IntPtr lppEntryID);
            HRESULT Logoff(uint ulUIParam, uint ulFlags, uint ulReserved);
            HRESULT SetDefaultStore(uint ulFlags, uint cbEntryID, IntPtr lpEntryID);
            HRESULT AdminServices(uint ulFlags, out IntPtr lppServiceAdmin);
            HRESULT ShowForm(uint ulUIParam, IntPtr lpMsgStore, IntPtr lpParentFolder, ref Guid lpInterface, uint ulMessageToken,
            IntPtr lpMessageSent, uint ulFlags, uint ulMessageStatus, uint ulMessageFlags, uint ulAccess, [MarshalAs(UnmanagedType.LPWStr)] string lpszMessageClass);
            HRESULT PrepareForm(ref Guid lpInterface, IntPtr lpMessage, out uint lpulMessageToken);
        }

    The below is the code get MAPI Session. It’s working.

         IntPtr pSession = IntPtr.Zero;
                if (MAPINative.MAPIInitialize(IntPtr.Zero) == HRESULT.S_OK)
                {
                    MAPINative.MAPILogonEx(0, null, null, MAPI_EXTENDED | MAPI_USE_DEFAULT, out pSession);
                    if (pSession == IntPtr.Zero)
                        MAPINative.MAPILogonEx(0, null, null, MAPI_EXTENDED | MAPI_NEW_SESSION | MAPI_USE_DEFAULT, out pSession);
                }

                if (pSession != IntPtr.Zero)
                {
                    object sessionObj = null;
                    try
                    {
                        sessionObj = Marshal.GetObjectForIUnknown(pSession);
                        session_ = sessionObj as IMAPISession;
                    }
                    catch { }
                }

                return session_ != null;


    Define IMsgStore interface as the below.
    [
           ComImport, ComVisible(false),
           InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
           Guid("00020306-0000-0000-C000-000000000046")
       ]
        public interface IMsgStore : IMAPIProp
        {
            [PreserveSig]
            HRESULT Advise(uint cbEntryID, IntPtr lpEntryID, uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);
            HRESULT Unadvise(uint ulConnection);
            HRESULT OpenEntry(uint cbEntryID, IntPtr lpEntryID, ref Guid lpInterface, uint ulFlags, out uint lpulObjType, out IntPtr lppUnk);
            HRESULT CompareEntryIDs(uint cbEntryID1, IntPtr lpEntryID1, uint cbEntryID2, IntPtr lpEntryID2, uint ulFlags, out uint lpulResult);
            HRESULT SetReceiveFolder(string lpszMessageClass, uint ulFlags, uint cbEntryID, IntPtr lpEntryID);
            [PreserveSig]
            HRESULT GetReceiveFolder([MarshalAs(UnmanagedType.LPWStr)]string lpszMessageClass, uint ulFlags, out uint cbEntryID, IntPtr lppEntryID, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lppszExplicitClass);
            HRESULT AbortSubmit(uint cbEntryID, IntPtr lpEntryID, uint ulFlags);

        }



    Open message store to get IMsgStore object . It works as well.

    public bool OpenMessageStore(string storeName)
            {
                if (session_ == null)
                    return false;
                IntPtr pTable = IntPtr.Zero;
                session_.GetMsgStoresTable(0, out pTable);
                if (pTable == IntPtr.Zero)
                    return false;
                bool bResult = false;
                object tableObj = null;
                MAPITable mb = null;
                try
                {
                    tableObj = Marshal.GetObjectForIUnknown(pTable);
                    mb = new MAPITable(tableObj as IMAPITable);
                    if (mb != null)
                    {
                        uint[] columns = new uint[] { 3, (uint)PropTags.PR_DISPLAY_NAME, (uint)PropTags.PR_ENTRYID, (uint)PropTags.PR_DEFAULT_STORE };
                        if (mb.SetColumns(new PropTags[] { PropTags.PR_DISPLAY_NAME, PropTags.PR_ENTRYID, PropTags.PR_DEFAULT_STORE }))
                        {
                            SRow[] sRows;

                            while (mb.QueryRows(1, out sRows))
                            {
                                if (sRows.Length != 1)
                                    break;
                                if (string.IsNullOrEmpty(storeName))
                                {
                                    if (sRows[0].propVals[2].AsBool)
                                        bResult = true;
                                }
                                else if (sRows[0].propVals[0].AsString.IndexOf(storeName) > -1)
                                    bResult = true;
                                if (bResult)
                                    break;
                            }
                            if (bResult)
                            {
                                if (MsgStore != null)
                                {
                                  MsgStore.Dispose();
                                  MsgStore = null;
                                }
                                SBinary entryId = SBinary.SBinaryCreate(sRows[0].propVals[1].AsBinary);
                                IntPtr pStore = IntPtr.Zero;
                                if (session_.OpenMsgStore(0, entryId.cb, entryId.lpb, IntPtr.Zero, MAPI_BEST_ACCESS, out pStore) == HRESULT.S_OK)
                                {
                                    if (pStore != IntPtr.Zero)
                                    {
                                        IMsgStore msgStore = Marshal.GetObjectForIUnknown(pStore) as IMsgStore;
                                                                        }
                                }
                                SBinary.SBinaryRelease(ref entryId);
                            }
                        }
                        mb.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
                return bResult;
            }


    Then I call  IMsgstore.Advise like the below.

    IntPtr pAdvise = IntPtr.Zero;
                    MAPINative.HrAllocAdviseSink(callbackHandler, IntPtr.Zero, out pAdvise);
                                
                    if (pAdvise != IntPtr.Zero)
                    {
                        hresult = msgStore_.Advise(0, IntPtr.Zero, (uint)eventMask, pAdvise, out ulConnection_);
                      
                    }

    I get  trouble here. No idea why I always get an error, E_INVALIDARG.
    Monday, February 20, 2012 5:41 AM

All replies

  • The use of MAPI from C# or other managed code isn't supported. It's only supported using unmanaged C++ or Delphi/Pascal.

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Fred72" <=?utf-8?B?RnJlZDcy?=> wrote in message news:e6f65654-fd8f-4484-ac9a-6918dcb4ccb4...
    For some reasons, I need subscribe MAPI Store events in C#. I can successfully get IMsgStore object. But the problem is when I call Advise method, I always get E_INVALIDARG error.

    I declared MAPI API in MAPINative class.

    namespace NetMAPI
    {
        public delegate void OnAdviseCallbackHandler(IntPtr pMAPI, uint cNotification, IntPtr lpNotifications);
        class MAPINative
        {
            [DllImport("MAPI32.dll")]
            internal static extern HRESULT MAPIInitialize(IntPtr lpMapiInit);

            [DllImport("MAPI32.dll")]
            internal static extern void MAPIUninitialize();

            [DllImport("MAPI32.dll")]
            internal static extern int MAPILogonEx(uint ulUIParam, [MarshalAs(UnmanagedType.LPWStr)] string lpszProfileName,
                    [MarshalAs(UnmanagedType.LPWStr)] string lpszPassword, uint flFlags, out IntPtr lppSession);
            
            [DllImport("MAPI32.dll")]
            internal static extern void MAPIFreeBuffer(IntPtr lpBuffer);

            [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint = "HrAllocAdviseSink@12")]
            internal static extern void HrAllocAdviseSink(OnAdviseCallbackHandler lpfnCallback, IntPtr lpvContext, out IntPtr lppAdviseSink);


        }
    }

    I MAPISession interface defined as the below.


    [
           ComImport, ComVisible(false),
           InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
           Guid("00020300-0000-0000-C000-000000000046")
        ]

        public interface IMAPISession
        {
            HRESULT GetLastError(int hResult, uint ulFlags, out IntPtr lppMAPIError);
            HRESULT GetMsgStoresTable(uint ulFlags, out IntPtr lppTable);
            HRESULT OpenMsgStore(uint ulUIParam, uint cbEntryID, IntPtr lpEntryID, IntPtr lpInterface, uint ulFlags, out IntPtr lppMDB);
            HRESULT OpenAddressBook(uint ulUIParam, IntPtr lpInterface, uint ulFlags, out IntPtr lppAdrBook);
            HRESULT OpenProfileSection(ref Guid lpUID, ref Guid lpInterface, uint ulFlags, out IntPtr lppProfSect);
            HRESULT GetStatusTable(uint ulFlags, out IntPtr lppTable);
            HRESULT OpenEntry(uint cbEntryID, IntPtr lpEntryID, ref Guid lpInterface, uint ulFlags, out uint lpulObjType, out IntPtr lppUnk);
            HRESULT CompareEntryIDs(uint cbEntryID1, IntPtr lpEntryID1, uint cbEntryID2, IntPtr lpEntryID2, uint ulFlags, out uint lpulResult);
            HRESULT Advise(uint cbEntryID, IntPtr lpEntryID, uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);
            HRESULT Unadvise(uint ulConnection);
            HRESULT MessageOptions(uint ulUIParam, uint ulFlags, [MarshalAs(UnmanagedType.LPWStr)] string lpszAdrType, IntPtr lpMessage);
            HRESULT QueryDefaultMessageOpt([MarshalAs(UnmanagedType.LPWStr)] string lpszAdrType, uint ulFlags, out uint lpcValues, out IntPtr lppOptions);
            HRESULT EnumAdrTypes(uint ulFlags, out uint lpcAdrTypes, out IntPtr lpppszAdrTypes);
            HRESULT QueryIdentity(out uint lpcbEntryID, out IntPtr lppEntryID);
            HRESULT Logoff(uint ulUIParam, uint ulFlags, uint ulReserved);
            HRESULT SetDefaultStore(uint ulFlags, uint cbEntryID, IntPtr lpEntryID);
            HRESULT AdminServices(uint ulFlags, out IntPtr lppServiceAdmin);
            HRESULT ShowForm(uint ulUIParam, IntPtr lpMsgStore, IntPtr lpParentFolder, ref Guid lpInterface, uint ulMessageToken,
            IntPtr lpMessageSent, uint ulFlags, uint ulMessageStatus, uint ulMessageFlags, uint ulAccess, [MarshalAs(UnmanagedType.LPWStr)] string lpszMessageClass);
            HRESULT PrepareForm(ref Guid lpInterface, IntPtr lpMessage, out uint lpulMessageToken);
        }

    The below is the code get MAPI Session. It’s working.

         IntPtr pSession = IntPtr.Zero;
                if (MAPINative.MAPIInitialize(IntPtr.Zero) == HRESULT.S_OK)
                {
                    MAPINative.MAPILogonEx(0, null, null, MAPI_EXTENDED | MAPI_USE_DEFAULT, out pSession);
                    if (pSession == IntPtr.Zero)
                        MAPINative.MAPILogonEx(0, null, null, MAPI_EXTENDED | MAPI_NEW_SESSION | MAPI_USE_DEFAULT, out pSession);
                }

                if (pSession != IntPtr.Zero)
                {
                    object sessionObj = null;
                    try
                    {
                        sessionObj = Marshal.GetObjectForIUnknown(pSession);
                        session_ = sessionObj as IMAPISession;
                    }
                    catch { }
                }

                return session_ != null;


    Define IMsgStore interface as the below.
    [
           ComImport, ComVisible(false),
           InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
           Guid("00020306-0000-0000-C000-000000000046")
       ]
        public interface IMsgStore : IMAPIProp
        {
            [PreserveSig]
            HRESULT Advise(uint cbEntryID, IntPtr lpEntryID, uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);
            HRESULT Unadvise(uint ulConnection);
            HRESULT OpenEntry(uint cbEntryID, IntPtr lpEntryID, ref Guid lpInterface, uint ulFlags, out uint lpulObjType, out IntPtr lppUnk);
            HRESULT CompareEntryIDs(uint cbEntryID1, IntPtr lpEntryID1, uint cbEntryID2, IntPtr lpEntryID2, uint ulFlags, out uint lpulResult);
            HRESULT SetReceiveFolder(string lpszMessageClass, uint ulFlags, uint cbEntryID, IntPtr lpEntryID);
            [PreserveSig]
            HRESULT GetReceiveFolder([MarshalAs(UnmanagedType.LPWStr)]string lpszMessageClass, uint ulFlags, out uint cbEntryID, IntPtr lppEntryID, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lppszExplicitClass);
            HRESULT AbortSubmit(uint cbEntryID, IntPtr lpEntryID, uint ulFlags);

        }



    Open message store to get IMsgStore object . It works as well.

    public bool OpenMessageStore(string storeName)
            {
                if (session_ == null)
                    return false;
                IntPtr pTable = IntPtr.Zero;
                session_.GetMsgStoresTable(0, out pTable);
                if (pTable == IntPtr.Zero)
                    return false;
                bool bResult = false;
                object tableObj = null;
                MAPITable mb = null;
                try
                {
                    tableObj = Marshal.GetObjectForIUnknown(pTable);
                    mb = new MAPITable(tableObj as IMAPITable);
                    if (mb != null)
                    {
                        uint[] columns = new uint[] { 3, (uint)PropTags.PR_DISPLAY_NAME, (uint)PropTags.PR_ENTRYID, (uint)PropTags.PR_DEFAULT_STORE };
                        if (mb.SetColumns(new PropTags[] { PropTags.PR_DISPLAY_NAME, PropTags.PR_ENTRYID, PropTags.PR_DEFAULT_STORE }))
                        {
                            SRow[] sRows;

                            while (mb.QueryRows(1, out sRows))
                            {
                                if (sRows.Length != 1)
                                    break;
                                if (string.IsNullOrEmpty(storeName))
                                {
                                    if (sRows[0].propVals[2].AsBool)
                                        bResult = true;
                                }
                                else if (sRows[0].propVals[0].AsString.IndexOf(storeName) > -1)
                                    bResult = true;
                                if (bResult)
                                    break;
                            }
                            if (bResult)
                            {
                                if (MsgStore != null)
                                {
                                  MsgStore.Dispose();
                                  MsgStore = null;
                                }
                                SBinary entryId = SBinary.SBinaryCreate(sRows[0].propVals[1].AsBinary);
                                IntPtr pStore = IntPtr.Zero;
                                if (session_.OpenMsgStore(0, entryId.cb, entryId.lpb, IntPtr.Zero, MAPI_BEST_ACCESS, out pStore) == HRESULT.S_OK)
                                {
                                    if (pStore != IntPtr.Zero)
                                    {
                                        IMsgStore msgStore = Marshal.GetObjectForIUnknown(pStore) as IMsgStore;
                                                                        }
                                }
                                SBinary.SBinaryRelease(ref entryId);
                            }
                        }
                        mb.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
                return bResult;
            }


    Then I call  IMsgstore.Advise like the below.

    IntPtr pAdvise = IntPtr.Zero;
                    MAPINative.HrAllocAdviseSink(callbackHandler, IntPtr.Zero, out pAdvise);
                                
                    if (pAdvise != IntPtr.Zero)
                    {
                        hresult = msgStore_.Advise(0, IntPtr.Zero, (uint)eventMask, pAdvise, out ulConnection_);
                      
                    }

    I get  trouble here. No idea why I always get an error, E_INVALIDARG.

    Ken Slovak MVP - Outlook
    Monday, February 20, 2012 3:43 PM
    Moderator
  • <plug>

    You can also use the RDOStore object in Redemption - it implements all events exposed by the IMsgSTore Extended MAPI object: http://www.dimastr.com/redemption/rdostore.htm#events 

    </plug>


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Monday, February 20, 2012 4:54 PM
  • How you allocate callbackHandler, show code for that, also tell us about office.window version and bitness.
    Tuesday, February 21, 2012 9:36 AM
  • The sink is allocated by calling HrAllocAdviseSink, but it looks like the eventMask variable is never initialized.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Tuesday, February 21, 2012 4:33 PM
  • The sink is allocated by calling HrAllocAdviseSink. That API call is succesful. It returns Int Pointer which point to IMAPIAdviseSink.

    eventMask is passed from caller. The whole function is as the below:

                             

     public bool RegisterEvents(EEventMask eventMask)
            {
                this.callbackHandler = OnNotifyCallback;
                HRESULT hresult = HRESULT.S_OK;
                try
                {
                    IntPtr pAdvise = IntPtr.Zero;
                    MAPINative.HrAllocAdviseSink(callbackHandler, IntPtr.Zero, out pAdvise);

                    if (pAdvise != IntPtr.Zero)
                    {
                        hresult = msgStore_.Advise(0, IntPtr.Zero, (uint)eventMask, pAdvise, out ulConnection_);
                    }


                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
                return hresult == HRESULT.S_OK;

            }

    Actually I suspect that's problem for declaration of IMsgStore. If I change Advise definition like the below:


      [
           ComImport, ComVisible(false),
           InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
           Guid("00020306-0000-0000-C000-000000000046")
       ]
        public interface IMsgStore : IMAPIProp
        {
            [PreserveSig]
            HRESULT Advise( uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);
           ...


        }

    hresult = msgStore_.Advise( (uint)eventMask, pAdvise, out ulConnection_); It will return zero (S_OK). But ulConnection_ still be zero. That means not connected. 

    Wednesday, February 22, 2012 5:18 AM
  • The sink is allocated by calling HrAllocAdviseSink. That API call is succesful. It returns Int Pointer which point to IMAPIAdviseSink.

    eventMask is passed from caller. The whole function is as the below:

                             

     public bool RegisterEvents(EEventMask eventMask)
            {
                this.callbackHandler = OnNotifyCallback;
                HRESULT hresult = HRESULT.S_OK;
                try
                {
                    IntPtr pAdvise = IntPtr.Zero;
                    MAPINative.HrAllocAdviseSink(callbackHandler, IntPtr.Zero, out pAdvise);

                    if (pAdvise != IntPtr.Zero)
                    {
                        hresult = msgStore_.Advise(0, IntPtr.Zero, (uint)eventMask, pAdvise, out ulConnection_);
                    }


                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
                return hresult == HRESULT.S_OK;

            }

    Actually I suspect that's problem for declaration of IMsgStore. If I change Advise definition like the below:


      [
           ComImport, ComVisible(false),
           InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
           Guid("00020306-0000-0000-C000-000000000046")
       ]
        public interface IMsgStore : IMAPIProp
        {
            [PreserveSig]
            HRESULT Advise( uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);
           ...


        }

    hresult = msgStore_.Advise( (uint)eventMask, pAdvise, out ulConnection_); It will return zero (S_OK). But ulConnection_ still be zero. That means not connected. 

    Wednesday, February 22, 2012 5:18 AM
  • ulConnection cannot be anything, there are no right or wrong values.

    If you get back S_OK, everything was fine.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Wednesday, February 22, 2012 5:21 AM
  • I'm using COM interface. That's all good except advise(). I cannot imagine why advise() not working and others working?

    Wednesday, February 22, 2012 5:21 AM
  • What exactly does not work? Does your app have UI? If not, do you run Windows message loop?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Wednesday, February 22, 2012 5:24 AM
  • I know that's wrong because:

    1) the callback delegate not get called.

    2) Per the MSDN, advise method should be defined as,

    HRESULT Advise(uint cbEntryID, IntPtr lpEntryID, uint ulEventMask, IntPtr lpAdviseSink, out uint lpulConnection);

    My biggest headache is if I define Advise as the above, it returns E_InvalidArg. What I guess is I passed wrong arguments. Really, no idea.

    Wednesday, February 22, 2012 5:30 AM
  •   private void OnNotifyCallback(IntPtr pMAPI, uint cNotification, IntPtr lpNotifications)
            {
                EEventMask eventType = (EEventMask)Marshal.ReadInt32(lpNotifications);
                uint intSize = (uint)Marshal.SizeOf(typeof(int));
                ulong sPtr = ((ulong)(lpNotifications)) + intSize * 2; //ulEventType, ulAlignPad


                switch (eventType)
                {
                    case EEventMask.fnevNewMail:
                        {
                          //@@TODO
                        break;
                    case EEventMask.fnevObjectCopied:
                    case EEventMask.fnevObjectCreated:
                    case EEventMask.fnevObjectDeleted:
                    case EEventMask.fnevObjectModified:
                    case EEventMask.fnevObjectMoved:
                        {
                            //@@TODO
                        break;
                }
            }

    That's my message store notification callback function. If Advise works, this callback should get called, when the corresponding event happens.

    Wednesday, February 22, 2012 5:37 AM
  • I have never used thsi in C#, but are you sure the function signature is right? Isn't the very least the function is supposed to be static?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Monday, March 5, 2012 9:41 PM