解决方案 »

  1.   

    procedure GetCpuInfo;
    var R: array[0..19] of Char;
    var CpuID: Integer;
    begin
      FillChar(R, 20, 0);
      asm
        mov eax, 0
        db 0fh, 0a2h               // 其实就是cpuid汇编指令
        mov dword ptr R[0],  ebx
        mov dword ptr R[4],  edx
        mov dword ptr R[8],  ecx
        mov eax, 1
        db 0fh, 0a2h               // cpuid
        mov CpuID, edx
      end;
      ShowMessage('CPU制造商为:' + R);
      ShowMessage('序列号为:' + IntToStr(CpuID));
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      GetCpuInfo;
    end;
      

  2.   

    procedure GetCpuInfo;
    var R: array[0..19] of Char;
    var CpuID: Integer;
    begin
      FillChar(R, 20, 0);
      asm
        mov eax, 0
        db 0fh, 0a2h               // 其实就是cpuid汇编指令
        mov dword ptr R[0],  ebx
        mov dword ptr R[4],  edx
        mov dword ptr R[8],  ecx
        mov eax, 1
        db 0fh, 0a2h               // cpuid
        mov CpuID, edx
      end;
      ShowMessage('CPU制造商为:' + R);
      ShowMessage('序列号为:' + IntToStr(CpuID));
    end;
      

  3.   

    不行啊,在多台机上测试得出的CPU的ID相同,都为25426431,这是为什么?
      

  4.   

    学习!
    试了一下:
    CPU制造商为:GenuineIntel
    序列号为:8452697
      

  5.   

    怎么解决这样的问题,在多台机器上得到的CPU的ID都相同,为什么会有这样的情况出现
      

  6.   

    函数原形如下:
     VOID GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);//指向系统信息结构的指针;
    例:
    var :System_Info;
    begin
      GetSystemInfo(SysInfo);//获取CPU信息;
      Edit1.text:='系统共有'+IntTostr(SysInfo.dwNumberOfProcessors)+'个CPU';
    end;
      

  7.   

    学习。试了一下luoweicaisd(笑三少) 的代码:
    CPU制造商为:GenuineIntel
    序列号为:8452607正确!
      

  8.   

    用上面那段代码,为什么多台机器测出的CPU ID 都是一样的?两台塞羊(型号一样)和一台奔三,得到的结果都是一样的。
      

  9.   

    下面是得到BIOS信息的代码:procedure TForm1.BiosInfo;
    const
      Subkey: string = ''Hardware\description\system'';
    var
      hkSB: HKEY;
      rType: LongInt;
      ValueSize, OrigSize: Longint;
      ValueBuf: array[0..1000] of char;
      procedure ParseValueBuf(const VersionType: string);
      var
        I, Line: Cardinal;
        S: string;
      begin
        i := 0;
        Line := 0;
        while ValueBuf[i] <> #0 do
        begin
          S := StrPas(@ValueBuf[i]); // move the Pchar into a string
          Inc(Line);
          Memo1.Lines.Append(Format(''%s Line %d = %s'',
            [VersionType, Line, S])); // add it to a Memo
          inc(i, Length(S) + 1); 
          // to point to next sz, or to #0 if at
        end
      end;
    end;begin
      if RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar(Subkey), 0, 
                      KEY_READ, hkSB) = ERROR_SUCCESS then
      try
        OrigSize := sizeof(ValueBuf);
        ValueSize := OrigSize;
        rType := REG_MULTI_SZ;
        if RegQueryValueEx(hkSB, ''SystemBiosVersion'', nil, @rType,
          @ValueBuf, @ValueSize) = ERROR_SUCCESS then
          ParseValueBuf(''System BIOS Version'');    ValueSize := OrigSize;
        rType := REG_SZ;
        if RegQueryValueEx(hkSB, ''SystemBIOSDate'', nil, @rType,
          @ValueBuf, @ValueSize) = ERROR_SUCCESS then
          Memo1.Lines.Append(''System BIOS Date '' + ValueBuf);    ValueSize := OrigSize;
        rType := REG_MULTI_SZ;
        if RegQueryValueEx(hkSB, ''VideoBiosVersion'', nil, @rType,
          @ValueBuf, @ValueSize) = ERROR_SUCCESS then
          ParseValueBuf(''Video BIOS Version'');    ValueSize := OrigSize;
        rType := REG_SZ;
        if RegQueryValueEx(hkSB, ''VideoBIOSDate'', nil, @rType,
          @ValueBuf, @ValueSize) = ERROR_SUCCESS then
          Memo1.Lines.Append(''Video BIOS Date '' + ValueBuf);
      finally
        RegCloseKey(hkSB);
      end;
    end;
     
      

  10.   

    读硬盘的序列号
    procedure GetHardDriveinfo;
      var
         VolumeSerialNumber : DWORD;
         MaximumComponentLength : DWORD;
         FileSystemFlags : DWORD;
         SerialNumber : string;
         drv:string;
    begin
         drv:='c:\';//可以改成其它硬盘     GetVolumeInformation(pchar(drv) , nil,0,@VolumeSerialNumber,
                         MaximumComponentLength, FileSystemFlags,
                         nil,0);
         SerialNumber:=inttostr(VolumeSerialNumber);
         ShowMessage(SerialNumber);end;
      

  11.   

    许多FAQ中推荐使用GetVolumeInformation来获取硬盘序列号。但是那获取的是卷的序列号,而不是硬盘的序列号。卷的序列号是在分区格式化时生成或修改。一些公司使用复制工具来为全部新计算机安装软件----通过将一个硬盘复制到其它硬盘,当然,所有这些计算机上卷的信息(包括序列号)都是相同的。
      
      我建议另外的一个方法:获取真正硬盘的序列号。
      不幸的是,下列代码只能工作在IDE硬盘上。
      
      
      //获取第一个IDE硬盘的序列号 
      function GetIdeSerialNumber : SerialNumber; 
      const IDENTIFY_BUFFER_SIZE = 512; 
      type 
        TIDERegs = packed record 
          bFeaturesReg     : BYTE; // Used for specifying SMART "commands". 
          bSectorCountReg  : BYTE; // IDE sector count register 
          bSectorNumberReg : BYTE; // IDE sector number register 
          bCylLowReg       : BYTE; // IDE low order cylinder value 
          bCylHighReg      : BYTE; // IDE high order cylinder value 
          bDriveHeadReg    : BYTE; // IDE drive/head register 
          bCommandReg      : BYTE; // Actual IDE command. 
          bReserved        : BYTE; // reserved for future use.  Must be zero. 
        end; 
        TSendCmdInParams = packed record 
          // Buffer size in bytes 
          cBufferSize  : DWORD; 
          // Structure with drive register values. 
          irDriveRegs  : TIDERegs; 
          // Physical drive number to send command to (0,1,2,3). 
          bDriveNumber : BYTE; 
          bReserved    : Array[0..2] of Byte; 
          dwReserved   : Array[0..3] of DWORD; 
          bBuffer      : Array[0..0] of Byte;  // Input buffer. 
        end; 
        TIdSector = packed record 
          wGenConfig                 : Word; 
          wNumCyls                   : Word; 
          wReserved                  : Word; 
          wNumHeads                  : Word; 
          wBytesPerTrack             : Word; 
          wBytesPerSector            : Word; 
          wSectorsPerTrack           : Word; 
          wVendorUnique              : Array[0..2] of Word; 
          sSerialNumber              : Array[0..19] of CHAR; 
          wBufferType                : Word; 
          wBufferSize                : Word; 
          wECCSize                   : Word; 
          sFirmwareRev               : Array[0..7] of Char; 
          sModelNumber               : Array[0..39] of Char; 
          wMoreVendorUnique          : Word; 
          wDoubleWordIO              : Word; 
          wCapabilities              : Word; 
          wReserved1                 : Word; 
          wPIOTiming                 : Word; 
          wDMATiming                 : Word; 
          wBS                        : Word; 
          wNumCurrentCyls            : Word; 
          wNumCurrentHeads           : Word; 
          wNumCurrentSectorsPerTrack : Word; 
          ulCurrentSectorCapacity    : DWORD; 
          wMultSectorStuff           : Word; 
          ulTotalAddressableSectors  : DWORD; 
          wSingleWordDMA             : Word; 
          wMultiWordDMA              : Word; 
          bReserved                  : Array[0..127] of BYTE; 
        end; 
        PIdSector = ^TIdSector; 
        TDriverStatus = packed record 
          // 驱动器返回的错误代码,无错则返回0
          bDriverError : Byte; 
          // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效
          bIDEStatus   : Byte; 
          bReserved    : Array[0..1] of Byte; 
          dwReserved   : Array[0..1] of DWORD; 
        end; 
        TSendCmdOutParams = packed record 
          // bBuffer的大小
          cBufferSize  : DWORD; 
          // 驱动器状态
          DriverStatus : TDriverStatus; 
          // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定
          bBuffer      : Array[0..0] of BYTE; 
        end; 
      
      var hDevice : THandle; 
          cbBytesReturned : DWORD; 
          ptr : PChar; 
          SCIP : TSendCmdInParams; 
          aIdOutCmd : Array [0..(SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1)-1] of Byte; 
          IdOutCmd  : TSendCmdOutParams absolute aIdOutCmd; 
      
        procedure ChangeByteOrder( var Data; Size : Integer ); 
        var ptr : PChar; 
            i : Integer; 
            c : Char; 
        begin 
          ptr := @Data; 
          for i := 0 to (Size shr 1)-1 do 
          begin 
            c := ptr^; 
            ptr^ := (ptr+1)^; 
            (ptr+1)^ := c; 
            Inc(ptr,2); 
          end; 
        end; 
      
      begin 
        Result := ''; // 如果出错则返回空串
        if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT, Windows 2000 
          begin 
            // 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\'
            hDevice := CreateFile( '\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE, 
              FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 ); 
          end 
        else // Version Windows 95 OSR2, Windows 98 
          hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 ); 
        if hDevice=INVALID_HANDLE_VALUE then Exit; 
        try 
          FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0); 
          FillChar(aIdOutCmd,SizeOf(aIdOutCmd),#0); 
          cbBytesReturned := 0; 
          // Set up data structures for IDENTIFY command. 
          with SCIP do 
          begin 
            cBufferSize  := IDENTIFY_BUFFER_SIZE; 
      //      bDriveNumber := 0; 
            with irDriveRegs do 
            begin 
              bSectorCountReg  := 1; 
              bSectorNumberReg := 1; 
      //      if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0 
      //      else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4); 
              bDriveHeadReg    := $A0; 
              bCommandReg      := $EC; 
            end; 
          end; 
          if not DeviceIoControl( hDevice, $0007c088, @SCIP, SizeOf(TSendCmdInParams)-1, 
            @aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil ) then Exit; 
        finally 
          CloseHandle(hDevice); 
        end; 
        with PIdSector(@IdOutCmd.bBuffer)^ do 
        begin 
          ChangeByteOrder( sSerialNumber, SizeOf(sSerialNumber) ); 
          (PChar(@sSerialNumber)+SizeOf(sSerialNumber))^ := #0; 
          Result := PChar(@sSerialNumber); 
        end; 
      end; 
      
      // 更多关于 S.M.A.R.T. ioctl 的信息可查看:
      //  http://www.microsoft.com/hwdev/download/respec/iocltapi.rtf 
      
      // MSDN库中也有一些简单的例子
      //  Windows Development -> Win32 Device Driver Kit -> 
      //  SAMPLE: SmartApp.exe Accesses SMART stats in IDE drives 
      
      // 还可以查看 http://www.mtgroup.ru/~alexk 
      //  IdeInfo.zip - 一个简单的使用了S.M.A.R.T. Ioctl API的Delphi应用程序
      
      // 注意: 
      
      //  WinNT/Win2000 - 你必须拥有对硬盘的读/写访问权限
      
      //  Win98 
      //    SMARTVSD.VXD 必须安装到 \windows\system\iosubsys 
      //    (不要忘记在复制后重新启动系统) 
      

  12.   

    在我的前一篇文章(http://www.ocloud.com/article/viewart.php?id=88)里我描述了一个通过调用以DFP_RECEIVE_DRIVE_DATA为控制码的DeviceIoControl函数来获取序列号,但在NT上只有拥有系统管理员权限的用户才能使用。现在我找到了让所有用户都可以使用的方法。
      { 构件下载:IdeSN.zip }
      提示! 在Win9x系统中必须安装smartvsd.vxd:你只需简单的将它从\windows\system\目录中复制到\windows\system\iosubsys\下,然后重新启动系统。
      
      // (c) Alex Konshin 30 jul 2000 
      
      program IdeSN; 
      
      // 目的:简单的控制台程序以获取第一个IDE硬盘的序列号
      
      {$APPTYPE CONSOLE} 
      
      uses 
        Windows, 
        SysUtils; // only for Win32Platform and SysErrorMessage 
      
      //------------------------------------------------------------- 
      function GetIdeDiskSerialNumber : String; 
      type 
        TSrbIoControl = packed record 
          HeaderLength : ULONG; 
          Signature    : Array[0..7] of Char; 
          Timeout      : ULONG; 
          ControlCode  : ULONG; 
          ReturnCode   : ULONG; 
          Length       : ULONG; 
        end; 
        SRB_IO_CONTROL = TSrbIoControl; 
        PSrbIoControl = ^TSrbIoControl; 
      
        TIDERegs = packed record 
          bFeaturesReg     : Byte; // Used for specifying SMART "commands". 
          bSectorCountReg  : Byte; // IDE sector count register 
          bSectorNumberReg : Byte; // IDE sector number register 
          bCylLowReg       : Byte; // IDE low order cylinder value 
          bCylHighReg      : Byte; // IDE high order cylinder value 
          bDriveHeadReg    : Byte; // IDE drive/head register 
          bCommandReg      : Byte; // Actual IDE command. 
          bReserved        : Byte; // reserved.  Must be zero. 
        end; 
        IDEREGS   = TIDERegs; 
        PIDERegs  = ^TIDERegs; 
      
        TSendCmdInParams = packed record 
          cBufferSize  : DWORD; 
          irDriveRegs  : TIDERegs; 
          bDriveNumber : Byte; 
          bReserved    : Array[0..2] of Byte; 
          dwReserved   : Array[0..3] of DWORD; 
          bBuffer      : Array[0..0] of Byte; 
        end; 
        SENDCMDINPARAMS   = TSendCmdInParams; 
        PSendCmdInParams  = ^TSendCmdInParams; 
      
        TIdSector = packed record 
          wGenConfig                 : Word; 
          wNumCyls                   : Word; 
          wReserved                  : Word; 
          wNumHeads                  : Word; 
          wBytesPerTrack             : Word; 
          wBytesPerSector            : Word; 
          wSectorsPerTrack           : Word; 
          wVendorUnique              : Array[0..2] of Word; 
          sSerialNumber              : Array[0..19] of Char; 
          wBufferType                : Word; 
          wBufferSize                : Word; 
          wECCSize                   : Word; 
          sFirmwareRev               : Array[0..7] of Char; 
          sModelNumber               : Array[0..39] of Char; 
          wMoreVendorUnique          : Word; 
          wDoubleWordIO              : Word; 
          wCapabilities              : Word; 
          wReserved1                 : Word; 
          wPIOTiming                 : Word; 
          wDMATiming                 : Word; 
          wBS                        : Word; 
          wNumCurrentCyls            : Word; 
          wNumCurrentHeads           : Word; 
          wNumCurrentSectorsPerTrack : Word; 
          ulCurrentSectorCapacity    : ULONG; 
          wMultSectorStuff           : Word; 
          ulTotalAddressableSectors  : ULONG; 
          wSingleWordDMA             : Word; 
          wMultiWordDMA              : Word; 
          bReserved                  : Array[0..127] of Byte; 
        end; 
        PIdSector = ^TIdSector; 
      
      const 
        IDE_ID_FUNCTION = $EC; 
        IDENTIFY_BUFFER_SIZE       = 512; 
        DFP_RECEIVE_DRIVE_DATA        = $0007c088; 
        IOCTL_SCSI_MINIPORT           = $0004d008; 
        IOCTL_SCSI_MINIPORT_IDENTIFY  = $001b0501; 
        DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE; 
        BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize; 
        W9xBufferSize = IDENTIFY_BUFFER_SIZE+16; 
      var 
        hDevice : THandle; 
        cbBytesReturned : DWORD; 
        pInData : PSendCmdInParams; 
        pOutData : Pointer; // PSendCmdOutParams 
        Buffer : Array[0..BufferSize-1] of Byte; 
        srbControl : TSrbIoControl absolute Buffer; 
      
        procedure ChangeByteOrder( var Data; Size : Integer ); 
        var ptr : PChar; 
            i : Integer; 
            c : Char; 
        begin 
          ptr := @Data; 
          for i := 0 to (Size shr 1)-1 do 
          begin 
            c := ptr^; 
            ptr^ := (ptr+1)^; 
            (ptr+1)^ := c; 
            Inc(ptr,2); 
          end; 
        end; 
      
      begin 
        Result := ''; 
        FillChar(Buffer,BufferSize,#0); 
        if Win32Platform=VER_PLATFORM_WIN32_NT then 
          begin // Windows NT, Windows 2000 
            // 获取 SCSI port handle 
            hDevice := CreateFile( '\\.\Scsi0:', 
              GENERIC_READ or GENERIC_WRITE, 
              FILE_SHARE_READ or FILE_SHARE_WRITE, 
              nil, OPEN_EXISTING, 0, 0 ); 
            if hDevice=INVALID_HANDLE_VALUE then Exit; 
            try 
              srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL); 
              System.Move('SCSIDISK',srbControl.Signature,8); 
              srbControl.Timeout      := 2; 
              srbControl.Length       := DataSize; 
              srbControl.ControlCode  := IOCTL_SCSI_MINIPORT_IDENTIFY; 
              pInData := PSendCmdInParams(PChar(@Buffer) 
                         +SizeOf(SRB_IO_CONTROL)); 
              pOutData := pInData; 
              with pInData^ do 
              begin 
                cBufferSize  := IDENTIFY_BUFFER_SIZE; 
                bDriveNumber := 0; 
                with irDriveRegs do 
                begin 
                  bFeaturesReg     := 0; 
                  bSectorCountReg  := 1; 
                  bSectorNumberReg := 1; 
                  bCylLowReg       := 0; 
                  bCylHighReg      := 0; 
                  bDriveHeadReg    := $A0; 
                  bCommandReg      := IDE_ID_FUNCTION; 
                end; 
              end; 
              if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, 
                @Buffer, BufferSize, @Buffer, BufferSize, 
                cbBytesReturned, nil ) then Exit; 
            finally 
              CloseHandle(hDevice); 
            end; 
          end 
        else 
          begin // Windows 95 OSR2, Windows 98 
            hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, 
              CREATE_NEW, 0, 0 ); 
            if hDevice=INVALID_HANDLE_VALUE then Exit; 
            try 
              pInData := PSendCmdInParams(@Buffer); 
              pOutData := @pInData^.bBuffer; 
              with pInData^ do 
              begin 
                cBufferSize  := IDENTIFY_BUFFER_SIZE; 
                bDriveNumber := 0; 
                with irDriveRegs do 
                begin 
                  bFeaturesReg     := 0; 
                  bSectorCountReg  := 1; 
                  bSectorNumberReg := 1; 
                  bCylLowReg       := 0; 
                  bCylHighReg      := 0; 
                  bDriveHeadReg    := $A0; 
                  bCommandReg      := IDE_ID_FUNCTION; 
                end; 
              end; 
              if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, 
                pInData, SizeOf(TSendCmdInParams)-1, pOutData, 
                W9xBufferSize, cbBytesReturned, nil ) then Exit; 
            finally 
              CloseHandle(hDevice); 
            end; 
          end; 
          with PIdSector(PChar(pOutData)+16)^ do 
          begin 
            ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber)); 
            SetString(Result,sSerialNumber,SizeOf(sSerialNumber)); 
          end; 
      end; 
      
      
      //============================================================= 
      var s : String; 
          rc : DWORD; 
      begin 
        s := GetIdeDiskSerialNumber; 
        if s='' then 
          begin 
            rc := GetLastError; 
            if rc=0 then WriteLn('IDE drive is not support SMART feature') 
            else WriteLn(SysErrorMessage(rc)); 
          end 
        else WriteLn('Disk serial number: ''', s,''''); 
      end. 
      

  13.   

    感谢fontain等网友的关注,为表感谢,送分了,接分了...