2011-09-23 49 views
5

我有一個程序在Windows中對原始IO執行磁盤操作。在線/離線取盤

如果目標磁盤在線,所有工作正常。但是,某些Windows操作系統的默認行爲是讓新磁盤初始脫機。

我很難找到正確的API在Windows上執行此操作。命令行等效將是這樣的:

"select disk 2", "online disk" | diskpart 

但是我需要能夠在代碼中做到這一點。我查看了DeviceIoControl Win32 API(我認爲是正確的),但無法確定使用哪個控制代碼。我無法找到它的事實讓我想我可能會錯過一個更好的API來使用。

+0

爲什麼不只是shell從C#執行命令行呢? –

+1

由於多種原因,但足以說這不是一個選項。如果diskmgmt和diskpart可以做到這一點,有一種方法。我想知道那是什麼。 – Joe

+1

@joe - diskmgmt和diskpart是gui對Windows內置的命令,它們可能使用Win32 API。考慮到他們已經有一段時間了,這不太可能。您可以通過命令行完成的任何操作。 –

回答

2

This question有幾個有用的鏈接到Windows API,包括DeviceIOControl方法。

查看完所有枚舉後,我找不到任何與使磁盤聯機有關的任何內容,或者對格式化/分區之外的磁盤進行任何有趣的更改。這可能是因爲此功能僅支持熱插拔硬盤驅動器。熱插拔硬盤驅動器的市場非常小,而且絕大多數情況下都有驅動程序來支持任何需要的操作。最後剩下的部分應該能夠使用diskpart工具來完成任何必要的工作。

你需要再次看看我的想法。您正在運行具有聯機硬盤權限的進程,但無法訪問命令行程序?以下是常見的原因的一些建議,不使用命令行程序:

  • 不能有一個黑色的屏幕彈出 - 噸可用的解決方案這個問題在網上
  • 保安隊不會允許它 - 你已經在以管理員身份運行進程,所以你信任它,你爲什麼不相信內置的Windows功能
  • 技術問題排除了調用其他進程 - 我會感興趣的是,管理員
  • 編碼指南,如「始終使用API​​」 - 由於缺乏需要而沒有一個編號爲
+0

對於熱插拔以外的動態磁盤,實際上有很多用途。感謝您的鏈接,我發現雖然您注意到那裏沒有真正的解決方案。 – Joe

+0

@Joe:我的意思是驅動器的物理能力不是動作 – Guvante

4

對於後代,答案(Win 2k3/Vista及更高版本)是虛擬磁盤服務(VDS)。有一些工作將它們放在一起,特別是如果你不在.NET中使用COM對象。

磁盤在線/離線使用IVdsDrive::SetStatus完成。至少它應該;我發現只需在磁盤上禁用只讀狀態即可解決我的問題。我可以用IVdsDisk::SetFlags和相應的標誌值做到這一點。

+0

api是一個很大的地獄,我該如何使用它?文件真的不清楚。 – Gizmo

2

不確定C#,但我在C++中使用它: 嘗試使用IOCTL_DISK_SET_DISK_ATTRIBUTES調用DeviceIoControl()。文件句柄必須具有讀取和寫入權限。我認爲它至少需要Windows 7.它不適用於Windows 2003 x64。 Windows 8成功將磁盤脫機,然後您可以從備份中重寫該磁盤。

BOOL disk_offline(HANDLE h_file, bool enable){ 
DWORD bytes_returned = 0; 
BOOL b_offline = 0; 
if(get_size_volume_disk(h_file)){ 
    SET_DISK_ATTRIBUTES disk_attr; 
    ZeroMemory(&disk_attr, sizeof(disk_attr)); 
    disk_attr.Version = sizeof(SET_DISK_ATTRIBUTES); 
    disk_attr.Attributes = enable? DISK_ATTRIBUTE_OFFLINE: 0; 
    disk_attr.AttributesMask = DISK_ATTRIBUTE_OFFLINE; 
    b_offline = DeviceIoControl(h_file, IOCTL_DISK_SET_DISK_ATTRIBUTES, &disk_attr, disk_attr.Version, NULL, 0, &bytes_returned, NULL); 
    // Invalidates the cached partition table and re-enumerates the device. 
    if(!enable) BOOL b_update = DeviceIoControl(h_file, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &bytes_returned, NULL); 
} 
return b_offline; 
} 
0

使用的DeviceIoControl和IOCTL_DISK_IS_WRITABLE控制代碼,可以檢查磁盤是否可寫。如果磁盤脫機,則返回false。這意味着可以確定磁盤是否處於脫機狀態,並且可以在Windows 2003及之後正常工作。但是,我找不到任何有用的IOCTL在Windows 2003上使磁盤聯機。IOCTL_DISK_SET_DISK_ATTRIBUTES僅適用於Windows 2008及之後的版本。