问题
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.
回答1:
I know this has been a while, but for anyone else who finds this post I solved this issue that I was also having by copying how VLC does AutoPlay Events. It doesn't allow you to call running code, but it will at least allow you to call your application with whatever command line arguments you wish.
Just add the following registry keys to your machine, replacing VLC with your app.
HKEY_CLASSES_ROOT
VLC
shell
import
Open
command
Default = "[Path]\vlc.exe" --started-from-file dvd:///%1
HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Windows
CurrentVersion
Explorer
AutoplayHandlers
EventHandlers
PlayDVDMovieOnArrival
VLCPlayDVDMovieOnArrival [REG_SZ]
Handlers
VLCPlayDVDMovieOnArrival
Action [REG_SZ]= Play DVD Movie
DefaultIcon [REG_EXPAND_SZ]= [somepath]\VLC.exe, 0
InvokeProgID [REG_SZ]= VLC.DVDMovie
InvokeVerb [REG_SZ]= Open
Provider [REG_SZ]= VideoLanVLC media player
来源:https://stackoverflow.com/questions/15227425/how-to-implement-autoplay-for-windows-7-8