tags:

views:

1030

answers:

3

Hi I'm using this code to generate machine signature. But it's take noticeable time to execute. Wonder why it's that slow ? Any faster method recommended ?

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
A: 

There is a Win32 API call to this also, but i think WMI is the better way since it's still managed code.

Win32 API function: GetVolumeInformation

I found the following function on eggheadcafe (it's C#, but should be not problem to do in vb.net) to extract the Serial number:

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);
}
Alexander
You need to include the declarations for GetVolumeInformation as well for this code to work.
RobS
A: 

There is a .Net way also from egghead cafe using the System.Management namespace.

Firstly, you need to add the reference to the System.Management dll in vb.net. Using the Project->Add Reference menu item.

Then the following code gets the drive serial number for the C drive:

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()
RobS
+1  A: 

This is embarrassing. The performance problem can be solved by simply check for "fixed" drive.

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
Sake
How did you discover that was the problem?
TURBOxSPOOL
Stepping through debugger. The "IsReady" checking for other kind of drives (floppy, cd-rom) can take noticeable pause.Nothing mystery here.
Sake