如何访问隐藏的分区/卷

我必须编写一个代码来使用c#或c ++访问隐藏的磁盘分区/卷。 但在这件事上找不到任何帮助参考。

作为隐藏卷,它不包含“磁盘字母”,因此您不能只键入“C:\”并访问它。 一个例子是Windows附带的“恢复分区”。 你无法在资源管理器上看到它但它就在那里。

我的应用程序将从thoose分区写入和读取数据,我必须找到一种方法来执行类似“c:\”的操作。

第5,6卷是隐藏分区

在上图中,卷5和6是隐藏的分区。 我在stackoverflow上找到了这个链接,但它只是“列出”de分区: https : //msdn.microsoft.com/en-us/library/cc542456(v = VS.85).aspx

编辑

问题是:即使使用WMI作为建议,我也找不到在查找文件时如何过滤卷。 例如, select * from win32_DataFile将列出机器中的所有文件。

我认为应该是一种使用ID(或名称)过滤Volumes的方法。 就像是:

 select * from win32_DataFile where volumeId = '\\?\Volume{2d5f3a68-75f5-44c4-aa42-716b45811916}\' 

或者更美丽的方式:

 var files = Directory.GetFiles(@"\\?\Volume{6ff7748e-78db-4838-8896-254b074918f5}\"); 

此外,我发现了一个关于分区和卷的优秀的awenser(它们不是一回事) https://social.technet.microsoft.com/Forums/en-US/e7b2ddd6-f245-49ed-8fec-3b6e08e75369/how- DO-找到的最分区全局唯一标识符?论坛= winservergen

EDIT2

正如Harry所说,使用“\。\ Volume ….”是恢复文件的好方法。 但我找不到使用c#编写(创建)新文件的方法。 到目前为止,最好的approch是使用pinvoke来实现c ++ CreateFile方法/句柄。


任何建议?

FindFirstVolume()API返回系统上每个卷的根的路径。

例如,此代码打印第一个卷的路径,以及该卷根目录中第一个文件的名称:

  HANDLE h1, h2; wchar_t volpath[4096]; WIN32_FIND_DATA find_data; h1 = FindFirstVolume(volpath, _countof(volpath)); printf("%ws\n", volpath); wcscat_s(volpath, _countof(volpath), L"*.*"); h2 = FindFirstFile(volpath, &find_data); printf("%ws\n", find_data.cFileName); 

(在生产代码中,您需要添加错误检查等)

附录

FindFirstVolume返回如下路径: \\?\Volume{6ff7748e-78db-4838-8896-254b074918f5}\

如果您在C ++中使用Win32 API(CreateFile等),则可以直接使用该路径,但由于.NET中的错误或限制,它不适用于文件管理类,如Directory.GetFiles()。 (当然,你可以P / Invoke到Win32 API,但这很尴尬。)

相反,您可以通过用点替换路径开头出现的问号来解决此问题:

 var files = Directory.GetFiles(@"\\.\Volume{6ff7748e-78db-4838-8896-254b074918f5}\"); 

如果您的程序是Windows特定的,则可以使用WMI。 我在WMI上做了很多工作,做任何类型的操作或获取有关Windows系统的数据都非常方便。

首先,您可以下载wmiexplorer以查看可用的数据和类。 您的相关命名空间将是root\cimv 。 在那里你可以找到各种有趣的课程:

  • Win32_LogicalDisk :包含所有磁盘,也包含隐藏的磁盘。
  • CIM_Directory :包含所有目录(据我所知也是隐藏的磁盘)
  • CIM_DataFile :包含所有文件(我也认为这个文件还包含来自隐藏磁盘的文件)
  • 你可以使用更多的类来检索文件权限……微软有一个非常好的文档

接下来,您可以在C#(或VB.NET)程序中实现所需的WMI查询。 例如,这个将打印所有磁盘:

 WqlObjectQuery wqlQuery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(wqlQuery); foreach (ManagementObject disk in searcher.Get()) { Console.WriteLine(disk.ToString()); } 

如您所见,WMI支持SQL之类的查询(尽管它不那么强大……)

WMI还支持大多数ist类的methot。 例如,您可以检查每个磁盘的错误:

 foreach (ManagementObject disk in searcher.Get()) { if(shouldCheckThisDisk) disk.Chkdsk(); }