Visual c++ 在windows服务中实现IQueryCancelAutoPlay的问题

Visual c++ 在windows服务中实现IQueryCancelAutoPlay的问题,visual-c++,com,windows-services,Visual C++,Com,Windows Services,我正在实现IQueryCancelAutoPlay COM接口,并从Windows服务*将其注册到Running Objects表中 我的问题是,当我插入大容量存储设备(或任何真正的设备)时,它从未被调用。以下是更多信息: 我在ROT注册的代码: Text::string clsIdString = Text::to_string(Com::CLSID_QCAListener); // remove curly braces clsIdString = clsIdString.substr(1,

我正在实现IQueryCancelAutoPlay COM接口,并从Windows服务*将其注册到Running Objects表中

我的问题是,当我插入大容量存储设备(或任何真正的设备)时,它从未被调用。以下是更多信息:

我在ROT注册的代码:

Text::string clsIdString = Text::to_string(Com::CLSID_QCAListener);
// remove curly braces
clsIdString = clsIdString.substr(1, clsIdString.length() - 2);

// set registry key to make sure we get notifications from windows
Reg::SetValue(HKEY_LOCAL_MACHINE, 
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\CancelAutoplay\\CLSID"),
clsIdString, _T(""));

HRESULT result = S_OK;

// create class moniker ...
CComPtr<IMoniker> moniker;
result = CreateClassMoniker(Com::CLSID_QCAListener, &moniker);
if( !ValidateResult(result, "Error creating class moniker") )
return;

DBG << _T("Getting IRunningObjectTable pointer ...") << std::endl;

// get running oject table ... 
CComPtr<IRunningObjectTable> runningObjectTable;
result = GetRunningObjectTable(0, &runningObjectTable);
if( !ValidateResult(result, "Error getting running object table") )
return;

// create an instance of the QCAListener class ...
Com::QCAListener * listenerInstance = new Com::QCAListener();
if(!ValidateResult( listenerInstance != 0,
"Error creating QueryCancelAutoplayListener"))
return;
// ... and set the pointer in the _qcaListener variable
CComPtr<IQueryCancelAutoPlay> qcaListener;
listenerInstance->QueryInterface(IID_IQueryCancelAutoPlay, reinterpret_cast<void**>(&qcaListener));

DBG << _T("Registering IQueryCancelAutoPlay with ROT ...") << std::endl;
result = runningObjectTable->Register(
ROTFLAGS_REGISTRATIONKEEPSALIVE,
listenerInstance,
moniker,
&_qcaRegistration);
ValidateResult(result, "Error registering QueryCancelAutoplayListener with the ROT");
Text::string clsIdString=Text::to_string(Com::CLSID_QCAListener);
//去掉花括号
clsIdString=clsIdString.substr(1,clsIdString.length()-2);
//设置注册表项以确保从windows获取通知
注册表::设置值(HKEY_本地_机器,
_T(“软件\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\CancelAutoplay\\CLSID”),
clsIdString,_T(“”);
HRESULT结果=S_正常;
//创建类名字对象。。。
CComPtr名字;
结果=CreateClassMoniker(Com::CLSID_QCAListener,&moniker);
if(!ValidateResult(结果,“创建类名字对象时出错”))
返回;
DBG我找到了答案(对于那些遇到类似问题时偶然发现这个答案的人):

该服务在不同的窗口站和不同的桌面下运行。当
IQueryCalcelAutoPlay
实现在
ROT
中注册时,这是针对不同的桌面完成的


插入新的USB设备时,当前用户的桌面外壳(explorer)将找不到此注册(因为它未在当前桌面上注册)。

我刚刚从MFC/GUI应用程序中尝试了相同的代码,它可以工作:(