【问题标题】:Any faster method to get Volume Serial number?任何更快的方法来获取卷序列号?
【发布时间】:2009-07-17 10:56:49
【问题描述】:

您好,我正在使用此代码生成机器签名。但是执行起来需要相当长的时间。想知道为什么这么慢?有什么更快的方法推荐吗?

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

【问题讨论】:

    标签: .net vb.net wmi


    【解决方案1】:

    egghead cafe 也有一个使用 System.Management 命名空间的 .Net 方式。

    首先,您需要在 vb.net 中添加对 System.Management dll 的引用。使用 Project->Add Reference 菜单项。

    然后下面的代码获取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()
    

    【讨论】:

      【解决方案2】:

      这很尴尬。只需检查“固定”驱动器即可解决性能问题。

      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
      

      【讨论】:

      • 您是如何发现问题所在的?
      • 单步调试器。检查其他类型的驱动器(软盘、cd-rom)的“IsReady”可能需要明显的暂停。这里没有什么神秘之处。
      【解决方案3】:

      对此也有一个 Win32 API 调用,但我认为 WMI 是更好的方法,因为它仍然是托管代码。

      Win32 API 函数:GetVolumeInformation

      我在eggheadcafe(它是C#,但在vb.net中应该没问题)找到了以下函数来提取序列号:

      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);
      }
      

      【讨论】:

      • 您还需要包含 GetVolumeInformation 的声明,此代码才能正常工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      相关资源
      最近更新 更多