■No33228に返信(ねここねこさんの記事)
> 「ディスク番号」と「ボリュームラベル」と「ドライブレター」を> 取得したいです。
API ではなく、WMI で取得してみました。
Win32_Volume を使うことで、ドライブレターのない論理ボリュームが得られました。
併せて、物理ドライブからパーティション情報を取得するコードも掲載しておきます。
Imports System.Management
Imports System.Runtime.CompilerServices
Module Module1
''' <summary>
''' ボリューム情報
''' </summary>
Public Function GetVolume() As XElement
Dim doc = <Volumes/>
Using mosVolume As New ManagementObjectSearcher("SELECT * FROM Win32_Volume"),
volumes = mosVolume.Get()
For Each volume In volumes.WithDisposal()
Dim nodeVolume = <Volume
Label=<%= volume!Label %>
DriveLetter=<%= volume!DriveLetter %>
DriveType=<%= CType(volume!DriveType, DriveType) %>
Name=<%= volume!Name %>
FileSystem=<%= volume!FileSystem %>
FreeSpace=<%= volume!FreeSpace %>
Capacity=<%= volume!Capacity %>
PNPDeviceID=<%= volume!PNPDeviceID %>
/>
doc.Add(nodeVolume)
Next
End Using
Return doc
End Function
''' <summary>
''' 物理ドライブとパーティションの情報
''' </summary>
Public Function GetDrives() As XElement
Dim doc = <Drives/>
Using mosDrive As New ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"),
drives = mosDrive.Get()
For Each drive In drives.WithDisposal()
Dim nodeDrive = <Drive
Index=<%= drive!Index %>
Partitions=<%= drive!Partitions %>
DeviceID=<%= drive!DeviceID %>
PNPDeviceID=<%= drive!PNPDeviceID %>
Model=<%= drive!Model %>
SerialNumber=<%= drive!SerialNumber %>
/>
doc.Add(nodeDrive)
Dim wql = New RelatedObjectQuery(
$"Win32_DiskDrive='{nodeDrive.@DeviceID}'",
"Win32_DiskPartition"
).QueryString
Using mosPartitions As New ManagementObjectSearcher(wql),
partitions = mosPartitions.Get()
For Each parition In partitions.WithDisposal()
Dim nodePatition = <Partition
DiskIndex=<%= parition!DiskIndex %>
Index=<%= parition!Index %>
DeviceID=<%= parition!DeviceID %>
PNPDeviceID=<%= parition!PNPDeviceID %>
StartingOffset=<%= $"{CType(parition!StartingOffset, UInt64?) / 1024:N0} KB" %>
Size=<%= $"{CType(parition!Size, UInt64?) / 1024:N0} KB" %>
Bootable=<%= parition!Bootable %>
PrimaryPartition=<%= parition!PrimaryPartition %>
Status=<%= parition!Status %>
/>
nodeDrive.Add(nodePatition)
Next
End Using
Next
End Using
Return doc
End Function
''' <summary>
''' 論理ディスクとパーティションの情報
''' </summary>
Public Function GetLogicalDisks() As XElement
Dim doc = <Disks/>
Using mosDisks As New ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk"),
disks = mosDisks.Get()
For Each disk In disks.WithDisposal()
Dim nodeDisk = <Disk
DeviceID=<%= disk!DeviceID %>
DriveType=<%= CType(disk!DriveType, DriveType) %>
PNPDeviceID=<%= disk!PNPDeviceID %>
ProviderName=<%= disk!ProviderName %>
VolumeName=<%= disk!VolumeName %>
VolumeSerialNumber=<%= disk!VolumeSerialNumber %>
/>
doc.Add(nodeDisk)
Dim wql = New RelatedObjectQuery(
$"Win32_LogicalDisk.DeviceID='{nodeDisk.@DeviceID}'",
"Win32_DiskPartition"
).QueryString
Using mosPartitions As New ManagementObjectSearcher(wql),
partitions = mosPartitions.Get()
For Each parition In partitions.WithDisposal()
Dim nodePatition = <Partition
DiskIndex=<%= parition!DiskIndex %>
Index=<%= parition!Index %>
DeviceID=<%= parition!DeviceID %>
PNPDeviceID=<%= parition!PNPDeviceID %>
/>
nodeDisk.Add(nodePatition)
Next
End Using
Next
End Using
Return doc
End Function
#Region "ヘルパーメソッド"
<Extension>
Private Iterator Function WithDisposal(list As ManagementObjectCollection
) As IEnumerable(Of ManagementBaseObject)
Using list
Using e = list.GetEnumerator()
While e.MoveNext()
Using mo = e.Current
Yield mo
End Using
End While
End Using
End Using
End Function
Private Enum DriveType
Unknown = 0
NoRootDirectory = 1
RemovableDisk = 2
LocalDisk = 3
NetworkDrive = 4
CompactDisc = 5
RamDisk = 6
End Enum
#End Region
End Module