我想我找到了解決方案。
雖然我不知道如何通過現有提供者實時發送事件,但Windows 8公開了允許修改ETL跟蹤日誌的界面,因此可以將事件的ProviderId
更改爲不同的值。有問題的界面是ITraceRelogger
。你需要這些GUID:從Windows 8 SDK(c:\Program Files (x86)\Windows Kits\8.0\Include\um\relogger.h
)
EXTERN_GUID(CLSID_TraceRelogger, 0x7b40792d, 0x05ff, 0x44c4, 0x90, 0x58, 0xf4, 0x40, 0xc7, 0x1f, 0x17, 0xd4);
DEFINE_GUID(IID_ITraceRelogger, 0xF754AD43, 0x3BCC, 0x4286, 0x80, 0x09,0x9C, 0x5D, 0xA2, 0x14, 0xE8, 0x4E); // {F754AD43-3BCC-4286-8009-9C5DA214E84E}
DEFINE_GUID(IID_ITraceEventCallback, 0x3ED25501, 0x593F, 0x43E9, 0x8F, 0x38,0x3A, 0xB4, 0x6F, 0x5A, 0x4A, 0x52); // {3ED25501-593F-43E9-8F38-3AB46F5A4A52}
和relogger.h
文件。原始relogger.h
似乎以某種方式被打破,因爲它引用了一些外部符號,但似乎沒有LIB文件來補充它。我相信你會設法解決這個問題!
要使用它,只需創建一個實例:
ITraceRelogger *relog = NULL;
hres = CoCreateInstance(CLSID_TraceRelogger, 0, CLSCTX_INPROC_SERVER, IID_ITraceRelogger2, (LPVOID *)& relog);
加你input.etl
和output.etl
文件:
#include <windows.h>
#include <cguid.h>
#include <atlbase.h>
#include <comdef.h>
...
CComBSTR input = "input.etl";
CComBSTR output = "output.etl";
...
hres = relog->AddLogfileTraceStream(input, NULL, & trace);
...
hres = relog->SetOutputFilename(output);
然後,你需要註冊一個回調,這將處理事件的修改。事件回調的實現示例放置在此答案的末尾。下面是關於如何與當前ITraceRelogger使用它的代碼:
EventCallback *ec = new EventCallback();
hres = relog->RegisterCallback(ec);
...
hres = relog->ProcessTrace();
警告:ProcessTrace()
將返回一個錯誤,如果你還沒有註冊任何回調。
這裏的工作回調的例子:
class EventCallback: public ITraceEventCallback {
private:
DWORD ref_count;
DWORD64 evno;
public:
EventCallback() {
ref_count = 0;
evno = 0;
}
STDMETHODIMP QueryInterface(const IID& iid, void **obj) {
if(iid == IID_IUnknown) {
*obj = dynamic_cast<IUnknown *>(this);
} else if(iid == IID_ITraceEventCallback) {
*obj = dynamic_cast<ITraceEventCallback *>(this);
} else {
*obj = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
STDMETHODIMP_ (ULONG) AddRef(void) {
return InterlockedIncrement(& ref_count);
}
STDMETHODIMP_ (ULONG) Release() {
ULONG ucount = InterlockedDecrement(& ref_count);
if(ucount == 0) {
delete this;
}
return ucount;
}
HRESULT STDMETHODCALLTYPE OnBeginProcessTrace(ITraceEvent *HeaderEvent, ITraceRelogger *Relogger) {
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnEvent(ITraceEvent *Event, ITraceRelogger *Relogger) {
// Your main method.
evno++;
Relogger->Inject(Event);
}
HRESULT STDMETHODCALLTYPE OnFinalizeProcessTrace(ITraceRelogger *Relogger) {
return S_OK;
}
};
Relogger->Inject
將當前Event
複製到輸出文件。您可以使用MSDN的ITraceRelogger
來檢查可用的方法,這將允許您更改所需的事件屬性。我感興趣的方法是SetProviderId()
。
另外,請記住,MSDN指出,ITraceRelogger
在Windows 7中可用。這不是我所經歷的 - 我無法在Windows 7中實例化此類,因此MSDN可能有關於此主題的錯誤信息。
看來,安裝此更新後:http://support.microsoft.com/kb/2882822,你將能夠使用Win7中的這個類。 – antonone