用C#獲取硬盤序列號,CPU序列號,網卡MAC地址

這個問題首先得考慮的就是你的硬盤是不是SCSI硬盤
如果是,那麼根本不存在"物理序列號",只可能取得卷標的序列號

如果是卷標序列號,要注意的是每次格式化硬盤的時候這個序列號都會變
代碼可以參考:
http://www.csdn.net/Develop/Read_Article.asp?Id=25196

如果是物理序列號:
String HDid;
ManagementClass cimobject = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection moc = cimobject.GetInstances();
foreach(ManagementObject mo in moc)
{
HDid = (string)mo.Properties["Model"].Value;
MessageBox.Show(HDid );
}

如果是取得邏輯序列號(Format產生的那個),用WMI就可以,在引用中,添加system.mangement以後。
using System.Management;
.....
ManagementObject m_objDisk = new ManagementObject( "win32_logicaldisk.deviceid=\"c\"");
string strSN = (string)m_objDisk.GetPropertyValue( "VolumeSerialNumber ");

如果要取得物理分區號,看這個帖子:
關於硬盤序列號,高手請留步啊. (之一)
http://expert.csdn.net/Expert/TopicView3.asp?id=1143107

683E0480(第一種方案取得)

ST3160815AS (第二個方案取得的)

5239355835565745202020202020202020202020(第三種方案取得)

private string[] GetMoc()
{
string[] str = new string[3];
ManagementClass mcCpu = new ManagementClass("win32_Processor");
ManagementObjectCollection mocCpu = mcCpu.GetInstances();
foreach(ManagementObject m in mocCpu)
{
str[0] = m["ProcessorId"].ToString();
}

        ManagementClass mcHD = new ManagementClass("win32_logicaldisk");
        ManagementObjectCollection mocHD = mcHD.GetInstances();
        foreach(ManagementObject m in mocHD)
        {
            if(m["DeviceID"].ToString() == "C:")
            {
                str[1] = m["VolumeSerialNumber"].ToString();
                break;
            }
        }

        ManagementClass mcMAC = new ManagementClass("Win32_NetworkAdapterConfiguration");
        ManagementObjectCollection mocMAC = mcMAC.GetInstances();
        foreach(ManagementObject m in mocMAC)
        {
            if((bool)m["IPEnabled"])
            {
                str[2] = m["MacAddress"].ToString();
                break;
            }
        }

        return str;
    }

以上爲取硬盤邏輯分區序列號,重新格式化會改變

以下爲硬盤物理序列號,需管理員權限,wmi

複製代碼

using System;
using System.Management;

namespace HTSoft.Common.Register
{
/// <summary>
/// 計算機信息類
/// </summary>
internal class Computer
{
public string CpuID;
public string MacAddress;
public string DiskID;
public string IpAddress;
public string LoginUserName;
public string ComputerName;
public string SystemType;
public string TotalPhysicalMemory; //單位:M
private static Computer _instance;

    internal static Computer Instance()
    {
        if (_instance == null)
            _instance = new Computer();
        return _instance;
    }

