2009-07-17 8 views
3

Salut J'utilise ce code pour générer la signature de la machine. Mais il faut du temps pour l'exécuter. Je me demande pourquoi c'est si lent? Une méthode plus rapide est-elle recommandée?Une méthode plus rapide pour obtenir le numéro de série du volume?

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 

Répondre

2

C'est embarrassant. Le problème de performance peut être résolu en vérifiant simplement le lecteur "fixe".

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

Comment avez-vous découvert que c'était le problème? –

+0

Passage par le débogueur. Le "IsReady" vérification pour d'autres types de lecteurs (disquette, CD-ROM) peut prendre une pause notable. Rien de mystérieux ici. – Sake

0

Il y a un appel API Win32 à cela aussi, mais je pense que WMI est le meilleur moyen car il est encore du code managé.

fonction Win32 API: GetVolumeInformation

Je trouve la fonction suivante sur eggheadcafe (il est C#, mais devrait être pas problème à faire dans vb.net) pour extraire le numéro de série:

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

Vous devez également inclure les déclarations de GetVolumeInformation pour que ce code fonctionne. – RobS

3

Il est également un chemin .Net à partir de egghead cafe en utilisant l'espace de noms System.Management.

Tout d'abord, vous devez ajouter la référence à la DLL System.Management dans vb.net. Utilisation de l'élément de menu Projet-> Ajouter une référence.

ensuite le code suivant obtient le numéro de série de lecteur pour le lecteur C:

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()