在VB.NET中查找逻辑驱动器ID [英] Find logical drive ID in VB.NET
问题描述
晚上好,
有谁知道如何获取逻辑驱动器的逻辑ID(非序列号)?我需要找到驱动器的位置号。下面是一个diskpart打印输出,我希望找到volume ###列下的数字。我搜索并搜索过,无法找到如何找到它。我发现的一切都是关于查找序列号,驱动器类型,驱动器号等。现在,我一直在尝试使用字符串操作,而且它一直都不准确。变量太多了。
让我解释并提供更多细节。我想创建一个程序,使用WinPe 4.0和Usb闪存驱动器部署Windows 7映像。我试图使用Diskpart删除现有分区,但不删除USB驱动器分区。下面的diskpart打印输出是我用来尝试获取卷号以执行Sel Vol和磁盘编号,以便删除分区。但我认为还有另一种方法可以做到而不是将打印输出到文本框并使用字符串操作来查找它。
代码:
卷### Ltr标签Fs类型尺寸状态信息
---------- --- ----------- ----- ---------- ------- --- ------
第0卷D DVD-ROM 0 B无媒体
第1卷E DVD-ROM 0 B无媒体
< br $>
所以我遇到了WMI类并认为我可以使用类似下面的函数从那里获得它来返回值并创建一个变量。但我无法弄明白。
私人 功能 GetDriveInfo( ByVal sVolumeName As 字符串)作为 字符串
Dim objMOC As Management.ManagementObjectCollection
Dim objMOS 作为 Management.ManagementObjectSearcher = 新 Management.ManagementObjectSearcher( SELECT * FROM Win32_Volume)
Dim objMO As Management.ManagementObject
objMOC = objMOS。获取()
对于 每个 objMO < span class =code-keyword>在 objMOC
Dim objDriveLetter As 字符串 = objMO( DeviceID)
Dim objVolumeLabel = objMO( Name )
MsgBox(objDriveLetter& vbCrLf& objVolumeLabel)
如果 UCase(objVolumeLabel)= UCase(sVolumeName)那么
< span class =code-keyword>返回 objDriveLetter.ToString
其他:返回 没什么
结束 如果
' Dim objOUT As String = String.Format({0} - {1 },objVolumeName,objID)
' MsgBox(objOUT)
下一步
返回 没什么
结束 功能
以下是我目前用来查找和删除分区的内容,但效率不高。
私有 Sub DelExistingPartitions()
如果 Me .InvokeRequired 那么
我 .Invoke(新 DelegateDelExistingPartitions( AddressOf DelExistingPartitions))
其他
Dim tmp 作为 字符串
Dim myprocess 作为 新处理
Dim StartInfo As 新 System.Diagnostics.ProcessStartInfo
StartInfo.FileName = sSystem32& \ diskpart.exe
StartInfo.CreateNoWindow = True
StartInfo.RedirectStandardInput = True
StartInfo.RedirectStandardOutput = True
StartInfo.UseShellExecute = False
myprocess.StartInfo = StartInfo
myprocess.Start()
< span class =code-keyword> Dim SR As System.IO.StreamReader = myprocess.StandardOutput
Dim SW As System.IO.StreamWriter = myprocess.StandardInput
SW.WriteLine( list vol)
SW.WriteLine( 退出)
myprocess。 HasExited = False
tmp = SR.ReadLine& vbCrLf
如果 tmp<> 然后
< span class =code-keyword> Me .txtResults.AppendText(tmp)
结束 如果
循环
对于 每个行在 txtResults.Lines
如果 line = 然后
ElseIf line.Contains( Microsoft DiskPart version)然后
ElseIf line.Contains( 版权所有(C))然后
ElseIf line.Contains( 在计算机上:) 然后
ElseIf line.Contains( DISKPART>)然后
ElseIf line.Contains( Volume ###)然后
ElseIf line.Contains( ----------)然后
ElseIf line.Contains(UCase( DVD-ROM))然后
ElseIf line.Contains(UCase( FAT32))然后
ElseIf line.Contains(UCase( IMAGES))然后
ElseIf line.Contains(UCase( X:\ Diskpart))然后
否则
Dim sIndexOfId = line.IndexOf( e)
Dim sVolumeID 作为 字符串 = line.Substring(sIndexOfId + 2 , 1 )
sExistingPartition = sVolumeID
' MsgBox( sExistingPartition)
SW.WriteLine( select vol& sExistingPartition)
SW.WriteLine( 删除vol覆盖)
' SW.WriteLine(exit)
End 如果
下一步
SW.Close()
SR.Close()
结束 如果
结束 Sub
如果您需要更进一步,请告诉我。
你可以使用WMI来做到这一点: http://en.wikipedia.org/wiki/Windows_Management_Instrumentation [ ^ ]。
首先,你需要找出去哪里文档。对于Win32_LogicalDisk
,请参阅:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394173%28v=vs.85%29.aspx [ ^ ]。
如你所见,没有逻辑ID这样的东西。此外,当我运行代码时,我看不到您可能想要的* volume *ID(请参阅下面的代码)。不,错误的方式。进一步搜索显示您可以使用Win32_Volume
,而不是逻辑ID:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394515%28v=vs。 85%29.aspx [ ^ ]。
通过.NET WMI(管理)使用此信息更加棘手。您没有所有属性和方法的完全映射API。相反,所有内容都应该由查询使用类型名称和属性(在您的情况下)找到,您可以从上面引用的文档中找到这些名称。此外,还有一种反射型API,允许您列出所有属性和方法。
看看我的代码示例:
使用系统;
使用 System.Management;
// ...
ManagementObjectSearcher searcher = new ManagementObjectSearcher( SELECT * FROM Win32_Volume< /跨度>);
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject item in collection)
System.Console.WriteLine(
名称:{0},设备ID:{1},
item [ 名称],item [ DeviceID]);
请参阅:
http://msdn.microsoft.com/en-us/library/system .management.aspx [ ^ ],
http://msdn.microsoft .COM / EN-US /库/ system.management.managementobjectcollection.aspx [ ^ ] ,
http://msdn.microsoft.com/en -us / library / system.management.managementobject.aspx [ ^ ]。
如果您需要了解其他内容,请了解所有具体的WMI查询,课程及其内容成员。 CodeProject的这篇文章为搜索它们提供了全面的帮助:
用于Windows Management Instrumentation的CIMTool - 第3部分 [ ^ ]。
这是一个非常强大的互动工具。
学习WMI和快速原型查询的另一种方法是Microsoft PowerShell:
http:// en .wikipedia.org / wiki / Powershell [ ^ ] ,
http://www.microsoft.com/powershell [ ^ ]。
-SA
查找系统卷的一种方法是:
首先,使用方法Environment.GetFolderPath(Environment.SpecialFolder) )
:
http://msdn.microsoft .com / zh-CN / library / 14tx8hby.aspx [ ^ ],
http ://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx [ ^ ]。
如你所见,两个枚举成员是系统
和Windows
,因此您可以找到系统所在的卷号,并将其与结果进行比较你使用WMI对象Win32_Volume
,如Sol所示这样,您可以找到相应的音量及其属性。
但是,它不能保证启动音量相同。 Boot是一个非常复杂的过程。它从BIOS或UEFI(BIOS的后继者)中指定的物理驱动器的引导顺序开始,并且物理驱动器由主引导记录进一步定义,然后它可以是具有不同方式继续进行的多引导系统。操作系统加载等等。
我找到了有关如何从WMI中找到启动信息的信息: http://stackoverflow.com/questions/9337354/access-the-windows-7-boot-configuration-data -using-c-sharp [ ^ ]。
我还没试过,所以请试试。我会对您的反馈感兴趣。
-SA
首先我宣布了以下变量:
公共 sTotalVolumes 正如 整数 = 0
公共 iRemovable 作为 整数 = 0
公共 sLocalDisks 作为 整数 = 0
公开 iDvd As 整数 = 0
公开 sLastDvdVolumeNumber 作为 整数 = 0
公共 sFirstLocalDiskVolumeNumber 作为 整数 = 0
然后我得到了机器卷的信息:
私有 Sub GetVolumeInfo()
Dim objMOC As Management.ManagementObjectCollection
Dim objMOS As Management.ManagementObjectSearcher = 新 Management.ManagementObjectSearcher( SELECT * FROM Win32_Volume)
Dim objMO As Management.ManagementObject
objMOC = objMOS。获取()
sTotalVolumes = CInt (objMOC.Count)
对于 每个 objMO < span class =code-keyword>在 objMOC
Dim sDriveName As 字符串 = objMO( 名称)
Dim sDriveType 作为 整数 = CInt (objMO( DriveType ))
' MsgBox(sDriveName& vbNewLine& sDriveType)
如果 sDriveType = 5 然后
iDvd = iDvd + 1
ElseIf sDriveType = 2 然后
iRemovable = iRemovable + 1
ElseIf sDriveType = 3 然后
sLocalDisks = sLocalDisks + 1
结束 如果
下一步
结束 Sub
然后我上次使用这个Sub
要删除现有分区:
私有 Sub DelExistingPartitions()
如果 我.InvokeRequired 然后
我 .Invoke(新 DelegateDelExistingPartitions( AddressOf DelExistingPartitions))
否则
GetVolumeInfo()
Dim tmp As String
Dim p As New 处理
p.StartInfo.FileName = sSystem32& \ diskpart.exe
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardInput = True
p.StartInfo.CreateNoWindow = True
p.Start()
Dim SR As System.IO.StreamReader = p.StandardOutput
Dim SW As System.IO.StreamWriter = p.StandardInput
' 在此处插入命令
' SW.WriteLine(list vol)
sFirstLocalDisk VolumeNumber = iDvd - 1
对于 i 作为 整数 = 1 至 sLocalDisks - 1 步骤 1
sFirstLocalDiskVolumeNumber = sFirstLocalDiskVolumeNumber + 1
' MsgBox(sFirstLocalDiskVolumeNumber)
SW.WriteLine( sel vol& sFirstLocalDiskVolumeNumber)
SW.WriteLine( 删除vol覆盖)
Next
SW.WriteLine( exit)
执行 p.HasExited = False
tmp = SR.ReadLine()
如果 tmp<> 然后
< span class =code-keyword> Me .txtResults.AppendText(tmp& vbCrLf)
End 如果
循环
SR.Close()
SW.Close()
p .Dispose()
结束 如果
结束 Sub
Good Evening,
Does anyone know how to get the logical ID(Not Serial Number) of a logical drive? I need to find location number of the drive. Below is a diskpart printout and I am looking to find the number under "volume ###" column. I have searched and searched, and can not find out how to find it. Everything I find is about finding serial number, drive type, drive letter, and so on. Right now, I have been trying to do with string manipulation, and its not exact all the time. There are too many variables.
Let me explain and give a little more detail. I want to create a program that will deploy a Windows 7 image using WinPe 4.0 and Usb Flash Drives. I am trying to use Diskpart to delete existing partitions, but not the USB drive partitions. The diskpart printout below is what I was using to try and get the volume number to do a "Sel Vol" and the disk number, in order to get the partition to delete. But I thought there would be another way to do it rather than output the printout to a textbox and use string manipulations to look for it.
Code:
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 D DVD-ROM 0 B No Media
Volume 1 E DVD-ROM 0 B No Media
So I came across the WMI Classes and thought I might be able to get it from there using a function similiar to below to return the value and create a variable. But I have not been able to figure it out.
Private Function GetDriveInfo(ByVal sVolumeName As String) As String
Dim objMOC As Management.ManagementObjectCollection
Dim objMOS As Management.ManagementObjectSearcher = New Management.ManagementObjectSearcher("SELECT * FROM Win32_Volume")
Dim objMO As Management.ManagementObject
objMOC = objMOS.Get()
For Each objMO In objMOC
Dim objDriveLetter As String = objMO("DeviceID")
Dim objVolumeLabel = objMO("Name")
MsgBox(objDriveLetter & vbCrLf & objVolumeLabel)
If UCase(objVolumeLabel) = UCase(sVolumeName) Then
Return objDriveLetter.ToString
Else : Return Nothing
End If
'Dim objOUT As String = String.Format("{0} - {1}", objVolumeName, objID)
' MsgBox(objOUT)
Next
Return Nothing
End Function
Here is what I am currently using to find and delete partitions, but it is not efficient.
Private Sub DelExistingPartitions()
If Me.InvokeRequired Then
Me.Invoke(New DelegateDelExistingPartitions(AddressOf DelExistingPartitions))
Else
Dim tmp As String
Dim myprocess As New Process
Dim StartInfo As New System.Diagnostics.ProcessStartInfo
StartInfo.FileName = sSystem32 & "\diskpart.exe"
StartInfo.CreateNoWindow = True
StartInfo.RedirectStandardInput = True
StartInfo.RedirectStandardOutput = True
StartInfo.UseShellExecute = False
myprocess.StartInfo = StartInfo
myprocess.Start()
Dim SR As System.IO.StreamReader = myprocess.StandardOutput
Dim SW As System.IO.StreamWriter = myprocess.StandardInput
SW.WriteLine("list vol")
SW.WriteLine("exit")
Do While myprocess.HasExited = False
tmp = SR.ReadLine & vbCrLf
If tmp <> "" Then
Me.txtResults.AppendText(tmp)
End If
Loop
For Each line In txtResults.Lines
If line = "" Then
ElseIf line.Contains("Microsoft DiskPart version") Then
ElseIf line.Contains("Copyright (C)") Then
ElseIf line.Contains("On computer:") Then
ElseIf line.Contains("DISKPART>") Then
ElseIf line.Contains("Volume ###") Then
ElseIf line.Contains("----------") Then
ElseIf line.Contains(UCase("DVD-ROM")) Then
ElseIf line.Contains(UCase("FAT32")) Then
ElseIf line.Contains(UCase("IMAGES")) Then
ElseIf line.Contains(UCase("X:\Diskpart")) Then
Else
Dim sIndexOfId = line.IndexOf("e")
Dim sVolumeID As String = line.Substring(sIndexOfId + 2, 1)
sExistingPartition = sVolumeID
'MsgBox(sExistingPartition)
SW.WriteLine("select vol " & sExistingPartition)
SW.WriteLine("Delete vol override")
' SW.WriteLine("exit")
End If
Next
SW.Close()
SR.Close()
End If
End Sub
If you need anything further, please let me know.
You can do it using WMI: http://en.wikipedia.org/wiki/Windows_Management_Instrumentation[^].
First of all, you need to figure out where to get the documentation. ForWin32_LogicalDisk
, please see:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394173%28v=vs.85%29.aspx[^].
As you can see, there is no such thing as "logical ID". Besides, when I run the code, I cannot see "*volume*" ID which you probably want (please see the code below). No, wrong way. Further search shows that you can useWin32_Volume
, not "logical ID":
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394515%28v=vs.85%29.aspx[^].
Using this information via .NET WMI (Management) is more tricky. You don't have the fully-mapped API for all properties and methods. Instead, everything should be found by the queries using type names and property (in your case) names which you can find from the documentation referenced above. Besides, there is a reflective type of API which allows your to list all the properties and methods.
Take a look at my code sample:
using System; using System.Management; //... ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Volume"); ManagementObjectCollection collection = searcher.Get(); foreach (ManagementObject item in collection) System.Console.WriteLine( "Name: {0}, Device ID: {1}", item["Name"], item["DeviceID"]);
Please see:
http://msdn.microsoft.com/en-us/library/system.management.aspx[^],
http://msdn.microsoft.com/en-us/library/system.management.managementobjectcollection.aspx[^],
http://msdn.microsoft.com/en-us/library/system.management.managementobject.aspx[^].
If you need to find out something else, learn all the concrete WMI queries, classes and their members. This CodeProject article provides comprehensive help in search for them:
CIMTool for Windows Management Instrumentation - Part 3[^].
This is a really powerful interactive tool.
Another way to learn WMI and quickly prototype queries is Microsoft PowerShell:
http://en.wikipedia.org/wiki/Powershell[^],
http://www.microsoft.com/powershell[^].
—SA
One way to find the system volume is this:
First, use the methodEnvironment.GetFolderPath(Environment.SpecialFolder)
:
http://msdn.microsoft.com/en-us/library/14tx8hby.aspx[^],
http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx[^].
As you can see, two of the enumeration members areSystem
andWindows
, so you can find a volume letter where the system is, and compare it with the results you got using the WMI objectWin32_Volume
, as shown in Solution 1. This way, you can find the corresponding volume and its properties.
However, it does not guarantee that the boot volume is the same. Boot is a pretty complex process. It starts from the boot order of physical drives specified in BIOS or UEFI (successor of BIOS), and on a physical drive is further defined by Master Boot Record, and then it can be a multu-boot system with different ways to proceed with the OS loading, and so on.
I found the information on how to find out boot information from WMI: http://stackoverflow.com/questions/9337354/access-the-windows-7-boot-configuration-data-using-c-sharp[^].
I did not try it yet, so please try. I would be interested in your feedback.
—SA
First I declared the follwing variables:
Public sTotalVolumes As Integer = 0 Public iRemovable As Integer = 0 Public sLocalDisks As Integer = 0 Public iDvd As Integer = 0 Public sLastDvdVolumeNumber As Integer = 0 Public sFirstLocalDiskVolumeNumber As Integer = 0
Then I got the machine's volumes' information:
Private Sub GetVolumeInfo() Dim objMOC As Management.ManagementObjectCollection Dim objMOS As Management.ManagementObjectSearcher = New Management.ManagementObjectSearcher("SELECT * FROM Win32_Volume") Dim objMO As Management.ManagementObject objMOC = objMOS.Get() sTotalVolumes = CInt(objMOC.Count) For Each objMO In objMOC Dim sDriveName As String = objMO("Name") Dim sDriveType As Integer = CInt(objMO("DriveType")) ' MsgBox(sDriveName & vbNewLine & sDriveType) If sDriveType = 5 Then iDvd = iDvd + 1 ElseIf sDriveType = 2 Then iRemovable = iRemovable + 1 ElseIf sDriveType = 3 Then sLocalDisks = sLocalDisks + 1 End If Next End Sub
Then last I used thisSub
to delete the existing partitions:
Private Sub DelExistingPartitions() If Me.InvokeRequired Then Me.Invoke(New DelegateDelExistingPartitions(AddressOf DelExistingPartitions)) Else GetVolumeInfo() Dim tmp As String Dim p As New Process p.StartInfo.FileName = sSystem32 & "\diskpart.exe" p.StartInfo.UseShellExecute = False p.StartInfo.RedirectStandardOutput = True p.StartInfo.RedirectStandardInput = True p.StartInfo.CreateNoWindow = True p.Start() Dim SR As System.IO.StreamReader = p.StandardOutput Dim SW As System.IO.StreamWriter = p.StandardInput 'Insert Commands Here 'SW.WriteLine("list vol") sFirstLocalDiskVolumeNumber = iDvd - 1 For i As Integer = 1 To sLocalDisks - 1 Step 1 sFirstLocalDiskVolumeNumber = sFirstLocalDiskVolumeNumber + 1 'MsgBox(sFirstLocalDiskVolumeNumber) SW.WriteLine("sel vol " & sFirstLocalDiskVolumeNumber) SW.WriteLine("Delete vol override") Next SW.WriteLine("exit") Do While p.HasExited = False tmp = SR.ReadLine() If tmp <> "" Then Me.txtResults.AppendText(tmp & vbCrLf) End If Loop SR.Close() SW.Close() p.Dispose() End If End Sub
这篇关于在VB.NET中查找逻辑驱动器ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!