2012-06-12 13 views
6

Sabit sürücü seri numarasını WMI'dan almak için bazı kodum var.WMI HDD Seri Numarası Transposed

SelectQuery selectQuery = new SelectQuery("Win32_PhysicalMedia"); 
ManagementObjectSearcher searcher = 
      new ManagementObjectSearcher(selectQuery); 
foreach (ManagementObject wmi_PM in searcher.Get()) 
{ 
     string str = wmi_PM["SerialNumber"]; 
} 

İlk başta çalıştığını ve doğru seri numarasını aldığını düşündüm. Yine de bir karşılaştırma ile kullanmaya çalıştıktan sonra, WMI raporlarının tam olarak doğru olmadığını bildirdim. WMI seri numarası, bir dizi boşluk ile doldurulur ve ayrıca karakterler aktarılır.

gerçek sürücü seri numarası etiket üzerinde yazılı ve bazı araçlar (muhtemelen DeviceIoControl kullanarak) "3RH8B1BG", WMI ancak "                                R38H1BGB" döndürür tarafından döndürülen .

Gerçek Seri No: 3RH8B1BG
WMI Seri No: R38H1BGB

SiSoftware Sandra gibi bazı araçlar, gerçi bu yastıklı ve aktarılmamıştır sayıda gerçek değil seri numarasını döndürür. Diğer her pozisyonu aktarırsanız, WMI değeri seri numarasıdır. Bu normal mi? sadece doğru değere dönüştürmek için kod yazmalı mıyım?

WMI'yi kullanmaktan kaçınmaya çalışıyorum, ancak ağda bir şeylerin nasıl yapılacağını bulmak artık WMI örneklerini geri getiriyor.

Farklı üreticilerin 2 farklı sabit diski için WMI değeri seri numarası her ikisi de tek bir disk değil, bu nedenle dönüştürülür.



Güncelleme: Şaşırtıcı Deviceıocontrol yanı bir aktarılmış seri numarasını döndürür   http://addressof.com/blog/archive/2004/02/14/392.aspx

Deviceıocontrol

        kullanarak bazı kod bulundu. diğer herhangi inanmak can DeviceIoControl ve WMI için standarttır

// function to decode the serial numbers of IDE hard drives 
    // using the IOCTL_STORAGE_QUERY_PROPERTY command 
char * flipAndCodeBytes (const char * str, 
      int pos, 
      int flip, 
      char * buf) 
{ 
    ... 
} 

tahmin: üstündeki CorySmith tarafından kodunda bir SwapChars

Private Shared Function SwapChars(ByVal chars() As Char) As String 
    For i As Integer = 0 To chars.Length - 2 Step 2 
    chars.Reverse(chars, i, 2) 
    Next 
    Return New String(chars).Trim 
End Function 

c işlev vardır ++ diye bahseder kod için kapağı vardır Karşı karşıya olduğum çözümler ya da örnekler buna sahip değildi.

+2

