ManagementObjectSearcher在全局挂钩中不起作用 [英] ManagementObjectSearcher does not work within global hook
问题描述
当我尝试在鼠标事件处理程序中获取所有正在运行的进程时,它将引发异常.首先,我认为问题仍然存在,因为我将 async
关键字放在了鼠标事件处理程序之前,但事实并非如此,因为非异步方法也会引发异常.
When I try to get all running processes inside mouse event handler it throws an exception. First I thought that the problem persists because I put async
keyword before mouse event handler, but it was not the case, as the exception is thrown also for non-asynchronous methods.
我正在使用 MouseKeyHook 库.
异常消息:
其他信息:转换到COM上下文0x1ac936a0,用于此RuntimeCallableWrapper失败,出现以下错误:An由于应用程序正在调度呼叫,因此无法进行拨出呼叫输入同步调用.(来自HRESULT的异常:0x8001010D(RPC_E_CANTCALLOUT_ININPUTSYNCCALL).
Additional information: Transition into COM context 0x1ac936a0 for this RuntimeCallableWrapper failed with the following error: An outgoing call cannot be made since the application is dispatching an input-synchronous call. (Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)).
从中获取所有进程的事件处理程序:
private async void MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
List<ProcessInfo> allRunningProcesses = Logic.GetAllProcesses();
// ...
}
使用 ManagementObjectSearcher
获取所有进程:
Get all processes by using ManagementObjectSearcher
:
public static List<ProcessInfo> GetAllProcesses()
{
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
using (var results = searcher.Get()) // EXCEPTION THROWN!
{
// ...
}
}
如您所见,调用 searcher.Get()
时会引发异常.注意:如果在鼠标事件处理程序( MouseUp
)之外使用此方法,则不会出现任何问题.
As you can see the exception is thrown when calling searcher.Get()
. Note: This method works without any issues if used outside the mouse event handler (MouseUp
).
推荐答案
事实证明,如果存在MTA,COM要求您在STA上运行代码您需要在 SendMessage()
中使用 ManagementObjectSearcher
方法.
因此,我需要做的是在差异线程并将 SetApartmentState
设置为 ApartmentState.STA
.
As it turns out, COM requires you to run your code on STA if there is MTA
involved and you are using the ManagementObjectSearcher
methods within SendMessage()
.
So, what I needed to do is to run my code on
differet thread and set SetApartmentState
to ApartmentState.STA
.
List<ProcessInfo> allRunningProcesses = null;
Thread threadProc = new Thread(() =>
{
allRunningProcesses = Logic.GetAllProcesses();
});
threadProc.SetApartmentState(ApartmentState.STA);
threadProc.Start();
threadProc.Join();
有用的链接:
msdn- 了解和使用COM线程模型
stackoverflow- 如何在STA线程中运行某些东西
这篇关于ManagementObjectSearcher在全局挂钩中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!