【发布时间】:2016-05-17 06:01:14
【问题描述】:
我有一个小代码可以解析系统的事件查看器以查找所需的数据。现在,当创建 .exe 但不在 .dll 中时,此代码可以正常工作。 如何收听我在 dll 中订阅的事件。
有没有更好的方法在 .dll 中实现 EvtSubscribe() 和 SubscriptionCallback() ?
这是因为我跳过了 DllMain() 函数吗?
main()
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hSubscription = NULL;
hSubscription = EvtSubscribe(NULL, NULL, pwsPath, pwsQuery, NULL, NULL,
(EVT_SUBSCRIBE_CALLBACK)SubscriptionCallback, EvtSubscribeStartAtOldestRecord);
if (NULL == hSubscription)
{
//some code
return;
}
回调 在构建 .exe 但不在 .dll 中时调用
// The callback that receives the events that match the query criteria.
DWORD WINAPI SubscriptionCallback(EVT_SUBSCRIBE_NOTIFY_ACTION action, PVOID pContext, EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
switch (action)
{
//some code
case EvtSubscribeActionDeliver:
if (ERROR_SUCCESS != (status = PrintEvent(hEvent)))
{
goto cleanup;
}
break;
}
cleanup:
return status; // The service ignores the returned status.
}
DWORD PrintEvent(EVT_HANDLE hEvent)
{
// print
}
【问题讨论】:
-
无法加载没有
DllMain的 DLL 以供执行。使用GFlags 启用show loader snaps 选项来诊断这类问题。 -
@IInspectable MSDN 声明 DlMain 是“动态链接库 (DLL) 的可选入口点”。程序员不必提供 DllMain,因为 C 运行时提供了一个。事实上,程序员提供的 DllMain 将被 C 运行时提供的入口点调用。
-
@MarcSherman:就系统而言,
DllMain不是可选的。如果您使用提供默认实现的库,则它是可选的,以防您没有提供。 -
@IInspectable 就系统而言,我们谈论的是 IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint,MSDN 说“入口点函数对于 DLL 来说是可选的。当没有入口点时,这个成员是零。”见msdn.microsoft.com/en-us/library/windows/desktop/…
-
加载 DLL 时不会调用您的
main函数。您可能想要导出一个新函数(使用相同的代码),然后从 EXE 中调用该函数。或者,您可以使用DllMain,从那里启动一个新线程,然后从该线程调用EvtSubscribe。强烈建议不要直接从DllMain调用此类函数。