Wow, bir [PDP-11] üzerinde çalışıyorsunuz gibi görünüyor (http://en.wikipedia.org/wiki/Endianness#Middle-endian)! – sarnold

+3

Aslında PDP-11 ile aynı küçük endian bayt siparişi veren bir bilgisayarda çalışıyor. Yani ben ve Windows (Windows CE değil, Windows Phone değil) çalıştırıyorsanız, siz de öyle. Tek çalışma çözümü DeviceIoControl'ü çağırmak ve orijinal posteri bulduğunuzda baytları kendiniz çevirmektir. WMI'yi çağırırsanız, WMI'nin sizin için baytları döndürüp döndürmediğini bilmiyorsunuzdur. –

cevap

1

Gerçek HD-Serial'leri çözmek için çalışan bir Çözüm bulundu. Aşağıdaki bağlantı, yönetici hakları olmadan bile kodunu çözme kodunu içerir: Decoding Source

Ancak Serials'leri Vista'nın yukarısındaki Win32_PhysicalMedia WMI sınıfından alırsanız, her durumda çalışmayabilir. Sonra Win32_DiskDrive sınıfını kullanmanız gerekir (bu bağlantıya göre: Jiliang Ge's Answer from Tuesday, October 27, 2009 3:12 AM

Kodu ekledim (genellikle VB.NET'te kodladığımdan VB'de). Başka birinin kodunu çalmak istemedim. Infos ve hala kod içinde Orijinal Kodlayıcıya bazı linkler.Şimdi de Çıkarılabilir Sürücüler (aynı rutin) Serialnumbers çözme içerir.

Yardım edin.

''' <summary> 
''' Decode Manufacuter Disk Serialnumbers (also for PNP USB-Drives) 
''' </summary> 
''' <param name="InterfaceType">InterfaceType from Win32_DiskDrive WMI-Class</param> 
''' <param name="PNPDeviceID">PNPDeviceID from Win32_DiskDrive WMI-Class</param> 
''' <param name="strVolumeSerial">Raw Serialnumber to be decoded</param> 
''' <returns>Decoded Serialnumber</returns> 
''' <remarks></remarks> 
Public Shared Function Decode_HD_Serial(ByVal InterfaceType As String, 
          ByVal PNPDeviceID As String, 
          ByVal strVolumeSerial As String) As String 

    'HANDLE USB PNP Devices differently (Removable USB-Sticks) 
    'see: http://www.experts-exchange.com/Programming/Languages/.NET/Q_24574066.html 

    If InterfaceType = "USB" Then 
     Dim splitDeviceId As String() = PNPDeviceID.Split("\"c) 
     Dim arrayLen As Integer = splitDeviceId.Length - 1 
     Dim serialArray As String() = splitDeviceId(arrayLen).Split("&"c) 
     Return serialArray(0) 
    Else 
     'Link:https://social.msdn.microsoft.com/Forums/vstudio/en-US/8523d7b9-0dc8-4d87-be69-a482aec9ee5e/wmi-win32physicalmedia-smart-id-in-vista-and-7-permissions?forum=netfxbcl 
     'After digging into the [Win32_PhysicalMedia] WMI class, I find that from Vista/Longhorn the 
     'class has been taken over by another class called [Win32_DiskDrive]. Thus, if all machines 
     'in your environment are Vista and above use the second class otherwise use the first one. 
     'Based on my tests, the class gives the unique form of serial number when you run the 
     'app as an admin or as a non-admin. 
     ' ---> IF System.Environment.OSVersion.Version.Major > 5 then its Vista or higher. USE WIN32_DiskDrive 

     Dim strVolumeSerialDecoded As String = String.Empty 
     'Remove all space characters ("20"). 
     'Example : 20202020205635424544434553 will be 5635424544434553. 
     strVolumeSerial.Trim.Replace("20", "") 
     'IF THE USER IS ADMINISTRATOR, THE strVolumeSerial STRING WILL ALREADY CONTAIN THE SERIAL NUMBER IN ASCII, AND NO CONVERSION IS REQUIRED (Microsoft bug ?), 
     'BUT IF THE strVolumeSerial STRING IS A HEX STRING, CONVERT IT TO ASCII : 
     If System.Text.RegularExpressions.Regex.IsMatch(strVolumeSerial, "^[a-fA-F0-9]+$") Then 
      'Convert to ASCII. Example : 5635424544434553 will be converted to V5BEDCES. 
      strVolumeSerial = HexDecode(strVolumeSerial) 
      'Swap pairs of characters. 
      'Example : V5BEDCES will be converted to 5VEBCDSE. 
      Dim serialNumber2 As String = "" 
      For i As Integer = 0 To strVolumeSerial.Length - 1 Step 2 
       strVolumeSerialDecoded &= strVolumeSerial(i + 1) 
       strVolumeSerialDecoded &= strVolumeSerial(i) 
      Next 
      'Return the serialnumber as ASCII string. 
      Return strVolumeSerialDecoded.Trim 
     Else 'If strVolumeSerial is ASCII, remove spaces and return the serialnumber string. 
      Return strVolumeSerial.Trim 
     End If 
    End If 
End Function 

''' <summary>Decodes a HEX-string to an ASCII string.</summary> 
''' <param name="strHEX">The HEX-string to decode.</param> 
''' <returns>If succeeded, the decoded String, an empty String if failed.</returns> 
Private Shared Function HexDecode(ByVal strHEX As String) As String 
    Try 
     Dim sb As StringBuilder = New StringBuilder 
     For i As Integer = 0 To strHEX.Length - 1 Step 2 
      sb.Append(Convert.ToChar(Convert.ToUInt32(strHEX.Substring(i, 2), 16)).ToString) 
     Next 
     Return sb.ToString 
    Catch ex As Exception 
     Return "" 
    End Try 
End Function 
+1

Sadece bağlantı gönderen kimse iyi bir şey yapmaz. İlgili bilgileri cevabınıza eklemeniz gerekir. –

+0

Bunun için üzgünüz. Sadece başka birinden kod çalmak istemedim. – dragonfly