2009-07-17 16 views
3

こんにちは私はマシンの署名を生成するためにこのコードを使用しています。しかし、実行にはかなりの時間がかかります。なぜそんなに遅いのだろうか?より高速な方法をお勧めしますか?ボリュームのシリアル番号を取得する方法は簡単ですか?

Public Shared Function DriveSN(ByVal DriveLetter As String) As String 
    Dim disk As ManagementObject = New ManagementObject(String.Format("Win32_Logicaldisk='{0}'", DriveLetter)) 
    Dim VolumeName As String = disk.Properties("VolumeName").Value.ToString() 
    Dim SerialNumber As String = disk.Properties("VolumeSerialnumber").Value.ToString() 
    Return SerialNumber.Insert(4, "-") 
End Function 

Private Shared msig As String = Nothing 

Public Shared Function MachineSignature() As String 
    If msig Is Nothing Then 
     Dim list As New List(Of String) 
     For Each d As DriveInfo In DriveInfo.GetDrives() 
      If (d.IsReady) Then 
       list.Add(DriveSN(d.Name.Substring(0, 2))) 
      End If 
     Next 
     msig = String.Join(" & ", list.ToArray()) 
    End If 
    Return msig 
End Function 

答えて

2

これは厄介である。

次のコードは、Cドライブのドライブのシリアル番号を取得します。パフォーマンスの問題は、単に「固定」ドライブを確認することで解決できます。

Public Shared Function MachineSignature() As String 
    If msig Is Nothing Then 
     Dim list As New List(Of String) 
     For Each d As DriveInfo In DriveInfo.GetDrives() 
      If (d.DriveType = DriveType.Fixed) AndAlso (d.IsReady) Then ' <-- check for DriveType' 
       list.Add(DriveSN(d.Name.Substring(0, 2))) 
      End If 
     Next 
     msig = String.Join(" & ", list.ToArray()) 
    End If 
    Return msig 
End Function 
+0

あなたはそれがどのように問題であることを発見しましたか? –

+0

デバッガを介してステップ実行します。他の種類のドライブ(フロッピー、CD-ROM)をチェックする "IsReady"は目立つポーズをとらえることができます。 ここには何も秘密がありません。 – Sake

0

これにもWin32 API呼び出しがありますが、それでも管理されたコードなのでWMIはより良い方法だと思います。

Win32 API関数:GetVolumeInformation

私はシリアル番号を抽出するために(それはC#のだが、vb.netで行うには問題ないはずです)eggheadcafeに次の関数を見つけました:

あり
public string GetVolumeSerial(string strDriveLetter) 
{ 
uint serNum = 0; 
uint maxCompLen = 0; 
StringBuilder VolLabel = new StringBuilder(256); // Label 
UInt32 VolFlags = new UInt32(); 
StringBuilder FSName = new StringBuilder(256); // File System Name 
strDriveLetter+=":\\"; // fix up the passed-in drive letter for the API call 
long Ret = GetVolumeInformation(strDriveLetter, VolLabel, (UInt32)VolLabel.Capacity, ref serNum, ref maxCompLen, ref VolFlags, FSName, (UInt32)FSName.Capacity); 

return Convert.ToString(serNum); 
} 
+1

GetVolumeInformationの宣言もこのコードが機能するように含める必要があります。 – RobS

3

System.Management名前空間を使用するegghead cafeの.Net方法です。

まず、vb.netのSystem.Management dllへの参照を追加する必要があります。プロジェクト - >参照の追加メニュー項目を使用します。

Dim drive As String = "C" 
Dim disk As System.Management.ManagementObject = _ 
     New System.Management.ManagementObject _ 
     ("win32_logicaldisk.deviceid=""" + drive + ":""") 
disk.Get() 
Dim SerialNumber as String = disk("VolumeSerialNumber").ToString() 
関連する問題