2012-01-12 46 views
1

我希望能够检测Windows在何时卸载卷(它可以是外部USB/FireWire/eSATA驱动器,网络共享文件夹或任何其他类型的逻辑卷)。在Windows上检测未安装的卷

我在MSDN上发现了RegisterDeviceNotification()功能,该功能非常适用于检测USB驱动器的连接/断开。此功能是否也可以用于各种音量,或只是外部物理设备? 如果没有,你是否知道我可以用它来做什么(除了投票)?

最后一个问题,我是新来在Windows C++和RegisterDeviceNotification()医生说,我的第一个参数是A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter.

以我为例,我本来想在我的程序的main()功能的通知注册,有某种onNotificationReceived()方法来处理通知。我可以这样做吗(如果是,如何),还是必须注册另一个在另一个进程中运行的窗口/服务?

回答

3

WM_DEVICECHANGE通知申请量达到和移除,你甚至不需要拨打RegisterDeviceNotification()

寻找dbch_devicetype == DBT_DEVTYP_VOLUME

还有an example in the documentation

+0

这听起来像我想要做的,所以,为了接收这些消息,我只需要在我的程序中声明一个回调函数?我在哪里可以找到这个功能的签名?谢谢! – nbarraille 2012-01-12 21:06:36

+0

@nbarraille:WM_DEVICECHANGE消息应发送到所有顶级窗口。所以在你的WndProc中处理它们,或者你最喜欢的框架给你处理窗口消息的地方。 – 2012-01-12 21:43:40

+1

我的程序只是一个控制台程序,它没有窗口。我如何注册以接收这些通知? – nbarraille 2012-01-12 22:00:25

0

获取唯一的卷名已卸载驱动器: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; 
} 
0

只是一个建议,但你可能想看看创建一个Windows Shell扩展,它可以接收通知系统的各种更改。

例如,实现IShellChangeNotify接口包括一个OnChange方法,该方法可以接收包括SHCNE_DRIVEREMOVED, SHCNE_MEDIAREMOVED, SHCNE_NETUNSHARE等在内的整个范围的通知。

您将不得不创建并注册一个DLL(即它不会是一个独立的exe),但我认为它会为您提供您正在查找的各种通知。