在VB.NET中查找逻辑驱动器ID [英] Find logical drive ID in VB.NET

查看:78
本文介绍了在VB.NET中查找逻辑驱动器ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

晚上好,



有谁知道如何获取逻辑驱动器的逻辑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. For Win32_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 use Win32_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 method Environment.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 are System and Windows, so you can find a volume letter where the system is, and compare it with the results you got using the WMI object Win32_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 this Sub 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