使用方法: unit MainForm;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;type TJobMainForm = class(TForm) Timer1: TTimer; GroupBox1: TGroupBox; GroupBox2: TGroupBox; Label1: TLabel; Edit1: TEdit; Label2: TLabel; Edit2: TEdit; Label3: TLabel; Edit3: TEdit; Label4: TLabel; Edit4: TEdit; Label5: TLabel; Edit5: TEdit; Label6: TLabel; Edit6: TEdit; Label7: TLabel; Edit7: TEdit; Label8: TLabel; Edit8: TEdit; Label9: TLabel; Edit9: TEdit; Label10: TLabel; Edit10: TEdit; Edit11: TEdit; Label11: TLabel; RunCPUHog: TButton; RunMemoryHog: TButton; SetRestrictions: TButton; AssociateWithJob: TCheckBox; ValuesInHex: TCheckBox; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormShow(Sender: TObject); procedure RunCPUHogClick(Sender: TObject); procedure RunMemoryHogClick(Sender: TObject); procedure SetRestrictionsClick(Sender: TObject); private { Private declarations } JobObj : THandle; Function ExecuteProcess(EXE : String) : THandle; public { Public declarations } end;var JobMainForm: TJobMainForm;implementationuses Jobs;{$R *.dfm}procedure TJobMainForm.FormCreate(Sender: TObject); begin JobObj := CreateJobObject(nil,nil); If (JobObj = 0) Then ShowMessage(SysErrorMessage(GetLastError)); end;procedure TJobMainForm.FormDestroy(Sender: TObject); begin CloseHandle(JobObj); end;procedure TJobMainForm.Timer1Timer(Sender: TObject); Var Info : TJobObjectBasicAndIOAccountingInformation; Len : Cardinal; Function I2S32(I : Integer) : String; Begin If ValuesInHex.Checked Then Result := IntToHex(I,8) Else Result := IntToStr(I); End; Function I2S64(I : Int64) : String; Begin If ValuesInHex.Checked Then Result := IntToHex(I,16) Else Result := IntToStr(I); End;begin { retrieve basic and IO information about the job object } Win32Check(QueryInformationJobObject(JobObj, JobObjectBasicAndIoAccountingInformation,@Info,SizeOf(Info),@Len)); { show the results on screen } With Info do Begin Edit1.Text := I2S64(BasicInfo.TotalUserTime); Edit2.Text := I2S64(BasicInfo.TotalKernelTime); Edit3.Text := I2S64(BasicInfo.ThisPeriodTotalUserTime); Edit4.Text := I2S64(BasicInfo.ThisPeriodTotalKernelTime); Edit5.Text := I2S32(BasicInfo.TotalPageFaultCount); Edit6.Text := I2S32(BasicInfo.ActiveProcesses); Edit7.Text := I2S32(BasicInfo.TotalTerminatedProcesses); Edit8.Text := I2S64(IoInfo.ReadOperationCount); Edit9.Text := I2S64(IoInfo.WriteOperationCount); Edit10.Text := I2S64(IoInfo.ReadTransferCount); Edit11.Text := I2S64(IoInfo.WriteTransferCount); End; end;
procedure TJobMainForm.FormShow(Sender: TObject); begin Timer1Timer(nil); end;Function TJobMainForm.ExecuteProcess(EXE : String) : THandle; Var SI : TStartupInfo; PI : TProcessInformation;Begin Result := INVALID_HANDLE_VALUE; FillChar(SI,SizeOf(SI),0); SI.cb := SizeOf(SI); If CreateProcess(nil,PChar('.\'+EXE),nil,nil, False,0,nil,nil,SI,PI) Then Begin { close thread handle } CloseHandle(PI.hThread); Result := PI.hProcess; End Else ShowMessage('CreateProcess call failed: '+ SysErrorMessage(GetLastError)); End;procedure TJobMainForm.RunCPUHogClick(Sender: TObject); Var Proc : THandle; begin Proc := ExecuteProcess('cpuhog.exe'); If AssociateWithJob.Checked Then Win32Check(AssignProcessToJobObject(JobObj,Proc)); CloseHandle(Proc); end;procedure TJobMainForm.RunMemoryHogClick(Sender: TObject); Var Proc : THandle; begin Proc := ExecuteProcess('memoryhog.exe'); If AssociateWithJob.Checked Then Win32Check(AssignProcessToJobObject(JobObj,Proc)); CloseHandle(Proc); end;procedure TJobMainForm.SetRestrictionsClick(Sender: TObject); Const MegaByte = 1024*1024; Var Limits : TJobObjectExtendedLimitInformation; Function SecondsTo100NSTicks(Secs : Integer) : Int64; Begin { convert seconds to 100 nanosecond ticks (milli, micro, nano) } Result := Secs*1000*1000*10; End;begin { fill structure } FillChar(Limits,SizeOf(Limits),0); With Limits,BasicLimitInformation do Begin PerProcessUserTimeLimit := SecondsTo100NSTicks(10); PerJobUserTimeLimit := SecondsTo100NSTicks(20); ActiveProcessLimit := 5; ProcessMemoryLimit := 20*MegaByte; { set flags } LimitFlags := JOB_OBJECT_LIMIT_PROCESS_TIME Or JOB_OBJECT_LIMIT_JOB_TIME Or JOB_OBJECT_LIMIT_ACTIVE_PROCESS Or JOB_OBJECT_LIMIT_PROCESS_MEMORY; End; { enforce limits } Win32Check(SetInformationJobObject(JobObj,JobObjectExtendedLimitInformation, @Limits,SizeOf(Limits))); ShowMessage('Limits set!'#13#13+ 'User time per process: 10 seconds'#13+ 'User time per job: 20 seconds'#13+ 'Active process limit: 5 processes'#13+ 'Per process memory allocation limit: 20 MB'); SetRestrictions.Enabled := False; end;end.可以结帖给分了 一向对分数很感兴趣:)http://lysoft.7u7.net
To: ly_liuyang(Liu Yang)'memoryhog.exe' 'cpuhog.exe'这个两个文件是什么? 我这里没有。
他说你去MICSOFT工作去吧,哈哈
没办法控制把,,
关键字:Job对象
类 别:APICoDelphi.com版权所有,未经允许,不得进行任何形式转载 如果一个进程被分配给Job对象,Windows 2000就会收集关于进程的信息。如果达到某一极限(如内存量消耗等等),系统将中止它。看起来有点粗暴,但如果应用程序本来就像避免这种情况时,它会工作得很好。你也可以设定为让Windows 2000记录到日志,然后继续运行进程。示例程序在启动时创建一个核心job对象(在主窗体的OnCreate中),然后用timer组件不断地监视状态。你可以选择用十进制或者十六进制来显示统计数字。示例程序有三个按钮:Run CPUHog(运行CPUHog)、RUN MemoryHog(运行MemoryHog),Set Restrictions(设置限制)。前两个按钮用来执行上文谈及的程序,第三个实现预定义的限制。下面的部分,我将演示这一切是如何实现的。
begin
JobObj := CreateJobObject(nil,nil);
If (JobObj = 0) Then
ShowMessage(SysErrorMessage(GetLastError));
end;
...
Function CreateJobObject(lpJobAttributes :
PSecurityAttributes;
lpName : PAnsiChar) : THandle; StdCall;
External Kernel32 Name 'CreateJobObjectA';
如果调用成功,返回值是被创建对象的句柄。反之则返回0,我在程序中用一个错误提示框表示。注意代码是如何运用在SYSUTILS.PAS单元中声明的SysErrorMessage函数构造错误信息的。
Interface unit for Windows 2000 Job Objects.Translated from WinBase.h in the Platform SDK.
}interfaceUses Windows;Type
TJobObjectInfoClass = Cardinal; PJobObjectAssociateCompletionPort = ^TJobObjectAssociateCompletionPort;
TJobObjectAssociateCompletionPort = Record
CompletionKey : Pointer;
CompletionPort : THandle;
End; PJobObjectBasicLimitInformation = ^TJobObjectBasicLimitInformation;
TJobObjectBasicLimitInformation = Record
PerProcessUserTimeLimit : TLargeInteger;
PerJobUserTimeLimit : TLargeInteger;
LimitFlags : DWORD;
MinimumWorkingSetSize : DWORD;
MaximumWorkingSetSize : DWORD;
ActiveProcessLimit : DWORD;
Affinity : DWORD;
PriorityClass : DWORD;
SchedulingClass : DWORD;
End; PJobObjectBasicUIRestrictions = ^TJobObjectBasicUIRestrictions;
TJobObjectBasicUIRestrictions = Record
UIRestrictionsClass : DWORD;
End; PJobObjectEndOfJobTimeInformation = ^TJobObjectEndOfJobTimeInformation;
TJobObjectEndOfJobTimeInformation = Record
EndOfJobTimeAction : DWORD;
End; TIOCounters = Record { all fields should be actually unsigned int64's }
ReadOperationCount : Int64;
WriteOperationCount : Int64;
OtherOperationCount : Int64;
ReadTransferCount : Int64;
WriteTransferCount : Int64;
OtherTransferCount : Int64;
End; PJobObjectExtendedLimitInformation = ^TJobObjectExtendedLimitInformation;
TJobObjectExtendedLimitInformation = Record
BasicLimitInformation : TJobObjectBasicLimitInformation;
IoInfo : TIOCounters;
ProcessMemoryLimit : DWORD;
JobMemoryLimit : DWORD;
PeakProcessMemoryUsed : DWORD;
PeakJobMemoryUsed : DWORD;
End; PJobObjectSecurityLimitInformation = ^TJobObjectSecurityLimitInformation;
TJobObjectSecurityLimitInformation = Record
SecurityLimitFlags : DWORD;
JobToken : THandle;
SidsToDisable : PTokenGroups;
PrivilegesToDelete : PTokenPrivileges;
RestrictedSids : PTokenGroups;
End; PJobObjectBasicAccountingInformation = ^TJobObjectBasicAccountingInformation;
TJobObjectBasicAccountingInformation = Record
TotalUserTime : TLargeInteger;
TotalKernelTime : TLargeInteger;
ThisPeriodTotalUserTime : TLargeInteger;
ThisPeriodTotalKernelTime : TLargeInteger;
TotalPageFaultCount : DWORD;
TotalProcesses : DWORD;
ActiveProcesses : DWORD;
TotalTerminatedProcesses : DWORD;
End; PJobObjectBasicAndIOAccountingInformation = ^TJobObjectBasicAndIOAccountingInformation;
TJobObjectBasicAndIOAccountingInformation = Record
BasicInfo : TJobObjectBasicAccountingInformation;
IoInfo : TIOCounters;
End; PJobObjectBasicProcessIDList = ^TJobObjectBasicProcessIDList;
TJobObjectBasicProcessIDList = Record
NumberOfAssignedProcesses : DWORD;
NumberOfProcessIdsInList : DWORD;
ProcessIdList : Array[0..0] of ULONG;
End;Const
{ for TJobObjectInfoClass }
JobObjectBasicAccountingInformation = 1;
JobObjectBasicLimitInformation = 2;
JobObjectBasicProcessIdList = 3;
JobObjectBasicUIRestrictions = 4;
JobObjectSecurityLimitInformation = 5;
JobObjectEndOfJobTimeInformation = 6;
JobObjectAssociateCompletionPortInformation = 7;
JobObjectBasicAndIoAccountingInformation = 8;
JobObjectExtendedLimitInformation = 9;
MaxJobObjectInfoClass = 10; { miscellaneous constants }
JOB_OBJECT_ASSIGN_PROCESS = $0001;
JOB_OBJECT_SET_ATTRIBUTES = $0002;
JOB_OBJECT_QUERY = $0004;
JOB_OBJECT_TERMINATE = $0008;
JOB_OBJECT_SET_SECURITY_ATTRIBUTES = $0010;
JOB_OBJECT_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or
SYNCHRONIZE Or $1F;
JOB_OBJECT_POST_AT_END_OF_JOB = 1;
JOB_OBJECT_MSG_END_OF_JOB_TIME = 1;
JOB_OBJECT_MSG_END_OF_PROCESS_TIME = 2;
JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT = 3;
JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO = 4; { where's 5? }
JOB_OBJECT_MSG_NEW_PROCESS = 6;
JOB_OBJECT_MSG_EXIT_PROCESS = 7;
JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS = 8;
JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT = 9;
JOB_OBJECT_MSG_JOB_MEMORY_LIMIT = 10;
JOB_OBJECT_LIMIT_WORKINGSET = $00000001;
JOB_OBJECT_LIMIT_PROCESS_TIME = $00000002;
JOB_OBJECT_LIMIT_JOB_TIME = $00000004;
JOB_OBJECT_LIMIT_ACTIVE_PROCESS = $00000008;
JOB_OBJECT_LIMIT_AFFINITY = $00000010;
JOB_OBJECT_LIMIT_PRIORITY_CLASS = $00000020;
JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = $00000040;
JOB_OBJECT_LIMIT_SCHEDULING_CLASS = $00000080;
JOB_OBJECT_LIMIT_PROCESS_MEMORY = $00000100;
JOB_OBJECT_LIMIT_JOB_MEMORY = $00000200;
JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = $00000400;
JOB_OBJECT_LIMIT_BREAKAWAY_OK = $00000800;
JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = $00001000;
JOB_OBJECT_LIMIT_RESERVED1 = $00002000;
JOB_OBJECT_LIMIT_RESERVED2 = $00004000;
JOB_OBJECT_LIMIT_RESERVED3 = $00008000;
JOB_OBJECT_LIMIT_RESERVED4 = $00010000;
JOB_OBJECT_LIMIT_RESERVED5 = $00020000;
JOB_OBJECT_LIMIT_RESERVED6 = $00040000;
JOB_OBJECT_LIMIT_VALID_FLAGS = $0007FFFF;
JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS = $000000FF;
JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS = $00001FFF;
JOB_OBJECT_RESERVED_LIMIT_VALID_FLAGS = $0007FFFF;
JOB_OBJECT_UILIMIT_NONE = $00000000;
JOB_OBJECT_UILIMIT_HANDLES = $00000001;
JOB_OBJECT_UILIMIT_READCLIPBOARD = $00000002;
JOB_OBJECT_UILIMIT_WRITECLIPBOARD = $00000004;
JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS = $00000008;
JOB_OBJECT_UILIMIT_DISPLAYSETTINGS = $00000010;
JOB_OBJECT_UILIMIT_GLOBALATOMS = $00000020;
JOB_OBJECT_UILIMIT_DESKTOP = $00000040;
JOB_OBJECT_UILIMIT_EXITWINDOWS = $00000080;
JOB_OBJECT_UILIMIT_ALL = $000000FF;
JOB_OBJECT_UI_VALID_FLAGS = $000000FF;
JOB_OBJECT_SECURITY_NO_ADMIN = $00000001;
JOB_OBJECT_SECURITY_RESTRICTED_TOKEN = $00000002;
JOB_OBJECT_SECURITY_ONLY_TOKEN = $00000004;
JOB_OBJECT_SECURITY_FILTER_TOKENS = $00000008;
JOB_OBJECT_SECURITY_VALID_FLAGS = $0000000F;Function AssignProcessToJobObject(hJob,hProcess : THandle) : Bool; StdCall;
External Kernel32 Name 'AssignProcessToJobObject';Function CreateJobObject(lpJobAttributes : PSecurityAttributes;
lpName : PAnsiChar) : THandle; StdCall;
External Kernel32 Name 'CreateJobObjectA';Function OpenJobObject(dwDesiredAccess : DWORD; bInheritHandle : Bool;
lpName : PAnsiChar) : THandle; StdCall;
External Kernel32 Name 'OpenJobObjectA';Function QueryInformationJobObject(hJob : THandle;
JobObjectInformationClass : TJobObjectInfoClass;
lpJobObjectInformation : Pointer;
cbJobObjectInformationLength : DWORD;
lpReturnLength : PDWORD) : Bool; StdCall;
External Kernel32 Name 'QueryInformationJobObject';Function SetInformationJobObject(hJob : THandle;
JobObjectInformationClass : TJobObjectInfoClass;
lpJobObjectInformation : Pointer;
cbJobObjectInformationLength : DWORD) : Bool; StdCall;
External Kernel32 Name 'SetInformationJobObject';Function TerminateJobObject(hJob : THandle; uExitCode : UINT) : Bool; StdCall;
External Kernel32 Name 'TerminateJobObject';implementationend.
unit MainForm;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;type
TJobMainForm = class(TForm)
Timer1: TTimer;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Edit4: TEdit;
Label5: TLabel;
Edit5: TEdit;
Label6: TLabel;
Edit6: TEdit;
Label7: TLabel;
Edit7: TEdit;
Label8: TLabel;
Edit8: TEdit;
Label9: TLabel;
Edit9: TEdit;
Label10: TLabel;
Edit10: TEdit;
Edit11: TEdit;
Label11: TLabel;
RunCPUHog: TButton;
RunMemoryHog: TButton;
SetRestrictions: TButton;
AssociateWithJob: TCheckBox;
ValuesInHex: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure RunCPUHogClick(Sender: TObject);
procedure RunMemoryHogClick(Sender: TObject);
procedure SetRestrictionsClick(Sender: TObject);
private
{ Private declarations }
JobObj : THandle;
Function ExecuteProcess(EXE : String) : THandle;
public
{ Public declarations }
end;var
JobMainForm: TJobMainForm;implementationuses Jobs;{$R *.dfm}procedure TJobMainForm.FormCreate(Sender: TObject);
begin
JobObj := CreateJobObject(nil,nil);
If (JobObj = 0) Then ShowMessage(SysErrorMessage(GetLastError));
end;procedure TJobMainForm.FormDestroy(Sender: TObject);
begin
CloseHandle(JobObj);
end;procedure TJobMainForm.Timer1Timer(Sender: TObject);
Var
Info : TJobObjectBasicAndIOAccountingInformation;
Len : Cardinal; Function I2S32(I : Integer) : String;
Begin
If ValuesInHex.Checked Then Result := IntToHex(I,8)
Else Result := IntToStr(I);
End; Function I2S64(I : Int64) : String;
Begin
If ValuesInHex.Checked Then Result := IntToHex(I,16)
Else Result := IntToStr(I);
End;begin
{ retrieve basic and IO information about the job object }
Win32Check(QueryInformationJobObject(JobObj,
JobObjectBasicAndIoAccountingInformation,@Info,SizeOf(Info),@Len));
{ show the results on screen }
With Info do Begin
Edit1.Text := I2S64(BasicInfo.TotalUserTime);
Edit2.Text := I2S64(BasicInfo.TotalKernelTime);
Edit3.Text := I2S64(BasicInfo.ThisPeriodTotalUserTime);
Edit4.Text := I2S64(BasicInfo.ThisPeriodTotalKernelTime);
Edit5.Text := I2S32(BasicInfo.TotalPageFaultCount);
Edit6.Text := I2S32(BasicInfo.ActiveProcesses);
Edit7.Text := I2S32(BasicInfo.TotalTerminatedProcesses);
Edit8.Text := I2S64(IoInfo.ReadOperationCount);
Edit9.Text := I2S64(IoInfo.WriteOperationCount);
Edit10.Text := I2S64(IoInfo.ReadTransferCount);
Edit11.Text := I2S64(IoInfo.WriteTransferCount);
End;
end;
begin
Timer1Timer(nil);
end;Function TJobMainForm.ExecuteProcess(EXE : String) : THandle;
Var
SI : TStartupInfo;
PI : TProcessInformation;Begin
Result := INVALID_HANDLE_VALUE;
FillChar(SI,SizeOf(SI),0);
SI.cb := SizeOf(SI);
If CreateProcess(nil,PChar('.\'+EXE),nil,nil,
False,0,nil,nil,SI,PI) Then Begin
{ close thread handle }
CloseHandle(PI.hThread);
Result := PI.hProcess;
End
Else ShowMessage('CreateProcess call failed: '+
SysErrorMessage(GetLastError));
End;procedure TJobMainForm.RunCPUHogClick(Sender: TObject);
Var Proc : THandle;
begin
Proc := ExecuteProcess('cpuhog.exe');
If AssociateWithJob.Checked Then
Win32Check(AssignProcessToJobObject(JobObj,Proc));
CloseHandle(Proc);
end;procedure TJobMainForm.RunMemoryHogClick(Sender: TObject);
Var Proc : THandle;
begin
Proc := ExecuteProcess('memoryhog.exe');
If AssociateWithJob.Checked Then
Win32Check(AssignProcessToJobObject(JobObj,Proc));
CloseHandle(Proc);
end;procedure TJobMainForm.SetRestrictionsClick(Sender: TObject);
Const MegaByte = 1024*1024;
Var Limits : TJobObjectExtendedLimitInformation; Function SecondsTo100NSTicks(Secs : Integer) : Int64;
Begin
{ convert seconds to 100 nanosecond ticks (milli, micro, nano) }
Result := Secs*1000*1000*10;
End;begin
{ fill structure }
FillChar(Limits,SizeOf(Limits),0);
With Limits,BasicLimitInformation do Begin
PerProcessUserTimeLimit := SecondsTo100NSTicks(10);
PerJobUserTimeLimit := SecondsTo100NSTicks(20);
ActiveProcessLimit := 5;
ProcessMemoryLimit := 20*MegaByte;
{ set flags }
LimitFlags := JOB_OBJECT_LIMIT_PROCESS_TIME Or
JOB_OBJECT_LIMIT_JOB_TIME Or
JOB_OBJECT_LIMIT_ACTIVE_PROCESS Or
JOB_OBJECT_LIMIT_PROCESS_MEMORY;
End;
{ enforce limits }
Win32Check(SetInformationJobObject(JobObj,JobObjectExtendedLimitInformation,
@Limits,SizeOf(Limits)));
ShowMessage('Limits set!'#13#13+
'User time per process: 10 seconds'#13+
'User time per job: 20 seconds'#13+
'Active process limit: 5 processes'#13+
'Per process memory allocation limit: 20 MB');
SetRestrictions.Enabled := False;
end;end.可以结帖给分了
一向对分数很感兴趣:)http://lysoft.7u7.net
'cpuhog.exe'这个两个文件是什么?
我这里没有。