const
SystemBasicInformation = 0;
SystemPerformanceInformation = 2;
SystemTimeInformation = 3;
type
TPDWord = ^DWORD;
TSystem_Basic_Information = packed record
dwUnknown1: DWORD;
uKeMaximumIncrement: ULONG;
uPageSize: ULONG;
uMmNumberOfPhysicalPages: ULONG;
uMmLowestPhysicalPage: ULONG;
uMmHighestPhysicalPage: ULONG;
uAllocationGranularity: ULONG;
pLowestUserAddress: Pointer;
pMmHighestUserAddress: Pointer;
uKeActiveProcessors: ULONG;
bKeNumberProcessors: byte;
bUnknown2: byte;
wUnknown3: word;
end;
type
TSystem_Performance_Information = packed record
liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}
dwSpare: array[0..75] of DWORD;
end;
type
TSystem_Time_Information = packed record
liKeBootTime: LARGE_INTEGER;
liKeSystemTime: LARGE_INTEGER;
liExpTimeZoneBias: LARGE_INTEGER;
uCurrentTimeZoneId: ULONG;
dwReserved: DWORD;
end;
var
NtQuerySystemInformation: function(infoClass: DWORD;
buffer: Pointer;
bufSize: DWORD;
returnSize: TPDword): DWORD; stdcall = nil;
liOldIdleTime: LARGE_INTEGER = ();
liOldSystemTime: LARGE_INTEGER = ();
function Li2Double(x: LARGE_INTEGER): Double;
begin
Result := x.HighPart * 4.294967296E9 + x.LowPart
end;
procedure GetCPUUsage;
var
SysBaseInfo: TSystem_Basic_Information;
SysPerfInfo: TSystem_Performance_Information;
SysTimeInfo: TSystem_Time_Information;
status: Longint; {long}
dbSystemTime: Double;
dbIdleTime: Double;
bLoopAborted: boolean;
begin
if @NtQuerySystemInformation = nil then
NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'),
'NtQuerySystemInformation');
// get number of processors in the system
status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo,
SizeOf(SysBaseInfo), nil);
if status <> 0 then
Exit;
bLoopAborted := False;
while not bLoopAborted do
begin
// get new system time
status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo,
SizeOf(SysTimeInfo), 0);
if status <> 0 then
Exit;
// get new CPU's idle time
status := NtQuerySystemInformation(SystemPerformanceInformation,
@SysPerfInfo, SizeOf(SysPerfInfo), nil);
if status <> 0 then
Exit;
// if it's a first call - skip it
if (liOldIdleTime.QuadPart <> 0) then
begin
// CurrentValue = NewValue - OldValue
dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) -
Li2Double(liOldIdleTime);
dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) -
Li2Double(liOldSystemTime);
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime := dbIdleTime / dbSystemTime;
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors
+ 0.5;
// Show Percentage
Form1.Label1.Caption := FormatFloat('CPU Usage: 0.0 %', dbIdleTime);
Application.ProcessMessages;
// Abort if user pressed ESC or Application is terminated
//bLoopAborted := (GetKeyState(VK_ESCAPE) and 128 = 128) or
//Application.Terminated;
if dbIdleTime > 0 then
begin
bLoopAborted:= True;
end;
end;
// store new CPU's idle and system time
liOldIdleTime := SysPerfInfo.liIdleTime;
liOldSystemTime := SysTimeInfo.liKeSystemTime;
// wait one second
//Sleep(1000);
end;
end;
Создание и работа с DLL
Код:
Создал длл и что дальше ?
[color=red]Для оформления кода используй теги. Модератор.[/color]
Никогда не работал с 1С, но насколько я понимаю, то 1С при загрузке DLL должна вызывать в этой DLL какую-то функцию, например DLLStartup. Если это так, то нужно экспортировать в DLL'ке эту функцию и в ней получать загрузку ЦП и возвращать полученное значение в 1С.
Цитата: Zbyszek
Никогда не работал с 1С, но насколько я понимаю, то 1С при загрузке DLL должна вызывать в этой DLL какую-то функцию, например DLLStartup. Если это так, то нужно экспортировать в DLL'ке эту функцию и в ней получать загрузку ЦП и возвращать полученное значение в 1С.
Именно... только как експортировать мне ее...
[QUOTE="Delphi Help"]When you are converting a project into a DLL, you need to make the following changes to the project file:
1. Change the reserved word program in the first line of the file to library.
2. Remove the Forms unit from the project's uses clause.
3. Remove all lines of code between the begin and end at the bottom of the file.
4. Below the uses clause, and before the begin…end block, add the reserved word exports, followed by the names of the interface routines and a semicolon.
Delphi will not create the list of interface routines to be exported.
After these modifications, when you compile the project, it produces a DLL instead of an application. Applications can now call the DLL to open the wrapped dialog box.[/QUOTE]
Код:
library CPUUsage;
uses Windows;
const
SystemBasicInformation = 0;
SystemPerformanceInformation = 2;
SystemTimeInformation = 3;
type
TPDWord = ^DWORD;
TSystem_Basic_Information = packed record
dwUnknown1: DWORD;
uKeMaximumIncrement: ULONG;
uPageSize: ULONG;
uMmNumberOfPhysicalPages: ULONG;
uMmLowestPhysicalPage: ULONG;
uMmHighestPhysicalPage: ULONG;
uAllocationGranularity: ULONG;
pLowestUserAddress: Pointer;
pMmHighestUserAddress: Pointer;
uKeActiveProcessors: ULONG;
bKeNumberProcessors: byte;
bUnknown2: byte;
wUnknown3: word;
end;
TSystem_Performance_Information = packed record
liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}
dwSpare: array[0..75] of DWORD;
end;
TSystem_Time_Information = packed record
liKeBootTime: LARGE_INTEGER;
liKeSystemTime: LARGE_INTEGER;
liExpTimeZoneBias: LARGE_INTEGER;
uCurrentTimeZoneId: ULONG;
dwReserved: DWORD;
end;
var
NtQuerySystemInformation: function(infoClass: DWORD;
buffer: Pointer;
bufSize: DWORD;
returnSize: TPDword): DWORD; stdcall = nil;
liOldIdleTime: LARGE_INTEGER = ();
liOldSystemTime: LARGE_INTEGER = ();
function Li2Double(x: LARGE_INTEGER): Double;
begin
Result := x.HighPart * 4.294967296E9 + x.LowPart
end;
function GetCPUUsage: Double;
var
SysBaseInfo: TSystem_Basic_Information;
SysPerfInfo: TSystem_Performance_Information;
SysTimeInfo: TSystem_Time_Information;
status: Longint; {long}
dbSystemTime: Double;
dbIdleTime: Double;
bLoopAborted: boolean;
begin
if @NtQuerySystemInformation = nil then
NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'), 'NtQuerySystemInformation');
// get number of processors in the system
status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo, SizeOf(SysBaseInfo), nil);
if status <> 0 then
begin
Result:=-1;
Exit;
end;
bLoopAborted := False;
while not bLoopAborted do
begin
// get new system time
status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo, SizeOf(SysTimeInfo), 0);
if status <> 0 then
begin
Result:=-1;
Exit;
end;
// get new CPU's idle time
status := NtQuerySystemInformation(SystemPerformanceInformation, @SysPerfInfo, SizeOf(SysPerfInfo), nil);
if status <> 0 then
begin
Result:=-1;
Exit;
end;
// if it's a first call - skip it
if (liOldIdleTime.QuadPart <> 0) then
begin
// CurrentValue = NewValue - OldValue
dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime := dbIdleTime / dbSystemTime;
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;
if dbIdleTime > 0 then
begin
bLoopAborted:= True;
end;
end;
liOldIdleTime := SysPerfInfo.liIdleTime;
liOldSystemTime := SysTimeInfo.liKeSystemTime;
end;
Result:=dbIdleTime;
end;
exports
GetCPUUsage;
end.
uses Windows;
const
SystemBasicInformation = 0;
SystemPerformanceInformation = 2;
SystemTimeInformation = 3;
type
TPDWord = ^DWORD;
TSystem_Basic_Information = packed record
dwUnknown1: DWORD;
uKeMaximumIncrement: ULONG;
uPageSize: ULONG;
uMmNumberOfPhysicalPages: ULONG;
uMmLowestPhysicalPage: ULONG;
uMmHighestPhysicalPage: ULONG;
uAllocationGranularity: ULONG;
pLowestUserAddress: Pointer;
pMmHighestUserAddress: Pointer;
uKeActiveProcessors: ULONG;
bKeNumberProcessors: byte;
bUnknown2: byte;
wUnknown3: word;
end;
TSystem_Performance_Information = packed record
liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}
dwSpare: array[0..75] of DWORD;
end;
TSystem_Time_Information = packed record
liKeBootTime: LARGE_INTEGER;
liKeSystemTime: LARGE_INTEGER;
liExpTimeZoneBias: LARGE_INTEGER;
uCurrentTimeZoneId: ULONG;
dwReserved: DWORD;
end;
var
NtQuerySystemInformation: function(infoClass: DWORD;
buffer: Pointer;
bufSize: DWORD;
returnSize: TPDword): DWORD; stdcall = nil;
liOldIdleTime: LARGE_INTEGER = ();
liOldSystemTime: LARGE_INTEGER = ();
function Li2Double(x: LARGE_INTEGER): Double;
begin
Result := x.HighPart * 4.294967296E9 + x.LowPart
end;
function GetCPUUsage: Double;
var
SysBaseInfo: TSystem_Basic_Information;
SysPerfInfo: TSystem_Performance_Information;
SysTimeInfo: TSystem_Time_Information;
status: Longint; {long}
dbSystemTime: Double;
dbIdleTime: Double;
bLoopAborted: boolean;
begin
if @NtQuerySystemInformation = nil then
NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'), 'NtQuerySystemInformation');
// get number of processors in the system
status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo, SizeOf(SysBaseInfo), nil);
if status <> 0 then
begin
Result:=-1;
Exit;
end;
bLoopAborted := False;
while not bLoopAborted do
begin
// get new system time
status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo, SizeOf(SysTimeInfo), 0);
if status <> 0 then
begin
Result:=-1;
Exit;
end;
// get new CPU's idle time
status := NtQuerySystemInformation(SystemPerformanceInformation, @SysPerfInfo, SizeOf(SysPerfInfo), nil);
if status <> 0 then
begin
Result:=-1;
Exit;
end;
// if it's a first call - skip it
if (liOldIdleTime.QuadPart <> 0) then
begin
// CurrentValue = NewValue - OldValue
dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime := dbIdleTime / dbSystemTime;
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;
if dbIdleTime > 0 then
begin
bLoopAborted:= True;
end;
end;
liOldIdleTime := SysPerfInfo.liIdleTime;
liOldSystemTime := SysTimeInfo.liKeSystemTime;
end;
Result:=dbIdleTime;
end;
exports
GetCPUUsage;
end.
Цитата: makbeth
// get number of processors in the system
надо добавить
Код:
if @NtQuerySystemInformation = nil then
begin
Result := -1;
Exit;
end;
begin
Result := -1;
Exit;
end;
Иначе при запуске не на NT-системах поведение функции непредсказуемо и скорее всего приведёт к AV.
Цитата: Freeman
Перед
надо добавить
Иначе при запуске не на NT-системах поведение функции непредсказуемо и скорее всего приведёт к AV.
надо добавить
Код:
if @NtQuerySystemInformation = nil then
begin
Result := -1;
Exit;
end;
begin
Result := -1;
Exit;
end;
Точно.
Ну, в общем, я сильно в код не вникал - просто перенес из того, что есть.
Нашёл у себя вот такую штуку - получает загрузку ЦП и на Win 9х.