读取硬盘序列号时单硬盘正常, 多硬盘为什么读不到?
下面的代码在单硬盘上很正常,我有个用户用的多硬盘(两块西捷,每块120G,还有一个移动硬盘),用下面的两种代码都读不到,为什么?//
// 这是用WMI读取硬盘序列号
//
ManagementClass mcDisk = new ManagementClass("Win32_PhysicalMedia");
ManagementObjectCollection mocDisk = mcDisk.GetInstances();
foreach(ManagementObject m in mocDisk)
{
if (m["SerialNumber"] != null)
{
computerId = m["SerialNumber"].ToString().Trim();
if (computerId != "")
{
break;
}
}
}
if (computerId == "")
{
computerId = "不能读取硬件码.";
}//
// 这是别人写的一个类,同样在多硬盘的机子上读不到.
//int n = 0; // 表示第几块硬盘
int id = IDE.Read(n);  // 读取硬盘序列号

解决方案 »

  1.   

    //
    // 续...
    //
    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");    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   "";   
    }   
    }
      

  2.   

    好麻烦的程序:
    第一种方法:
    using System.Management; 
    ManagementClass mc=new ManagementClass("Win32_PhysicalMedia");
    foreach(ManagementObject mb in aa.GetInstances())
    {
        MessageBox.Show(
        bb.Properties["SerialNumber"].Value.Tostring();
    }
    注意foreach循环
      

  3.   

    或参考http://zealot.cnblogs.com/archive/2006/02/25/49942.html
      

  4.   

    主要是m["SerialNumber"]在用户机子上测试时老是空引用,所以判断一下,免得一直产生空引用异常.if (m["SerialNumber"] != null)
    {
    computerId = m["SerialNumber"].ToString().Trim();
    if (computerId != "")
    {
    break;
    }
    }
      

  5.   

    谢谢 TheRule(绝非偶然): 那个网址讲的VB.NET的那个类和我贴的IDE类(C#)原理一样. 另外里面WMI调用也一样.
      

  6.   

    谁知道怎么用代码判断一个硬盘是HDD IDE还是HDD SCSI?
      

  7.   

    thanks a lot, wfhlxl:不是. 是所有的都读不到!