вопрос по реализации IQueryCancelAutoPlay в службе Windows - PullRequest
0 голосов
/ 07 апреля 2010

Я реализую IQueryCancelAutoPlay COM-интерфейс и регистрирую его с помощью таблицы запущенных объектов из службы Windows *.

Моя проблема в том, что он никогда не будет вызываться , когда я вставляю запоминающее устройство (или любое другое устройство на самом деле). Вот еще немного информации:

Мой код для регистрации в 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");

runningObjectTable-> Register возвращает S_OK, и в конце выполнения блока кода ref-count для listenerInstance равен 1 (если я полностью удаляю вызов runningObjectTable-> Register, ref-count остается 0, когда qcaListener выходит области видимости, так что это означает, что экземпляр моего класса остается активным в ROT).

Подробнее: при разработке моя служба работает с учетными данными моей учетной записи (локальный администратор). Хотя это, вероятно, изменится, оно должно работать так же, как и в текущей конфигурации.

Может кто-нибудь пролить свет на это?


* - я знаю, что в документации сказано, что я не должен реализовывать IQueryCancelAutoPlay в сервисе, но мне нужно делать это по разным причинам (бизнес-требования и т. Д.).

1 Ответ

1 голос
/ 12 апреля 2010

Я разобрался (для тех, кто наткнулся на этот ответ при возникновении аналогичной проблемы):

Служба работает под другой оконной станцией и другим рабочим столом. Когда реализация IQueryCalcelAutoPlay зарегистрирована в ROT, это делается для другого рабочего стола.

Оболочка рабочего стола текущего пользователя (проводник) не найдет эту регистрацию при подключении нового USB-устройства (поскольку оно не зарегистрировано на текущем рабочем столе).

...