[英]C# and diskpart: how to select by disk label and not by a number?
I have a C# application that install Windows image.我有一个安装 Windows 映像的 C# 应用程序。 I have to choose the disk where the system will copied (C: or D: or ...) on the user interface.
我必须在用户界面上选择系统将复制到的磁盘(C: 或 D: 或 ...)。 For that, it's ok.
为此,没关系。
Then i have to format the disk.然后我必须格式化磁盘。 I have to select with diskpart.exe the good physical disk associed to C:.
我必须使用diskpart.exe 选择与C: 关联的良好物理磁盘。 But with diskpart, we choose the disk with number: select disk 0 or 1 or ...
但是对于diskpart,我们选择带有编号的磁盘:选择磁盘0或1或...
How to make the connection between the good disk number and the letter choosen by users on the interface ?如何将好的盘号与用户在界面上选择的盘符进行连接?
I found Nothing on google.我在谷歌上什么也没找到。 I tried to find an information with wmi
Win32_DiskDrive
but nothing in common with diskpart detail disk .我尝试使用 wmi
Win32_DiskDrive
查找信息,但与 diskpart detail disk 没有任何共同之处。
Thank's谢谢
Another solution instead of using ManagementObjectSearcher
is using DiskPart.exe
programatically, but my code is rather a static solution (would be better with regex) but will work a long time.另一种不使用
ManagementObjectSearcher
解决方案是以编程方式使用DiskPart.exe
,但我的代码是一个静态解决方案(使用正则表达式会更好)但会工作很长时间。
It requires a manifest file with higher execution privileges (Add new element > Application Manifest File and change requestedExecutionLevel
to <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
. for further information: https://stackoverflow.com/a/43941461/5830773 )它需要具有较高的执行权限(添加新元素的清单文件>应用程序清单文件和变化
requestedExecutionLevel
到<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
进一步的信息: https://stackoverflow.com/a/ 43941461/5830773 )
Then you can use following code to get the drive list with DiskPart.exe
:然后您可以使用以下代码通过
DiskPart.exe
获取驱动器列表:
// execute DiskPart programatically
Process process = new Process();
process.StartInfo.FileName = "diskpart.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.StandardInput.WriteLine("list volume");
process.StandardInput.WriteLine("exit");
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// extract information from output
string table = output.Split(new string[] { "DISKPART>" }, StringSplitOptions.None)[1];
var rows = table.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 3; i < rows.Length; i++)
{
if (rows[i].Contains("Volume"))
{
int index = Int32.Parse(rows[i].Split(new string[] { " " }, StringSplitOptions.None)[3]);
string label = rows[i].Split(new string[] { " " }, StringSplitOptions.None)[8];
Console.WriteLine($@"Volume {index} {label}:\");
}
}
This gives following output like from DiskPart but you can customise it for your needs:这提供了类似于 DiskPart 的以下输出,但您可以根据需要对其进行自定义:
Volume 0 C:\
Volume 1 D:\
Volume 2 F:\
Volume 3 G:\
Volume 4 I:\
Volume 5 H:\
Now searching by drive letter is obvious:现在按驱动器号搜索很明显:
public int GetIndexOfDrive(string drive)
{
drive = drive.Replace(":", "").Replace(@"\", "");
// execute DiskPart programatically
Process process = new Process();
process.StartInfo.FileName = "diskpart.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.StandardInput.WriteLine("list volume");
process.StandardInput.WriteLine("exit");
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// extract information from output
string table = output.Split(new string[] { "DISKPART>" }, StringSplitOptions.None)[1];
var rows = table.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 3; i < rows.Length; i++)
{
if (rows[i].Contains("Volume"))
{
int index = Int32.Parse(rows[i].Split(new string[] { " " }, StringSplitOptions.None)[3]);
string label = rows[i].Split(new string[] { " " }, StringSplitOptions.None)[8];
if (label.Equals(drive))
{
return index;
}
}
}
return -1;
}
Usage:用法:
Console.WriteLine(GetIndexOfDrive(@"D:\")); // returns 1 on my computer
To map between disk and logical drive(C:, D:, etc), you have to get the information from:要在磁盘和逻辑驱动器(C:、D: 等)之间进行映射,您必须从以下位置获取信息:
Win32_LogicalDisk
Win32_LogicalDiskToPartition
Win32_DiskPartition
in any order.以任何顺序。 These tables will have all information.
这些表将包含所有信息。 It can be easily used using
System.Management
in c# .在 c# 中使用
System.Management
可以轻松使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.