[转] 检测硬件设备的变化

发布时间:2010-2-11 15:35
分类名称:windows


WINDOWS平台上的应用程序监视硬件设备的接入和移除,大致有三种方法

1.响应WM_DEVICECHANGE消息

当外接设备发生变化时,系统会向所有的top-level窗口发送此广播消息。可使用如下代码响应消息
BEGIN_MESSAGE_MAP(CHWDetectDlg, CDialog)
ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)
END_MESSAGE_MAP()

LRESULT CHWDetectDlg::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
switch(wParam)
{
case DBT_DEVICEARRIVAL:
break;
case DBT_DEVICEREMOVECOMPLETE:
break;
default:
break;
}

return 0;
}


注意:非top-level的窗口默认是收不到WM_DEVICECHANGE消息的,如果需要接收必须调用RegisterDeviceNotification来注册。另外,
驱动器中介质的变化(例如从读卡器中移除SD卡)不会发送该通知


2.用SHChangeNotifyRegister从资源管理器接收通知
#define WM_MY_DEVICECHANGED (WM_USER+1203)

SHChangeNotifyEntry shcnEntry;
shcnEntry.fRecursive = TRUE;
shcnEntry.pidl = NULL;
ULONG uIndex = SHChangeNotifyRegister(hWnd, SHCNRF_InterruptLevel|SHCNRF_ShellLevel|SHCNRF_RecursiveInterrupt,SHCNE_DRIVEADD|SHCNE_DRIVEREMOVED|
SHCNE_MEDIAINSERTED|SHCNE_MEDIAREMOVED, WM_MY_DEVICECHANGED, 1, &shcnEntry);
//响应方式跟WM_DEVICECHANGE一样
SHChangeNotifyDeregister(uIndex);


注意:这种方式依赖于Windows Shell(explorer.exe)和“Shell Hardware Detection”服务的运行。如果Shell终止或重启,则监控会失效;
如果后面的服务终止或重启,则监控不到光驱中介质的变化和读卡器中卡的拔插


3.定时检测某些设备是否存在
SetTimer(...);
afx_msg void OnTimer(UINT_PTR nIDEvent);

对于USB设备和光驱,检测函数可选用CreateFile,GetFileAttributes,GetDiskFreeSpaceEx等
CreateFile(_T("\\\\.\\G:")...);
GetFileAttributes(_T("G:\\"));
GetDiskFreeSpaceEx(_T("G:\\")...);

调用完检测函数后,立刻取GetLastError的值,如果等于ERROR_PATH_NOT_FOUND则表明设备不存在,如果是ERROR_NOT_READY则表示驱动器(DRIVE)存在但其中没有存储介质(MEDIA)