我有一个.NET应用程序,它产生多个子“ worker 进程”。我正在使用Windows作业对象API和JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE设置来确保子进程在父进程终止时总是被杀死。
但是,我观察到在关闭父级后,计算机上仍有许多孤立的进程在运行。使用Process Explorer,我可以看到它们仍然正确地分配给了作业,并且该作业已配置了正确的“关闭作业时保留”设置。
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE状态的文档:
“导致与作业关联的所有进程在关闭作业的最后一个句柄时终止。”
这似乎暗示着Job的句柄仍在某个地方打开...我搜索了Job对象的句柄,并在结果中找到了WmiPrvSE.exe的实例。如果我杀死了相关的WmiPrvSE.exe进程,则Job的未完成句柄显然已关闭,并且所有孤立的应用程序进程均按预期终止。
WmiPrvSE.exe如何处理我的工作?
最佳答案
您可能会发现this blog在整理WmiPrvSE在做什么。
WmiPrvSE是WMI提供程序主机。这意味着它托管WMI提供程序,即DLL。因此,几乎可以肯定WmiPrvSE无法处理您的工作,但是它托管的提供者之一确实可以。为了弄清楚哪个提供者是罪魁祸首,一种方法是遵循进程here,然后查看哪个单独的进程持有该句柄。
一旦确定了哪个提供程序持有该句柄,您就可以尝试根据该提供程序管理的系统组件推断出哪种查询可以处理您的Job。或者,如果您不关心失去对提供程序提供的组件管理的访问权限,则可以禁用该提供程序。
如果可以确定哪种查询将持有句柄,则可以推断出哪个程序正在发出查询。或者,事件日志可以告诉您(上面的第一个链接)。
要获得更多帮助,请在OP中提供其他详细信息,例如WmiPrvSE中正在运行的提供程序,任何相关的事件日志事件以及您获得的任何其他诊断信息。
编辑1/27/16
要找出导致WMIPrvSE获取作业句柄的事件,一种方法是使用Windbg的!htrace扩展名。加载.EXE之后,但在Windbg中执行它之前,需要运行!htrace -enable
。然后,您可以稍后插入并执行!htrace <handle>
来查看操纵手柄时的堆栈跟踪。您可能要从此article on handle implementation.开始