    internal Computer()
    {
        CpuID = GetCpuID();
        MacAddress = GetMacAddress();
        DiskID = GetDiskID();
        IpAddress = GetIPAddress();
        LoginUserName = GetUserName();
        SystemType = GetSystemType();
        TotalPhysicalMemory = GetTotalPhysicalMemory();
        ComputerName = GetComputerName();
    }
    string GetCpuID()
    {
        try
        {
            //獲取CPU序列號代碼 
            string cpuInfo = "";//cpu序列號 
            ManagementClass mc = new ManagementClass("Win32_Processor");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
            }
            moc = null;
            mc = null;
            return cpuInfo;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }

    }
    string GetMacAddress()
    {
        try
        {
            //獲取網卡硬件地址 
            string mac = "";
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if ((bool)mo["IPEnabled"] == true)
                {
                    mac = mo["MacAddress"].ToString();
                    break;
                }
            }
            moc = null;
            mc = null;
            return mac;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }

    }
    string GetIPAddress()
    {
        try
        {
            //獲取IP地址 
            string st = "";
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if ((bool)mo["IPEnabled"] == true)
                {
                    //st=mo["IpAddress"].ToString(); 
                    System.Array ar;
                    ar = (System.Array)(mo.Properties["IpAddress"].Value);
                    st = ar.GetValue(0).ToString();
                    break;
                }
            }
            moc = null;
            mc = null;
            return st;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }

    }

    string GetDiskID()
    {
        try
        {
            //獲取硬盤ID 
            String HDid = "";
            ManagementClass mc = new ManagementClass("Win32_DiskDrive");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                HDid = (string)mo.Properties["Model"].Value;
            }
            moc = null;
            mc = null;
            return HDid;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }

    }

    /// <summary> 
    /// 操作系統的登錄用戶名 
    /// </summary> 
    /// <returns></returns> 
    string GetUserName()
    {
        try
        {
            string st = "";
            ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {

                st = mo["UserName"].ToString();

            }
            moc = null;
            mc = null;
            return st;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }

    }

    /// <summary> 
    /// PC類型 
    /// </summary> 
    /// <returns></returns> 
    string GetSystemType()
    {
        try
        {
            string st = "";
            ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {

                st = mo["SystemType"].ToString();

            }
            moc = null;
            mc = null;
            return st;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }

    }

    /// <summary> 
    /// 物理內存 
    /// </summary> 
    /// <returns></returns> 
    string GetTotalPhysicalMemory()
    {
        try
        {

            string st = "";
            ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {

                st = mo["TotalPhysicalMemory"].ToString();

            }
            moc = null;
            mc = null;
            return st;
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }
    }
    /// <summary> 
    ///  獲取計算機名稱
    /// </summary> 
    /// <returns></returns> 
    string GetComputerName()
    {
        try
        {
            return System.Environment.GetEnvironmentVariable("ComputerName");
        }
        catch
        {
            return "unknow";
        }
        finally
        {
        }
    }
}

}
複製代碼

第三種方案:

Code

一般軟件的註冊機制可以通過獲取硬件序列號,然後用非對稱加密算法生成相應的公鑰和私鑰。但是用Managed Code寫獲取硬盤序列號的代碼不能解決所有的問題,比如不能在非管理員的權限下使用,前幾天Sunmast在他的Blog上發佈了《如何得到硬盤序列號?.NET版本[C#]》,就是沒有解決這個問題,用WMI也有很多問題。

要想順利獲取硬盤的序列號,目前只能依靠非託管代碼了。DiskId32是一個源碼公開的C++程序,可以解決上述問題。由於代碼比較底層,我對VC和DDK不熟悉,沒有能力將其封裝爲DLL,希望各位幫忙!

還有,就算封裝好了這個Native DLL並可以使用了,但還有問題沒有解決。如果封裝到了Native DLL,該DLL很容易被人替換成另外一個,畢竟在Managed Code裏面可以看到調用Native DLL的函數聲明,別人只要模仿這些函數界面重新寫一個新的就很容易達到破解目的了。不過具體我沒有測試過,不知道行不行。

於是我又想到了另外一個方法,就是把獲取硬盤序列號的Native DLL作爲資源文件封裝到Managed Code中,然後在每次要調要該DLL時,先把該DLL寫入磁盤,再動態綁定。由於Managed Code可以通過混淆器來保護,以致不能對其進行修改,這個我在《如何保護我們的 .NET 程序集?》中已經給出了答案。動態綁定Native DLL又是另外一個技術難題,我已經找到了一些資料,與大家分享。
Late binding on native DLLs with C#
Late-Binding DLLs in C#
Using legacy plug-ins with .NET - Part 1
Using legacy plug-ins with .NET - Part 2
C-Function pointer for .NET
Dynamic PInvoke method calls

不過最牛的就是下面這一招了!直接把Native Code用字節數組保存在Managed Code中,然後調用,真是牛B,不過我還沒有完全弄懂,希望大家來實踐實踐。
Execute Native Code From .NET

另外還有一篇文章是關於加密字符串的,值得研究!
Poly-Engine Crypt String

希望各位多多交流.NET程序的保護問題,找出最好的解決方案!

http://www.winsim.com/diskid32/diskid32.html

複製代碼

這個問題我查找了一下,已經有很多很多很多人問過了,有給了一些相映的解答。
1)利用 WMI 讀取
2)有高人給了一個地址,http://www.winsim.com/diskid32/diskid32.html 。同時給了一大段代碼,代碼見後面。

但是沒有明確講出來如何使用。尤其是第二種方法,感覺不錯,只是不懂得如何使用,哪位指點小弟一二

