我有一个程序正在为Windows中的磁盘执行原始IO。
如果目标磁盘在线,则一切正常。但是,某些Windows操作系统中的默认行为是让新磁盘最初脱机。
我很难在Windows上找到正确的API来执行此操作。等效的命令行类似于:
"select disk 2", "online disk" | diskpart
但是我需要能够在代码中执行此操作。我查看了DeviceIoControl Win32 API(我认为是正确的)但无法确定要使用的控件代码。我无法找到它的事实让我觉得我可能错过了一个更好的API来使用。
答案 0 :(得分:4)
对于后代,答案(在Win 2k3 / Vista及更高版本上)是虚拟磁盘服务(VDS)。有一些工作可以将它们整合在一起,特别是如果你不在.NET中使用COM对象那么多。
使用IVdsDrive::SetStatus完成在线/离线磁盘。至少它应该;我发现只需禁用磁盘上的只读状态就可以解决我的问题。我能够使用IVdsDisk::SetFlags和适当的标志值来执行此操作。
答案 1 :(得分:2)
This question有一些指向Windows API的有用链接,包括DeviceIOControl方法。
查看了所有枚举后,我找不到与将磁盘联机相关的任何内容,或者在格式化/分区之外对磁盘进行任何有趣的更改。这可能是因为此功能仅支持热插拔硬盘驱动器。热插拔硬盘的市场非常小,绝大多数情况下都有支持任何所需操作的驱动程序。最后,剩余部分应该能够使用diskpart工具进行必要的操作。
我认为您需要再次查看您的要求。您正在运行具有联机硬盘所需权限的进程,但无法访问命令行程序?以下是一些不使用命令行程序的常见原因的建议:
答案 2 :(得分:2)
不确定C#,但我在C ++中使用它:
尝试使用DeviceIoControl()
致电IOCTL_DISK_SET_DISK_ATTRIBUTES
。文件句柄必须具有读写访问权限。我认为它至少需要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;
}
答案 3 :(得分:0)
使用DeviceIoControl和IOCTL_DISK_IS_WRITABLE控制代码,可以检查磁盘是否可写。如果磁盘处于脱机状态,则返回false。这意味着可以确定磁盘是否处于脱机状态,并且可以在Windows 2003及之后正常运行。但是,我找不到任何有用的IOCTL来使磁盘在Windows 2003上联机.IOCTL_DISK_SET_DISK_ATTRIBUTES仅适用于Windows 2008及之后。