代码之家  ›  专栏  ›  技术社区  ›  Kira

计算发送/接收持续时间-Outlook

  •  1
  • Kira  · 技术社区  · 11 年前

    我正在进行一个旨在衡量Microsoft Outlook性能的项目。我的问题是“是否有检测发送/接收事件(开始和结束)的方法?”。哪个API提供了与此事件相关的方法。我在谷歌上搜索了一段时间,但没有发现任何有趣的东西。

    3 回复  |  直到 11 年前
        1
  •  3
  •   Kira    11 年前

    使用Namespace.SyncObjects集合。

    SyncObject.SyncStart/SyncEnd事件可能正是您想要的。

    编辑: 只是有一个名为 SyncStart 什么都不会做。Outlook如何知道它需要调用您的事件处理程序?

    您需要订阅COM事件-ATL和MFC都为COM事件提供包装。在低级别上,您需要为IConnectionPointContainer对引发事件的COM对象(在您的情况下为SyncObject)进行QI,调用 IConnectionPointContainer::FindConnectionPoint 传递适当的disp接口GUID(SyncObjectEvents),然后调用 IConnectionPoint.Advise 通过您的实现 IDispatch 。当引发事件时,您的 IDispatch::Invoke() 将使用与特定事件相对应的适当dispid来调用。

        2
  •  3
  •   RAM    7 年前

    正如Dimitry所说,您需要捕获SyncStart和SyncEnd事件,在C++中最简单的方法可能是为Outlook创建一个外接程序,获取正确的接口并实现接收器对象以获取所需的通知。

    http://msdn.microsoft.com/en-us/library/ee941475%28v=office.14%29.aspx

    编辑

    不确定你是否成功了,所以这里有一个没有插件的例子。。。

    创建一个新的控制台应用程序,添加这些include和imports(相应地更改路径)或使用相应的libid。。。

    #include <atlbase.h>
    #include <atlcom.h>
    #include <atlctl.h>
    #import "C:\\Program Files (x86)\\Common Files\\microsoft shared\\OFFICE12\\mso.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids, auto_search rename("DocumentProperties", "MsoDocumentProperties") rename("RGB", "MsoRGB") exclude("IAccessible")
    #import "C:\\Program Files (x86)\\Microsoft Office\\Office12\\msoutl.olb" raw_interfaces_only, raw_native_types, named_guids, auto_search rename("Folder", "OlkFolder") rename("CopyFile", "OlkCopyFile") rename("GetOrganizer", "GetOrganizerAE") rename("PlaySound", "OlkPlaySound") rename_namespace("Outlook")
    

    现在创建一个类来接收事件。。。您只需要从IDispatch派生,我为一个事件添加了一个HANDLE,以便在同步完成后提供建议。

    class COutlookEventSink : public IDispatch
    {
    public:
        COutlookEventSink(HANDLE hEvent);
        ~COutlookEventSink(void);
    
        // IUnknown
        HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
        ULONG STDMETHODCALLTYPE AddRef(void);
        ULONG STDMETHODCALLTYPE Release(void);
    
        // IDispatch
        HRESULT STDMETHODCALLTYPE GetTypeInfoCount(__RPC__out UINT *pctinfo);
        HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, __RPC__deref_out_opt ITypeInfo **ppTInfo);
        HRESULT STDMETHODCALLTYPE GetIDsOfNames(
            __RPC__in REFIID riid,
            __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
            __RPC__in_range(0,16384) UINT cNames,
            LCID lcid,
            __RPC__out_ecount_full(cNames) DISPID *rgDispId);
        HRESULT STDMETHODCALLTYPE Invoke(       
            DISPID dispIdMember,
            REFIID riid,
            LCID lcid,
            WORD wFlags,
            DISPPARAMS *pDispParams,
            VARIANT *pVarResult,
            EXCEPINFO *pExcepInfo,
            UINT *puArgErr);
    
    
    private:
        long _lRef; 
        HANDLE _hEvent;
    };
    
    COutlookEventSink::COutlookEventSink(HANDLE hEvent)
    {
        _lRef = 0;  
        _hEvent = hEvent;
    }
    
    COutlookEventSink::~COutlookEventSink(void)
    {
    }
    
    HRESULT STDMETHODCALLTYPE COutlookEventSink::QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
    {
        *ppvObject = NULL;
        if(IsEqualGUID(riid, IID_IUnknown))
            *ppvObject = reinterpret_cast<void**>(this);
    
        if(IsEqualGUID(riid, IID_IDispatch))
            *ppvObject = reinterpret_cast<void**>(this);
    
        if(*ppvObject)
        {
            ((IUnknown*)*ppvObject)->AddRef();
            return S_OK;
        }
    
        return E_NOINTERFACE;
    }
    
    ULONG STDMETHODCALLTYPE COutlookEventSink::AddRef()
    {
        return InterlockedIncrement(&_lRef);
    }
    
    ULONG STDMETHODCALLTYPE COutlookEventSink::Release()
    {
        if (InterlockedDecrement(&_lRef) == 0)
        {
            delete this;
            return 0;
        }
        return _lRef;
    }
    
    HRESULT STDMETHODCALLTYPE COutlookEventSink::GetTypeInfoCount(__RPC__out UINT *pctinfo)
    {
        return E_NOTIMPL;
    }
    
    HRESULT STDMETHODCALLTYPE COutlookEventSink::GetTypeInfo(UINT iTInfo, LCID lcid, __RPC__deref_out_opt ITypeInfo **ppTInfo)
    {
        return E_NOTIMPL;
    }
    
    HRESULT STDMETHODCALLTYPE COutlookEventSink::GetIDsOfNames(__RPC__in REFIID riid, __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, __RPC__in_range(0,16384) UINT cNames, LCID lcid, __RPC__out_ecount_full(cNames) DISPID *rgDispId)
    {
        return S_OK;
    }
    
    HRESULT STDMETHODCALLTYPE COutlookEventSink::Invoke(    
        DISPID dispIdMember,
        REFIID riid,
        LCID lcid,
        WORD wFlags,
        DISPPARAMS *pDispParams,
        VARIANT *pVarResult,
        EXCEPINFO *pExcepInfo,
        UINT *puArgErr)
    {           
        switch(dispIdMember)
        {
        case 61441: // SyncStart - Start a Timer ?
            break;
        case 61444: // SyncEnd
            SetEvent(_hEvent); // We done, exit
            break;
        }
    
        return S_OK;
    }
    

    现在,在主屏幕上创建Outlook应用程序,并将接收器添加到SyncObjects

    int _tmain(int argc, _TCHAR* argv[])
    {
        CoInitialize(NULL);
        CComPtr<Outlook::_Application> spApplication;
    
        HRESULT hr = spApplication.CoCreateInstance(__uuidof(Outlook::Application), 0, CLSCTX_LOCAL_SERVER );
        if(SUCCEEDED(hr) && spApplication)
        {
            CComPtr<Outlook::_NameSpace> spSession;
    
            hr = spApplication->get_Session(reinterpret_cast<Outlook::_NameSpace **>(&spSession));
            if (SUCCEEDED(hr) && spSession)
            {
                CComPtr<Outlook::SyncObjects> spSyncObjects;
    
                hr = spSession->get_SyncObjects(reinterpret_cast<Outlook::SyncObjects **>(&spSyncObjects));
                if (SUCCEEDED(hr) && spSyncObjects)
                {                                       
                    VARIANT index;
                    index.intVal = 1;
                    index.vt = VT_INT;
    
                    CComPtr<Outlook::_SyncObject> spSyncObject;
                    hr = spSyncObjects->Item(index, reinterpret_cast<Outlook::_SyncObject **>(&spSyncObject));
                    if (SUCCEEDED(hr) && spSyncObject)
                    {                           
                        CComPtr<IConnectionPointContainer> spContainer;
                        HRESULT hr = spSyncObject->QueryInterface(__uuidof(IConnectionPointContainer),reinterpret_cast<void **>(&spContainer));
                        if (SUCCEEDED(hr) && spContainer)
                        {   
                            HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
                            CComPtr<COutlookEventSink> spSink = new COutlookEventSink(hEvent);
                            CComPtr<IConnectionPoint> spConnectionPoint;
                            hr = spContainer->FindConnectionPoint(Outlook::DIID_SyncObjectEvents, &spConnectionPoint);
                            if (SUCCEEDED(hr) && spConnectionPoint)
                            {
                                DWORD dwCookie = 0;                             
                                CComPtr<IUnknown> spUnknown;
                                hr = spConnectionPoint->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&spUnknown));
                                if (SUCCEEDED(hr) && spUnknown)
                                {                                   
                                    hr = spConnectionPoint->Advise(spSink, &dwCookie);                                          
                                    if (SUCCEEDED(hr))
                                    {                                   
                                        spSyncObject->Start(); // Syncronize
    
                                        while(true)
                                        {                                                           
                                            MSG Message;
                                            while(PeekMessage(&Message, NULL, WM_NULL, WM_NULL, PM_REMOVE))
                                            {
                                                TranslateMessage(&Message);
                                                DispatchMessage(&Message);
                                            }   
    
                                            DWORD dwStatus = WaitForSingleObject(hEvent, 0); // Wait for end
                                            if(dwStatus == WAIT_OBJECT_0)
                                                break;                              
                                        }
    
    
                                        spConnectionPoint->Unadvise(dwCookie);                                  
                                    }
                                }
                            }
                        }                                               
                    }               
                }
            }
    
            spApplication.Release();
        }
    
        CoUninitialize();
    
        return 0;
    }
    
        3
  •  1
  •   Community Neeleshkumar S    7 年前

    我认为你需要的是,得到两个展望事件之间的时间间隔。如果你计划用C++来做这件事,我认为这会有点麻烦。但是,如果你想在MS的任何办公应用程序上进行一些编程,MS提供了一个API调用宏(VBA)。

    基本:

    1. Macro是一个可以使用vb脚本编写的附加程序,可以在任何MS office应用程序中单击按钮或事件老虎机运行 more details .

    2. 因此,您可以通过打开outlook打开宏编程界面,然后按ALT+F11。

    3. 所以可以使用这个宏做很多事情,你可以在谷歌上搜索更多细节。

    4. 如果你需要获得一些关于C++应用程序的信息,你可以考虑将API从宏变成C++,可能只是编写一个测试文件。

    5. Here 是一个例子,你可能会从中得到一些想法

    6. Here 是关于宏的教程

    希望这些想法能帮助你实现目标。