public class IDE
{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
internal struct IDSECTOR
{
public ushort wGenConfig;
public ushort wNumCyls;
public ushort wReserved;
public ushort wNumHeads;
public ushort wBytesPerTrack;
public ushort wBytesPerSector;
public ushort wSectorsPerTrack;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=3)]
public ushort [] wVendorUnique;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=20)]
public string sSerialNumber;
public ushort wBufferType;
public ushort wBufferSize;
public ushort wECCSize;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=8)]
public string sFirmwareRev;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=40)]
public string sModelNumber;
public ushort wMoreVendorUnique;
public ushort wDoubleWordIO;
public ushort wCapabilities;
public ushort wReserved1;
public ushort wPIOTiming;
public ushort wDMATiming;
public ushort wBS;
public ushort wNumCurrentCyls;
public ushort wNumCurrentHeads;
public ushort wNumCurrentSectorsPerTrack;
public uint ulCurrentSectorCapacity;
public ushort wMultSectorStuff;
public uint ulTotalAddressableSectors;
public ushort wSingleWordDMA;
public ushort wMultiWordDMA;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=128 )]
public byte [] bReserved;
}

  [StructLayout(LayoutKind.Sequential)]       
  internal   struct   DRIVERSTATUS     
  {     
      public   byte     bDriverError;     
      public   byte     bIDEStatus;     
      [   MarshalAs(   UnmanagedType.ByValArray,   SizeConst=2   )]       
      public   byte   []   bReserved;     
      [   MarshalAs(   UnmanagedType.ByValArray,   SizeConst=2   )]       
      public   uint   []   dwReserved;     
  }     

  [StructLayout(LayoutKind.Sequential)]       
  internal   struct   SENDCMDOUTPARAMS     
  {     
      public   uint   cBufferSize;     
      public   DRIVERSTATUS     DriverStatus;     
      [   MarshalAs(   UnmanagedType.ByValArray,   SizeConst=513   )]       
      public   byte   []   bBuffer;     
  }     

  [StructLayout(LayoutKind.Sequential,   CharSet=CharSet.Ansi)]       
  internal   struct   SRB_IO_CONTROL     
  {     
      public   uint   HeaderLength;     
      [   MarshalAs(   UnmanagedType.ByValTStr,   SizeConst=8   )]       
      public   string   Signature;     
      public   uint   Timeout;     
      public   uint   ControlCode;     
      public   uint   ReturnCode;     
      public   uint   Length;     
  }     

  [StructLayout(LayoutKind.Sequential)]       
  internal   struct   IDEREGS     
  {     
      public   byte   bFeaturesReg;     
      public   byte   bSectorCountReg;     
      public   byte   bSectorNumberReg;     
      public   byte   bCylLowReg;     
      public   byte   bCylHighReg;     
      public   byte   bDriveHeadReg;     
      public   byte   bCommandReg;     
      public   byte   bReserved;     
  }     

  [StructLayout(LayoutKind.Sequential)]       
  internal   struct   SENDCMDINPARAMS     
  {     
      public   uint           cBufferSize;     
      public   IDEREGS       irDriveRegs;     
      public   byte   bDriveNumber;     
      [   MarshalAs(   UnmanagedType.ByValArray,   SizeConst=3   )]       
      public   byte   []   bReserved;     
      [   MarshalAs(   UnmanagedType.ByValArray,   SizeConst=4   )]       
      public   uint   []   dwReserved;     
      public   byte             bBuffer;     

}

  [StructLayout(LayoutKind.Sequential)]       
  internal   struct   GETVERSIONOUTPARAMS     
  {     
      public   byte   bVersion;     
      public   byte   bRevision;     
      public   byte   bReserved;     
      public   byte   bIDEDeviceMap;     
      public   uint   fCapabilities;     
      [   MarshalAs(   UnmanagedType.ByValArray,   SizeConst=4   )]       
      public   uint   []   dwReserved;   //   For   future   use.     
  }     

  [DllImport("kernel32.dll")]     
  private   static   extern   int   CloseHandle(uint   hObject);     

  [DllImport("kernel32.dll")]     
  private   static   extern   int   DeviceIoControl(uint   hDevice,     
    uint   dwIoControlCode,     
    ref   SENDCMDINPARAMS   lpInBuffer,     
    int   nInBufferSize,     
    ref   SENDCMDOUTPARAMS   lpOutBuffer,     
    int   nOutBufferSize,     
    ref   uint   lpbytesReturned,     
    int   lpOverlapped);     

  [DllImport("kernel32.dll")]     
  private   static   extern   int   DeviceIoControl(uint   hDevice,     
    uint   dwIoControlCode,     
    int   lpInBuffer,     
    int   nInBufferSize,     
    ref   GETVERSIONOUTPARAMS   lpOutBuffer,     
    int   nOutBufferSize,     
    ref   uint   lpbytesReturned,     
    int   lpOverlapped);     

  [DllImport("kernel32.dll")]     
  private   static   extern   uint   CreateFile(string   lpFileName,     
    uint   dwDesiredAccess,     
    uint   dwShareMode,     
    int   lpSecurityAttributes,     
    uint   dwCreationDisposition,     
    uint   dwFlagsAndAttributes,     
    int   hTemplateFile);     

  private   const   uint   GENERIC_READ   =   0x80000000;     
  private   const   uint   GENERIC_WRITE   =   0x40000000;     
  private   const   uint   FILE_SHARE_READ   =   0x00000001;     
  private   const   uint   FILE_SHARE_WRITE   =   0x00000002;     
  private   const   uint   OPEN_EXISTING   =   3;     
  private   const   uint   INVALID_HANDLE_VALUE   =   0xffffffff;     
  private   const   uint   DFP_GET_VERSION   =   0x00074080;     
  private   const   int   IDE_ATAPI_IDENTIFY   =   0xA1;     //     Returns   ID   sector   for   ATAPI.     
  private   const   int   IDE_ATA_IDENTIFY   =   0xEC;     //     Returns   ID   sector   for   ATA.     
  private   const   int   IDENTIFY_BUFFER_SIZE   =   512;     
  private   const   uint   DFP_RECEIVE_DRIVE_DATA   =   0x0007c088;     

  public   static   string   Read(byte   drive)     
  {     
        OperatingSystem   os   =   Environment.OSVersion;     
        if   (os.Platform   !=   PlatformID.Win32NT)   throw   new   NotSupportedException("僅支持WindowsNT/2000/XP");     
        //我沒有NT4,請哪位大大測試一下NT4下能不能用     
        //if   (os.Version.Major   <   5)   throw   new   NotSupportedException("僅支持WindowsNT/2000/XP");     

      string   driveName   =   "\\\\.\\PhysicalDrive"   +   drive.ToString();     
      uint   device   =   CreateFile(driveName,     
    GENERIC_READ   |   GENERIC_WRITE,       
    FILE_SHARE_READ   |   FILE_SHARE_WRITE,     
    0,   OPEN_EXISTING,   0,   0);     
      if   (device   ==   INVALID_HANDLE_VALUE)   return   "";     
      GETVERSIONOUTPARAMS   verPara   =   new   GETVERSIONOUTPARAMS();     
      uint   bytRv   =   0;     

      if   (0   !=   DeviceIoControl(device,   DFP_GET_VERSION,     
    0,   0,   ref   verPara,   Marshal.SizeOf(verPara),     
    ref   bytRv,   0))     
      {     
            if   (verPara.bIDEDeviceMap   >   0)     
            {     
    byte   bIDCmd   =   (byte)(((verPara.bIDEDeviceMap   >>   drive   &   0x10)   !=   0)   ?       IDE_ATAPI_IDENTIFY   :   IDE_ATA_IDENTIFY);     
    SENDCMDINPARAMS   scip   =   new   SENDCMDINPARAMS();     
    SENDCMDOUTPARAMS   scop   =   new   SENDCMDOUTPARAMS();     

    scip.cBufferSize   =   IDENTIFY_BUFFER_SIZE;     
    scip.irDriveRegs.bFeaturesReg   =   0;     
    scip.irDriveRegs.bSectorCountReg   =   1;     
    scip.irDriveRegs.bCylLowReg   =   0;     
    scip.irDriveRegs.bCylHighReg   =   0;     
    scip.irDriveRegs.bDriveHeadReg   =   (byte)(0xA0   |   ((drive   &   1)   <<   4));     
    scip.irDriveRegs.bCommandReg   =   bIDCmd;     
    scip.bDriveNumber   =   drive;     

    if   (0   !=   DeviceIoControl(device,   DFP_RECEIVE_DRIVE_DATA,     
          ref   scip,   Marshal.SizeOf(scip),   ref   scop,     
          Marshal.SizeOf(scop),   ref   bytRv,   0))     
    {     
        StringBuilder   s   =   new   StringBuilder();     
        for   (int   i   =   20;   i   <   40;   i   +=   2)     
        {     
            s.Append((char)(scop.bBuffer[i+1]));     
            s.Append((char)scop.bBuffer[i]);     
        }     
        CloseHandle(device);     
        return   s.ToString().Trim();     
    }     
              }     
        }     
        CloseHandle(device);     
        return   "";     
  }     

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章