我正在编写一个程序,需要解析来自windows命令“diskpart”的输出结果,特别是在解析磁盘和放大器时。用VB.NET输出的卷信息(使用“list disk”和“list volume”)
我设法使用dos命令diskpart /s myscript.scp > result.txt
现在在VB.NET中,我需要解析'result.txt'以检索'卷号','驱动器号','驱动器标签','类型','大小'和& 'size_unit'进入一个数组进行进一步处理。
检索所有这些数据的最佳方法是什么?我尝试在MSDN上阅读有关.NET正则表达式(Regex)的内容,它让我感到困惑,并且不确定在我的情况下应该使用什么模式。
希望有人可以帮助我,欢迎任何其他解析方法。
* 2013年6月26日更新 - 由于某些技术原因,我需要坚持使用“diskpart”并依赖它的输出结果进行解析。
输入示例(result.txt)
Microsoft DiskPart version 6.1.7601
Copyright (C) 1999-2008 Microsoft Corporation.
On computer: PC1
Disk ### Status Size Free Dyn Gpt
-------- ------------- ------- ------- --- ---
Disk 0 Online 1863 GB 1024 KB
Disk 1 No Media 0 B 0 B
Disk 2 Online 7424 MB 0 B
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 E DVD-ROM 0 B No Media
Volume 1 C SYSTEM NTFS Partition 100 GB Healthy System
Volume 2 D TEMP NTFS Partition 1606 GB Healthy Pagefile
Volume 3 G Removable 0 B No Media
Volume 4 F GSFKEY NTFS Removable 7423 MB Healthy
输出
disk(0)
.disknum=0
.size=1863
.size_unit="GB
disk(0)
.disknum=1
.size=0
.size_unit="B"
..and so on
vol(0)
.volnum=0
.letter="E"
.label=""
.type="DVD-ROM"
.size=0
.size_unit="B"
vol(1)
.volnum=1
.letter="C"
.label="SYSTEM"
.type="Partition"
.size=100
.size_unit="GB"
..and so on
答案 0 :(得分:5)
您可以从System.IO.DriveInfo获取此信息吗?
public DriveInfo(string driveName);
public long AvailableFreeSpace
public string DriveFormat
public DriveType DriveType
public DirectoryInfo RootDirectory
public long TotalFreeSpace
public long TotalSize
public string VolumeLabel
public static DriveInfo[] GetDrives();
答案 1 :(得分:3)
我首先会创建一个代表您数据的类:
Public Class DiskPartResult
Public Property Volume As String
Public Property Number As Int32
Public Property Ltr As String
Public Property Label As String
Public Property Fs As String
Public Property Type As String
Public Property SizeUnit As String
Public Property Status As String
Public Property Info As String
End Class
现在,您可以使用File.ReadLines
跟随Linq查询来获取相关数据行:
Dim diskPartFileLines = File.ReadLines("Results.txt")
Dim dataLines = From line In diskPartFileLines
Skip While Not line.TrimStart().StartsWith("----------") Skip (1)
Take While line.TrimStart().StartsWith("Volume")
现在您可以填写List(Of DiskPartResult)
:
Dim alldata = New List(Of DiskPartResult)
For Each line As String In dataLines
Dim columns = line.Trim().Split({vbTab}, StringSplitOptions.RemoveEmptyEntries)
If columns.Length <> 9 Then Continue For
Dim data = New DiskPartResult()
data.Volume = columns(0)
data.Number = Int32.Parse(columns(1))
data.Ltr = columns(2)
data.Label = columns(3)
data.Fs = columns(4)
data.Type = columns(5)
Dim sizeInfo = columns(6)
data.Size = Double.Parse(sizeInfo.Split()(0).Trim())
data.SizeUnit = sizeInfo.Split()(1).Trim()
data.Status = columns(7)
data.Info = columns(8)
alldata.Add(data)
Next
如果您想输出它:
For Each dpr As DiskPartResult In alldata
Console.WriteLine("vol({0})", dpr.Volume)
Console.WriteLine(" .volnum={0}", dpr.Number)
Console.WriteLine(" .letter={0}", dpr.Ltr)
Console.WriteLine(" .label={0}", dpr.Label)
Console.WriteLine(" .type={0}", dpr.Type)
Console.WriteLine(" .size={0}", dpr.Size)
' and so on ... '
Next
显然,分隔符不是制表符,而是所有空格。任何 想法?
然后你可以“分割”你可以从标题行获得的双白空间索引,因为数据行使用相同的索引。
我创建了以下扩展方法来获取文本中给定分隔符字符串的所有索引:
<System.Runtime.CompilerServices.Extension()> _
Public Function AllIndexOf(text As String, str As String, comparisonType As StringComparison) As IList(Of Integer)
Dim allIndeces As IList(Of Integer) = New List(Of Integer)()
Dim index As Integer = text.IndexOf(str, comparisonType)
While index <> -1
allIndeces.Add(index)
index = text.IndexOf(str, index + str.Length, comparisonType)
End While
Return allIndeces
End Function
现在您可以使用此代码查询所需的信息:
Dim diskPartFileLines = File.ReadAllLines("Results.txt")
Dim headerLine = (From line In diskPartFileLines
Skip While Not line.TrimStart().StartsWith("----------")).First().Trim()
Dim colStartIndices As IList(Of Int32) = headerLine.AllIndexOf(" ", StringComparison.OrdinalIgnoreCase)
Dim dataLines = From line In diskPartFileLines
Skip While Not line.TrimStart().StartsWith("----------") Skip 1
Take While line.TrimStart().StartsWith("Volume")
Select line.Trim()
Dim alldata = New List(Of DiskPartResult)
然后枚举查询,初始化DiskPartResults
并将它们添加到列表中:
For Each line In dataLines
Dim data = New DiskPartResult()
Dim lastIndex = 0
For i As Int32 = 0 To colStartIndices.Count - 1
Dim index = colStartIndices(i)
Select Case i
Case 0
data.Volume = line.Substring(lastIndex, index - lastIndex).Trim()
Case 1
data.Number = Int32.Parse(line.Substring(lastIndex, index - lastIndex).Trim())
Case 2
data.Ltr = line.Substring(lastIndex, index - lastIndex).Trim()
Case 3
data.Label = line.Substring(lastIndex, index - lastIndex).Trim()
Case 4
data.Fs = line.Substring(lastIndex, index - lastIndex).Trim()
Case 5
data.Type = line.Substring(lastIndex, index - lastIndex).Trim()
Case 6
Dim sizeInfo = line.Substring(lastIndex, index - lastIndex).Trim()
data.Size = Double.Parse(sizeInfo.Split()(0).Trim())
data.SizeUnit = sizeInfo.Split()(1).Trim()
Case 7
data.Status = line.Substring(lastIndex, index - lastIndex).Trim()
Case 8
data.Info = line.Substring(lastIndex, index - lastIndex).Trim()
End Select
lastIndex = index
Next
Next
请注意,For Each
未经过测试,但它可以为您提供这个想法。
答案 2 :(得分:1)
'获取磁盘编号 昏暗的查询 昏暗的objWMI 昏暗的磁盘驱动器 昏暗的diskDrive 昏暗的分区 昏暗的分区'将包含驱动器&amp;分区号码 昏暗的逻辑风险 Dim logicalDisk'将包含驱动器号 Dim stroutput As New StringBuilder
objWMI = GetObject("winmgmts:\\.\root\cimv2")
diskDrives = objWMI.ExecQuery("SELECT * FROM Win32_DiskDrive") ' First get out the physical drives
For Each diskDrive In diskDrives
query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + diskDrive.DeviceID + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition" ' link the physical drives to the partitions
partitions = objWMI.ExecQuery(query)
For Each partition In partitions
query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition.DeviceID + "'} WHERE AssocClass = Win32_LogicalDiskToPartition" ' link the partitions to the logical disks
logicalDisks = objWMI.ExecQuery(query)
For Each logicalDisk In logicalDisks
stroutput.Append(logicalDisk.DeviceID & " - " & partition.Caption)
' Wscript.Echo(logicalDisk.DeviceID & " - " & partition.Caption)
Next
Next
Next
MessageBox.Show(stroutput.ToString)