Quick info: I am using Visual Studio 2008, Windows 8 (64-bit).
I am trying to creating an AutoPlay Handler that presents itself when a WPD device is plugged into the computer. If my AutoPlay option is selected, all I want it to do is to simply launch my application.
Since there aren't any recent examples of implementing AutoPlay for Windows, I was hoping someone could help me out a little and answer a couple of questions:
1). I have created an ATL project with a COM object that implements the IHWEventHandler interface. Initially, all I am trying to get the COM object to do is to create a .txt file in my C drive to indicate that it was called successfully. I have tried getting my AutoPlay event to point to this COM object, but nothing happens when I select my AutoPlay entry. Here is my .h code for my COM class:
class ATL_NO_VTABLE CSimpleAutoPlayCom :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSimpleAutoPlayCom, &CLSID_SimpleAutoPlayCom>,
public IHWEventHandler
//public ISimpleAutoPlayCom
{
public:
CSimpleAutoPlayCom()
{
ofstream myfile;
myfile.open ("C:\\AutoPlayExerciseWorked.txt");
myfile << "Called from Constructor.\n";
myfile.close();
}
DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLEAUTOPLAYCOM)
DECLARE_NOT_AGGREGATABLE(CSimpleAutoPlayCom)
BEGIN_COM_MAP(CSimpleAutoPlayCom)
//COM_INTERFACE_ENTRY(ISimpleAutoPlayCom)
COM_INTERFACE_ENTRY(IHWEventHandler)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
// IHWEventHandler
STDMETHODIMP Initialize(__RPC__in LPCWSTR pszParams);
STDMETHODIMP HandleEvent(__RPC__in LPCWSTR pszDeviceID, __RPC__in LPCWSTR pszAltDeviceID, __RPC__in LPCWSTR pszEventType);
STDMETHODIMP HandleEventWithContent(__RPC__in LPCWSTR pszDeviceID, __RPC__in LPCWSTR pszAltDeviceID, __RPC__in LPCWSTR pszEventType, __RPC__in LPCWSTR pszContentTypeHandler, __RPC__in_opt IDataObject *pdataobject);
};
This is the .cpp:
// CSimpleAutoPlayCom
STDMETHODIMP CSimpleAutoPlayCom::Initialize(__RPC__in LPCWSTR pszParams)
{
ofstream myfile;
myfile.open ("C:\\AutoPlayExerciseWorked.txt");
myfile << "Called from Initialize\n";
myfile.close();
return S_OK;
}
STDMETHODIMP CSimpleAutoPlayCom::HandleEvent(__RPC__in LPCWSTR pszDeviceID, __RPC__in LPCWSTR pszAltDeviceID, __RPC__in LPCWSTR pszEventType)
{
ofstream myfile;
myfile.open ("C:\\AutoPlayExerciseWorked.txt");
myfile << "Called from HandleEvent.\n";
myfile.close();
return S_OK;
}
STDMETHODIMP CSimpleAutoPlayCom::HandleEventWithContent(__RPC__in LPCWSTR pszDeviceID, __RPC__in LPCWSTR pszAltDeviceID, __RPC__in LPCWSTR pszEventType, __RPC__in LPCWSTR pszContentTypeHandler, __RPC__in_opt IDataObject *pdataobject)
{
ofstream myfile;
myfile.open ("C:\\AutoPlayExerciseWorked.txt");
myfile << "Called from HandleEventWithContent.\n";
myfile.close();
return S_OK;
}
Overall, does this implementation look correct? Do I need to implement any additional interface in order to get my AutoPlay event to call this COM object?
I understand that when i build the project, Visual Studio automatically registers my COM object. I build my COM object for 64-bit windows, and register the .dll using regsvr32.exe as well, but this does not seem to help.
2). Also, I am suspecting that perhaps I did not register my AutoPlay registry keys correctly. I first manually added my Autoplay event handler like so:
HKEY_LOCAL_MACHINE > SOFTWARE > Microsoft > Windows > CurrentVersion > Explorer > AutoPlayHandlers > Handlers > MyAutoPlayHandler
MyAutoPlayHandler holds the following:
Action REG_SZ MyAction
DefaultIcon REG_SZ (directory to my application icon)
InvokeProgID REG_SZ (name of key under HKEY_CLASSES_ROOT that was generated by my ATL project: AutoPlayExericesCom.SimpleAutoPlayCom.1)
InvokeVerb REG_SZ open
Provider REG_SZ Myself
Then I added MyAutoPlayHandler to the following:
HKEY_LOCAL_MACHINE > SOFTWARE > Microsoft > Windows > CurrentVersion > Explorer > AutoPlayHandlers > EventHandlers > WPD > Function > {2D8A6512-A74C-448E-BA8A-F4AC07C49399} which is WPD_FUNCTIONAL_CATEGORY_ALL
Cool, so I plug in my Android device, and I see my AutoPlay entry in the AutoPlay list. I click it, and nothing happens (no txt file was created in the C drive as I was expecting).
So I Additionally create another key like the following:
HKEY_CLASSES_ROOT > MyAutoPlayDropHandler > shell > open > DropTarget
Where DropTarget Contains a CLSID value with the CLSID idea of the COM object I created. I change the InvokeProgID to point to this key, but still nothing happens.
For experimentation, I tried adding my handler under the ShowPicturesOnArrival key, and when plugging in a USB drive containing images, then selecting my AutoPlay Entry, I got the following error message:
"This file does not have a program associated with it to perform this action. Please install a program or, if on is already installed, create an association in the Default Programs control panel."
So now I have some kind of error response to the ShowPicturesOnArrival key, but why nothing for the WPD? I'm suspecting I'm missing something somewhere to get this to work, but I am running out of ideas. Any suggestions that I could try to fix this would be greatly appreciated.