【问题标题】:How to access hidden partitions/volumes如何访问隐藏的分区/卷
【发布时间】:2015-09-08 09:58:03
【问题描述】:

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

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

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

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

编辑

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

我认为应该是一种使用它们的 ID(或名称)过滤卷的方法。 比如:

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

或者更漂亮的方式,比如:

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

另外,我在 Partitions and Volumes 中找到了一个优秀的 awenser(它们不是一回事) https://social.technet.microsoft.com/Forums/en-US/e7b2ddd6-f245-49ed-8fec-3b6e08e75369/how-do-i-find-the-partition-guid?forum=winservergen

EDIT2

Harry 认为,使用“\.\Volume....”是恢复文件的好方法。但我找不到使用 c# 编写(创建)新文件的方法。 迄今为止最好的方法是使用 pinvoke 到 c++ CreateFile 方法/句柄。


有什么建议吗?

【问题讨论】:

  • “找不到关于此事的任何帮助参考” - 您在问题中的链接是否为您下次搜索提供了很多提示?您是否阅读了有关示例中使用的每个功能的详细信息?在这一点上,您的问题可能非常广泛...
  • 在 C++ 中,您可以使用 GetLogicalDriveStrings stackoverflow.com/a/18573199/4603670GetDriveType

标签: c# c++ winapi wmi disk-partitioning


【解决方案1】:

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}\");

【讨论】:

  • Harry,非常感谢您使用“\\.\”的提示,它适用于 GetFiles。关于写文件,我猜那是更深层次的东西。我尝试使用 File.Create 和其他 Stream 低级方法,但不断收到此异常:“FileStream 不会打开 Win32 设备,例如磁盘分区和磁带驱动器。避免在路径中使用“\\.\”。”我想唯一的方法是对 CreateFile c++ 方法使用 pinvoke。
  • 德拉特。您的程序可以将卷临时安装在某个文件夹上吗?或者,如果您有管理员权限,您可以创建一个目录符号链接,这将是一种侵入性较小的方法。
  • 我认为这不是我申请的好方法。无论如何,你的 awenser 帮了很多忙。我可能会在某些情况下使用 pinvoke,并且将来可能会重写 c# File 类以支持这种操作。顺便说一句,感谢您的帮助!
【解决方案2】:

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

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

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

接下来,您可以在 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 类的方法。例如,您可以检查每个磁盘的错误:

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

【讨论】:

  • 感谢托马斯的建议。我设法使用 WMI 查询来检索琐碎的有用信息。但找不到列出“驱动器的所有文件”的方法。因为当驱动器被隐藏时,“驱动程序”属性为空或为空。我不能只是找到一种过滤该信息的方法,并且没有路径过滤器它会带来整个机器的所有文件,呵呵。任何方式都非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 2023-03-20
  • 2017-05-20
相关资源
最近更新 更多