Прототип ITaskHandler::Start
имеет следующий вид:
HRESULT ( STDMETHODCALLTYPE Start )(
__RPC__in ITaskHandler * This,
/* [in] */ __RPC__in_opt IUnknown *pHandlerServices,
/* [in] */ __RPC__in BSTR data)
Почему pHandlerServices
является необязательным - и если я получаю значение NULL (как в моем случае) - как я могу уведомить планировщик задач о том, что я выполнил задачу.
ОК - вот сделка, которую я реализовал QueryInterface
класса, чтобы всегда возвращать один и тот же объект, думая - ITaskHandler
будет немедленно запрошен. Однако это был не тот случай - первый запрос был для IClassFactory
, а сигнатура функции CreateInstance
имела второй параметр pUnkOuter
NULL, который перекрывается со вторым параметром моей реализации ITaskHandler_Start
. Тем не менее, странно, что pHandlerServices
помечен как необязательный.
Вот моя текущая реализация обработчика, который все еще не работает (последний результат выполнения - Нет такого интерфейса, поддерживаемого (0x80004002)) - мой интерфейс ITaskHandler
никогда не запрашивается. Я даже дошел до реализации ICallFactory
, но псевдоним без удачи (CreateCall
никогда не вызывается) - вот код:
#define COBJMACROS
#include <windows.h>
#include <objbase.h>
#include <unknwn.h>
// {179D1704-49C5-4111-B3CF-C528ABB014D0}
DEFINE_GUID(CLSID_IRmouseHandler,
0x179d1704, 0x49c5, 0x4111, 0xb3, 0xcf, 0xc5, 0x28, 0xab, 0xb0, 0x14, 0xd0);
#define wstringCLSID_IRmouseHandler L"{179D1704-49C5-4111-B3CF-C528ABB014D0}"
static const GUID CLSID_IRmouseHandler =
{ 0x179d1704, 0x49c5, 0x4111, { 0xb3, 0xcf, 0xc5, 0x28, 0xab, 0xb0, 0x14, 0xd0 } };
// {D363EF80-5C42-46D8-847B-B3A27A3BD0E3}
DEFINE_GUID(IID_IRmouseHandler,
0xd363ef80, 0x5c42, 0x46d8, 0x84, 0x7b, 0xb3, 0xa2, 0x7a, 0x3b, 0xd0, 0xe3);
static const GUID IID_IRmouseHandler =
{ 0xd363ef80, 0x5c42, 0x46d8, { 0x84, 0x7b, 0xb3, 0xa2, 0x7a, 0x3b, 0xd0, 0xe3 } };
#include <taskschd.h>
#include <ObjIdl.h>
#define stub(x)\
\
STDMETHODCALLTYPE x() {\
MessageBox(\
NULL,\
"ITaskHandler_" #x,\
"Account Details",\
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2\
);}
extern ITaskHandler tskhandler; extern IClassFactory factory; extern ICallFactory callfactory;
stub(CreateCall)
HRESULT ( STDMETHODCALLTYPE CreateInstance )(
IClassFactory * This,
/* [annotation][unique][in] */
_In_opt_ IUnknown *pUnkOuter,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject) { return QueryInterface(This, riid, ppvObject);}
HRESULT STDMETHODCALLTYPE QueryInterface(
__RPC__in ITaskHandler * This,
/* [in] */ __RPC__in REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject) {
if(!ppvObject) return E_POINTER;
if(!memcmp(riid, &IID_ITaskHandler, sizeof *riid) || !memcmp(riid, &IID_IUnknown, sizeof *riid))*ppvObject = &tskhandler;
else if(!memcmp(riid, &IID_ICallFactory, sizeof *riid))*ppvObject = &callfactory;
else if(!memcmp(riid, &IID_IClassFactory, sizeof *riid))*ppvObject = &factory;
else return E_NOINTERFACE;
return S_OK;}
ULONG STDMETHODCALLTYPE AddRef(){}
stub(Release)
HRESULT ( STDMETHODCALLTYPE Start )(
__RPC__in ITaskHandler * This,
/* [in] */ __RPC__in_opt IUnknown *pHandlerServices,
/* [in] */ __RPC__in BSTR data) {ITaskHandlerStatus *pHandlerStatus;
IUnknown_QueryInterface(pHandlerServices,&IID_ITaskHandlerStatus,&pHandlerStatus),
ITaskHandlerStatus_TaskCompleted(pHandlerStatus,S_OK);return S_OK;}
stub(Stop)
stub(Pause)
stub(Resume)
ITaskHandler tskhandler = {.lpVtbl = &(struct ITaskHandlerVtbl){.QueryInterface=QueryInterface,.Resume=Resume,
.AddRef=AddRef,.Release=Release,.Start=Start,.Stop=Stop,.Pause=Pause}};
IClassFactory factory = {.lpVtbl = &(struct IClassFactoryVtbl){.QueryInterface=QueryInterface,
.AddRef=AddRef,.Release=Release,.CreateInstance=CreateInstance}};
ICallFactory callfactory = {.lpVtbl = &(struct ICallFactoryVtbl){.QueryInterface=QueryInterface,
.AddRef=AddRef,.Release=Release,.CreateCall=CreateCall}};
int WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
) { DWORD dwToken; //AddVectoredExceptionHandler(1,PvectoredExceptionHandler);
CoInitializeEx(NULL,0), CoRegisterClassObject(&CLSID_IRmouseHandler,&tskhandler,CLSCTX_LOCAL_SERVER,REGCLS_MULTIPLEUSE,&dwToken),Sleep(INFINITE);}