2011-09-23 80 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及之后的版本。