以下代码是从别人那看来的 但发觉我每次提取序列号似乎不同 请问是不是双核CPU造成的 如何纠正这个问题呢FUNCTION GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,EAX {@Resukt}
MOV EAX,1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
END; function GetCPUSerialNumber: String;
var
CPUID:TCPUID;
begin
Result:='';
CPUID:=GetCPUID;
Result := IntToHex(CPUID[1],8)+IntToHex(CPUID[2],8)+IntToHex(CPUID[3],8)+IntToHex(CPUID[4],8);
end;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,EAX {@Resukt}
MOV EAX,1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
END; function GetCPUSerialNumber: String;
var
CPUID:TCPUID;
begin
Result:='';
CPUID:=GetCPUID;
Result := IntToHex(CPUID[1],8)+IntToHex(CPUID[2],8)+IntToHex(CPUID[3],8)+IntToHex(CPUID[4],8);
end;
解决方案 »
- 如何禁止delphi 自动将输入法填入imeName
- ADOQuery 多表更新问题
- 急,菜鸟运行存储过程的问题
- 如何把一个excel或word等文件保存到oracle7.3中,并可以把它读出并用excel或word程序打开.(用DELPHI开发)
- 关于mssql2000的行集过滤问题(非delphi相关问题)
- 如何在程序中自动登陆数据库,而该数据库有密码的。(bde和Paradox)
- 请问那有stringgrid控件使用介绍的文章
- 类似于微软拼音的虚拟键盘的源代码。那个有?
- 一个表可能同时有3、4个人同时打开进行读写,用什么库好,还需注意什么技术?
- ******* DLL、Vxd 的问题
- 请问如何实现按内容搜索某目录中的文件?
- 如何将image 中的图像保存 到ini 文件中,且能读取出来?
{******************************************************************************}
{ CnPack For Delphi/C++Builder }
{ 中国人自己的开放源码第三方开发包 }
{ (C)Copyright 2001-2008 CnPack 开发组 }
{ ------------------------------------ }
{ }
{ 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
{ 改和重新发布这一程序。 }
{ }
{ 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
{ 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
{ }
{ 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
{ 还没有,可访问我们的网站: }
{ }
{ 网站地址:http://www.cnpack.org }
{ 电子邮件:[email protected] }
{ }
{******************************************************************************}unit CnHardWareInfo;
{* |<PRE>
================================================================================
* 软件名称:CnPack 组件包
* 单元名称:硬件信息单元
* 单元作者:SkyJacker
* LiuXiao
* 备 注:硬件信息单元,目前只实现获取多核、多CPU系统中指定CPU的序列号与占用率
* 开发平台:WindowsXP sp2 + Delphi 6.0 up2
* 兼容测试:Win2000/XP + Delphi 5、6
* 本 地 化:该单元中的字符串均符合本地化处理方式
* 单元标识:$Id: CnHardWareInfo.pas,v 1.4 2008/03/06 13:07:21 liuxiao Exp $
* 修改记录:2008.01.12 V1.1
* LiuXiao 加入对 CPU 占用率的读取
* 2007.01.23 V1.0
* 创建单元,实现功能
================================================================================
|</PRE>}interface{$I CnPack.inc}uses
Classes, Windows, SysUtils, ExtCtrls;
type
TCnCPUIdFormat = (ifContinuous, ifDashed);
{* CPU序列号显示样式
|<PRE>
ifContinuous: -连续型
ifDashed: -使用分割符'-'分割
|</PRE>
} TCnCpuId = class(TPersistent)
{CPU 信息类}
private
FTimer: TTimer;
FCPUCount: Integer;
FCPUIds: TStrings;
FCPUIdFormat: TCnCPUIdFormat;
FCPUUsageRead: Boolean;
FCPUUsage: array[0..255] of Integer; // 总不会超过 256 个 CPU 吧?
FCurCnt, FLastCnt: array[0..255] of Integer;
FAverageCPUUsage: Integer;
function GetFirstCPUId: string;
function GetCPUId(Index: Integer): string;
procedure SetCPUIdFormat(ACPUIdFormat: TCnCPUIdFormat);
function GetAverageCPUUsage: Integer;
function GetCPUUsage(Index: Integer): Integer;
function GetFirstCPUUsage: Integer; function RefreshCPUUsages: Cardinal; // 只被定时调用
procedure CpuUsageTimer(Sender: TObject);
public
constructor Create;
{* 构造函数,创建 FCPUIds 并调用 ReadCPUId}
destructor Destroy; override; procedure ReadCPUId;
{* 获得所有 CPU 内核的序列号,并存入 FCPUIds 列表} property CPUIdFormat: TCnCPUIdFormat read FCPUIdFormat write SetCPUIdFormat;
{* CPU 序列号显示样式}
property CPUCount: Integer read FCPUCount;
{* 系统中 CPU 核总数}
property FirstCPUId: string read GetFirstCPUId;
{* 获取首个 CPU 的 ID,用于单 CPU 系统}
property CPUId[Index: Integer]: string read GetCPUId;
{* 获得指定 CPU 的序列号。索引 Index 从 0 开始}
property CPUUsage[Index: Integer]: Integer read GetCPUUsage;
{* 获得指定 CPU 的占用率,0 到 100
需要说明的是,本类在 NT 系统上采用定时采样获得 CPU 的忙周期数再计算而来,
因此在刚实例化、未采样完成时,得到的 CPU 占用率可能有误。以下同。
}
property AverageCPUUsage: Integer read GetAverageCPUUsage;
{* 获得平均 CPU 占用率,0 到 100}
property FirstCPUUsage: Integer read GetFirstCPUUsage;
{* 获得首个 CPU 的占用率,0 到 100,用于单 CPU 系统}
end;implementationtype
_SYSTEM_BASIC_INFORMATION = record
Unknown: ULONG;
MaximumIncrement: ULONG;
PhysicalPageSize: ULONG;
NumberOfPhysicalPages: ULONG;
LowestPhysicalPage: ULONG;
HighestPhysicalPage: ULONG;
AllocationGranularity: ULONG;
LowestUserAddress: ULONG;
HighestUserAddress: ULONG;
ActiveProcessors: ULONG;
NumberProcessors: UCHAR;
end;
SYSTEM_BASIC_INFORMATION = _SYSTEM_BASIC_INFORMATION;
PSYSTEM_BASIC_INFORMATION = ^SYSTEM_BASIC_INFORMATION;
TSystemBasicInformation = SYSTEM_BASIC_INFORMATION;
PSystemBasicInformation = ^TSystemBasicInformation; SYSTEM_PROCESSOR_TIMES = packed record
IdleTime: LARGE_INTEGER;
KernelTime: LARGE_INTEGER;
UserTime: LARGE_INTEGER;
DpcTime: LARGE_INTEGER;
InterruptTime: LARGE_INTEGER;
InterruptCount: ULONG;
end;
TSystemProcessorTimes = SYSTEM_PROCESSOR_TIMES;
PSystemProcessorTimes = ^TSystemProcessorTimes;
SYSTEM_INFORMATION_CLASS = (
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemNotImplemented1,
SystemProcessesAndThreadsInformation,
SystemCallCounts,
SystemConfigurationInformation,
SystemProcessorTimes,
SystemGlobalFlag,
SystemNotImplemented2,
SystemModuleInformation,
SystemLockInformation,
SystemNotImplemented3,
SystemNotImplemented4,
SystemNotImplemented5,
SystemHandleInformation,
SystemObjectInformation,
SystemPagefileInformation,
SystemInstructionEmulationCounts,
SystemInvalidInfoClass1,
SystemCacheInformation,
SystemPoolTagInformation,
SystemProcessorStatistics,
SystemDpcInformation,
SystemNotImplemented6,
SystemLoadImage,
SystemUnloadImage,
SystemTimeAdjustment,
SystemNotImplemented7,
SystemNotImplemented8,
SystemNotImplemented9,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemLoadAndCallImage,
SystemPrioritySeparation,
SystemNotImplemented10,
SystemNotImplemented11,
SystemInvalidInfoClass2,
SystemInvalidInfoClass3,
SystemTimeZoneInformation,
SystemLookasideInformation,
SystemSetTimeSlipEvent,
SystemCreateSession,
SystemDeleteSession,
SystemInvalidInfoClass4,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemAddVerifier,
SystemSessionProcessesInformation);
TSystemInformationClass = SYSTEM_INFORMATION_CLASS;
TNativeQuerySystemInformation = function(SystemInformationClass:
TSystemInformationClass; SystemInformation: Pointer; SystemInformationLength:
Cardinal; ReturnLength: PDWORD): Cardinal; stdcall;
const
STATUS_SUCCESS = $00000000;var
NtDllHandle: THandle = 0; NtQuerySystemInformation: TNativeQuerySystemInformation = nil;function GetNtNativeAPIs: Boolean;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
NtDllHandle := GetModuleHandle('NTDLL.DLL');
if NtDllHandle = 0 then
NtDllHandle:=LoadLibrary('NTDLL.DLL'); if NtDllHandle <> 0 then
begin
// @NtQueryInformationToken:=GetProcAddress(NtDllHandle,'NtQueryInformationToken');
// @NtOpenProcessToken := GetProcAddress(NtDllHandle,'NtOpenProcessToken');
// @NtOpenSection := GetProcAddress(NtDllHandle,'NtOpenSection');
// @NtClose := GetProcAddress(NtDllHandle,'NtClose');
// @NtOpenProcess := GetProcAddress(NtDllHandle,'NtOpenProcess');
@NtQuerySystemInformation := GetProcAddress(NtDllHandle,'NtQuerySystemInformation');
// @NtCreateSection := GetProcAddress(NtDllHandle,'NtCreateSection');
// @NtCreateToken := GetProcAddress(NtDllHandle,'NtCreateToken');
// @NtMapViewOfSection := GetProcAddress(NtDllHandle,'NtMapViewOfSection');
// @NtUnmapViewOfSection := GetProcAddress(NtDllHandle,'NtUnmapViewOfSection');
// @NtOpenFile := GetProcAddress(NtDllHandle,'NtOpenFile');
// @NtCreateFile := GetProcAddress(NtDllHandle,'NtCreateFile');
// @NtQueryObject := GetProcAddress(NtDllHandle,'NtQueryObject');
// @NtQueryInformationProcess := GetProcAddress(NtDllHandle,'NtQueryInformationProcess');
// @NtQueryInformationThread := GetProcAddress(NtDllHandle,'NtQueryInformationThread');
// @NtQueryInformationFile := GetProcAddress(NtDllHandle,'NtQueryInformationFile');
// @NtDuplicateObject := GetProcAddress(NtDllHandle,'NtDuplicateObject');
// @NtDeviceIoControlFile := GetProcAddress(NtDllHandle,'NtDeviceIoControlFile');
end;
end;
Result := NtDllHandle <> 0;
end;procedure FreeNtNativeAPIs;
begin
if NtDllHandle <> 0 then
begin
FreeLibrary(NtDllHandle);
NtDllHandle := 0;
end;
end;constructor TCnCpuId.Create;
begin
FCPUIds := TStringList.Create;
FCPUIdFormat := ifContinuous;
ReadCPUId; FTimer := TTimer.Create(nil);
FTimer.Interval := 1000;
FTimer.OnTimer := CpuUsageTimer;
FTimer.Enabled := True;
RefreshCPUUsages; if Win32Platform = VER_PLATFORM_WIN32_NT then // NT 下需要采样判断
FCPUUsageRead := False;
end;destructor TCnCpuId.Destroy;
begin
FTimer.Free;
FCPUIds.Free;
end;// 获取所有 CPU 的序列号
procedure TCnCpuId.ReadCPUId;
var
I: Integer;
Mask: Integer;
CurrProc: THandle;
SysInfo: TSystemInfo;
ProcessAffinityOld: Cardinal;
ProcessAffinity: Cardinal;
SystemAffinity: Cardinal; // 获取 CPU 序列号
function GetCnCPUID: string;
const
cnIFContinuous = '%.8x%.8x%.8x%.8x';
cnIFDashed = '%.8x-%.8x-%.8x-%.8x';
var
iEax,iEbx,iEcx,iEdx: Integer;
begin
asm
push ebx
push ecx
push edx
mov eax, $1
dw $A20F //CPUID
mov iEax, eax
mov iEbx, ebx
mov iEcx, ecx
mov iEdx, edx
pop edx
pop ecx
pop ebx
end;
if FCPUIdFormat=ifContinuous then
Result := Format(cnIFContinuous, [iEax, iEbx, iEcx, iEdx])
else
Result := Format(cnIFDashed, [iEax, iEbx, iEcx, iEdx])
end;
begin
FCPUCount := 0;
FCPUIds.Clear;
// 获取 CPU 个数
GetSystemInfo(SysInfo);
FCPUCount := SysInfo.dwNumberOfProcessors; // 获取所有 CPU 的序列号
Mask := $1;
CurrProc := GetCurrentProcess;
if not GetProcessAffinityMask(CurrProc, ProcessAffinityOld, SystemAffinity) then
Exit;
try
for I:=0 to FCpuCount-1 do
begin
ProcessAffinity := Mask shl I;
if not SetProcessAffinityMask(CurrProc, ProcessAffinity) then
Break; FCPUIds.Add(GetCnCPUID);
end;
finally
//恢复默认
SetProcessAffinityMask(CurrProc, ProcessAffinityOld);
end;
end;procedure TCnCpuId.SetCPUIdFormat(ACPUIdFormat: TCnCPUIdFormat);
begin
if FCPUIdFormat <> ACPUIdFormat then
begin
FCPUIdFormat := ACPUIdFormat;
ReadCPUId;
end;
end;// 获得单 CPU 系统 ID
function TCnCpuId.GetFirstCPUId: string;
begin
if FCPUIds.Count > 0 then
Result := FCPUIds.Strings[0];
end;// 得到第几个 CPU 的序列号
function TCnCpuId.GetCPUId(Index: Integer): string;
begin
Result := '';
// 保证 FCPUIds 索引的合法性
if (Index < 0) or (Index > FCPUIds.Count - 1) then
Exit; Result := FCPUIds.Strings[Index];
end;function TCnCpuId.GetAverageCPUUsage: Integer;
begin
if not FCPUUsageRead then
Result := -1
else
Result := FAverageCPUUsage;
end;
function TCnCpuId.GetCPUUsage(Index: Integer): Integer;
begin
if not FCPUUsageRead or (Index > FCPUCount - 1) then
Result := -1
else
Result := FCPUUsage[Index];
end;function TCnCpuId.GetFirstCPUUsage: Integer;
begin
if FCPUUsageRead and (FCPUCount > 0) then
Result := FCPUUsage[0]
else
Result := -1;
end;function TCnCpuId.RefreshCPUUsages: Cardinal;
var
CpuCnt: Cardinal;
I: integer;
Spt: Pointer;
Sbi: TSystemBasicInformation; dwType, cbData: Cardinal;
hOpen: HKEY;
Buffer: Cardinal;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
for I := 0 to FCPUCount - 1 do // 保存旧值
FLastCnt[I] := FCurCnt[I]; if NtQuerySystemInformation(SystemBasicInformation, @Sbi, SizeOf(Sbi), nil)
<> STATUS_SUCCESS then
CpuCnt := 1
else
CpuCnt := Sbi.NumberProcessors; Spt := AllocMem(CpuCnt * (SizeOf(TSystemProcessorTimes) + 4));
NtQuerySystemInformation(SystemProcessorTimes, Spt, CpuCnt * (SizeOf(TSystemProcessorTimes) + 4), @Result); for I := 0 to CpuCnt - 1 do
begin
with PSystemProcessorTimes(PChar(Spt) + I * (sizeof(TSystemProcessorTimes) + 4))^ do
FCurCnt[I] := IdleTime.QuadPart;
// 采样后计算
try
FCPUUsage[I] := Round((10000000 - (FCurCnt[I] - FLastCnt[I]) / (FTimer.Interval / 1000)) / 10000000 * 100);
except
FCPUUsage[I] := 0;
end;
end;
FreeMem(spt);
end
else
begin
if RegOpenKeyEx(HKEY_DYN_DATA,'PerfStats\StatData', 0, KEY_READ, hOpen) = ERROR_SUCCESS then
begin
cbData:=sizeof(Cardinal);
if RegQueryValueEx(hOpen, 'KERNEL\CPUUsage', nil, @dwType, PBYTE(@Buffer),
@cbData) = ERROR_SUCCESS then
FCPUUsage[0] := Buffer;
RegCloseKey(hOpen);
end
else
FCPUUsage[0] := -1;
end; FCPUUsageRead := True;
end;procedure TCnCpuId.CpuUsageTimer(Sender: TObject);
var
I: Integer;
begin
RefreshCPUUsages;
FAverageCPUUsage := 0;
for I := 0 to FCPUCount - 1 do
begin
if FCPUUsage[I] <> -1 then
FAverageCPUUsage := FAverageCPUUsage + FCPUUsage[I];
end; if FCPUCount > 0 then
FAverageCPUUsage := Round(FAverageCPUUsage / FCPUCount)
else
FAverageCPUUsage := -1;
end;initialization
GetNtNativeAPIs;finalization
FreeNtNativeAPIs;end.
这个是关键