我希望能够检测到何时在Windows上卸载卷(它可能是外部USB / FireWire / eSATA驱动器,网络共享文件夹或任何其他类型的逻辑卷)。
我发现MSDN上的RegisterDeviceNotification()
功能是检测USB驱动器连接/断开的常用功能。此功能是否也适用于所有类型的卷,或仅适用于外部物理设备?
如果没有,你是否知道我可以用它做什么(除了民意测验)?
最后一个问题,我是Windows上的C ++新手,RegisterDeviceNotification()
doc说我的第一个参数应该是A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter.
在我的情况下,我本来想在我的程序的main()
函数中注册通知,并使用某种onNotificationReceived()
方法来处理通知。我可以这样做(如果是,如何),还是我必须注册另一个在另一个进程中运行的窗口/服务?
答案 0 :(得分:3)
WM_DEVICECHANGE
通知应用程序已到达和删除卷,您甚至不必致电RegisterDeviceNotification()
。
寻找dbch_devicetype == DBT_DEVTYP_VOLUME
。
答案 1 :(得分:1)
获取已卸载驱动器的唯一卷名:http://help.lockergnome.com/windows2/unique-volume-unmounted-drive--ftopict477553.html
FSCTL_IS_VOLUME_MOUNTED
确定是否已装入指定的卷,或者指定的文件或目录是否已装入卷:http://msdn.microsoft.com/en-us/library/windows/desktop/aa364574(v=vs.85).aspx
如何检测该驱动器号上是否装有卷。
bool DiskInDrive(
std::wstring const& inDrive)
{
std::wstring volume = std::wstring(L"\\\\.\\") + inDrive.substr(0, 2);
HANDLE h = CreateFileW(
volume.c_str(),
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
0,
NULL);
if(h == INVALID_HANDLE_VALUE)
{
DWORD lastError = GetLastError();
// 2 means "no disk", anything else means by inference "disk
// in drive, but you do not have admin privs to do a
// CreateFile on that volume".
return lastError != 2;
}
DWORD bytesReturned; // ignored
BOOL devSuccess = DeviceIoControl(h, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &bytesReturned, NULL);
if(devSuccess == FALSE)
{
DWORD lastError = GetLastError();
(void)lastError; // For debugging.
// Presumably, any error means "no disk in drive", or more
// accurately, "no volume mounted on that drive letter".
CloseHandle(h);
return false;
}
CloseHandle(h);
return true;
}
答案 2 :(得分:0)
只是一个建议,但您可能需要考虑创建一个Windows Shell扩展,它可以接收有关系统各种更改的通知。
例如,实施IShellChangeNotify
界面包含OnChange
方法,该方法可以接收包括SHCNE_DRIVEREMOVED, SHCNE_MEDIAREMOVED, SHCNE_NETUNSHARE
等在内的各种通知。
你必须创建并注册一个DLL(即它不是一个独立的exe),但我认为它会为你提供你正在寻找的各种通知。