我有一个运行Chrome客户端浏览器的应用程序,有时需要执行WMI代码以访问某些设备信息,但是每次都会失败。仅当应用程序不使用TChromium对象时,它才起作用。可能的TChromium(CEF3)初始化COM库,并且当前线程上仅允许一个实例。我读到该应用程序应将CoInitializeEx与COINIT_APARTMENTTHREADED一起使用,而不是CoInitialize。
在一个应用程序中使用TChromium(CEF3)时可以访问COM库和CoInitializeSecurity吗?如果是,该怎么办?
下面是我要实现的目标:
CoUninitialize();
CoInitialize(NULL);
if(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0) == S_OK)
{
// cannot get here, CoInitializeSecurity fails
... need to execute WMI code using IWbemLocator, IWbemServices ...
}
答案 0 :(得分:3)
COM每个线程只能初始化1次。每个线程可以多次调用CoInitialize/Ex()
(每次成功调用都会调用相应的CoUninitialize()
,每次调用 CoInitialize/Ex()
),但是COM仅在第一次调用时被初始化,如果COM已在调用线程上初始化,则后续调用将返回S_FALSE
或RPC_E_CHANGED_MODE
。
要解决您的问题,请尝试将WMI代码移动到单独的工作线程中,然后完全控制要为该线程初始化COM的方式,与在主UI线程上初始化COM的方式完全分开。让您的主线程在需要时创建WMI线程并等待其终止,然后WMI线程可以查询设备信息并将其传递回主线程。