关于C#:如何访问隐藏的分区/卷

How to access hidden partitions/volumes

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

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

我的应用程序将从thoose分区中写入和读取数据,我必须找到一种对thoose进行诸如" c:"之类的方法。

Volumes 5,6 are hidden partitions

在上图中,卷5和6是隐藏的分区。
我在stackoverflow上找到了此链接,但仅"列出"了de分区:
https://msdn.microsoft.com/zh-CN/library/cc542456(v=VS.85).aspx

编辑

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

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

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

或更漂亮的方法是:

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

另外,我在分区和卷方面发现了一个出色的awenser(它们是不同的东西)
https://social.technet.microsoft.com/Forums/zh-CN/e7b2ddd6-f245-49ed-8fec-3b6e08e75369/how-do-i-find-the-partition-guid?forum=winservergen

编辑2

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

有什么建议吗?


如果您的程序是Windows特定的,则可以使用WMI。我与WMI进行了很多合作,可以很方便地进行任何类型的操作或获取有关Windows系统的数据。

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

  • Win32_LogicalDisk:包含所有磁盘,也包含隐藏磁盘。
  • CIM_Directory:包含所有目录(据我所知,也来自隐藏磁盘)
  • CIM_DataFile:包含所有文件(我也认为此文件还包含来自隐藏磁盘的文件)
  • 您可以使用更多类,例如检索文件权限... Microsoft有一个很好的文档

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

1
2
3
4
5
6
7
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类的methots。例如,您可以检查每个磁盘上的错误:

1
2
3
4
5
foreach (ManagementObject disk in searcher.Get())
{
    if(shouldCheckThisDisk)
        disk.Chkdsk();
}


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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    HANDLE h1, h2;
    wchar_t volpath[4096];
    WIN32_FIND_DATA find_data;

    h1 = FindFirstVolume(volpath, _countof(volpath));

    printf("%ws\
"
, volpath);

    wcscat_s(volpath, _countof(volpath), L"*.*");

    h2 = FindFirstFile(volpath, &find_data);

    printf("%ws\
"
, find_data.cFileName);

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

附录

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

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

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

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