简体   繁体   English

ManagementObjectSearcher在全局挂钩中不起作用

[英]ManagementObjectSearcher does not work within global hook

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. 首先,我认为问题仍然存在,因为我在鼠标事件处理程序之前放置了async关键字,但事实并非如此,因为非异步方法也会引发异常。

I'm using MouseKeyHook library. 我正在使用MouseKeyHook库。

Exception message: 异常消息:

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. 附加信息:为此RuntimeCallableWrapper转换到COM上下文0x1ac936a0失败,出现以下错误:由于应用程序正在调度输入同步调用,因此无法进行传出调用。 (Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)). (来自HRESULT的异常:0x8001010D(RPC_E_CANTCALLOUT_ININPUTSYNCCALL))。

Event handler from which I'm getting all processes: 从中获取所有进程的事件处理程序:

private async void MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
    List<ProcessInfo> allRunningProcesses = Logic.GetAllProcesses();
    // ...
}

Get all processes by using ManagementObjectSearcher : 通过使用ManagementObjectSearcher获取所有进程:

public static List<ProcessInfo> GetAllProcesses()
{   
     using (var searcher = new ManagementObjectSearcher(wmiQueryString))
            using (var results = searcher.Get()) // EXCEPTION THROWN!
            {
                // ...
            }
}

As you can see the exception is thrown when calling searcher.Get() . 如您所见,调用searcher.Get()时会引发异常。 Note: This method works without any issues if used outside the mouse event handler ( MouseUp ). 注意:如果在鼠标事件处理程序( MouseUp )之外使用此方法,则不会出现任何问题。

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() . 事实证明,如果涉及到MTA,并且您在SendMessage()中使用ManagementObjectSearcher方法,则COM要求您在STA上运行代码。
So, what I needed to do is to run my code on differet thread and set SetApartmentState to ApartmentState.STA . 因此,我需要做的是在SetApartmentState线程上运行我的代码,并将SetApartmentState设置为ApartmentState.STA

List<ProcessInfo> allRunningProcesses = null;

Thread threadProc = new Thread(() =>
{
    allRunningProcesses = Logic.GetAllProcesses();
});

threadProc.SetApartmentState(ApartmentState.STA);
threadProc.Start();
threadProc.Join();

Useful links: 有用的链接:

msdn- Understanding and Using COM Threading Models msdn- 了解和使用COM线程模型
stackoverflow- How to run something in the STA thread stackoverflow- 如何在STA线程中运行某些内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM