2012-01-12 84 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),但我認爲它會爲您提供您正在查找的各種通知。