这个问题首先得考虑的就是你的硬盘是不是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
{
///


/// 计算机信息类
///

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
        {
        }

    }

    ///  
    /// 操作系统的登录用户名 
    ///  
    ///  
    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
        {
        }

    }

    ///  
    /// PC类型 
    ///  
    ///  
    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
        {
        }

    }

    ///  
    /// 物理内存 
    ///  
    ///  
    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
        {
        }
    }
    ///  
    ///  获取计算机名称
    ///  
    ///  
    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   "";     
  }     

}