Delphi 如何仅使用作业\对象\基本\限制\信息调用SetInformationJobObject?

Delphi 如何仅使用作业\对象\基本\限制\信息调用SetInformationJobObject?,delphi,winapi,delphi-2010,Delphi,Winapi,Delphi 2010,我有作业API的基本翻译,如下所示: type TJobObjectInfoClass = ( JobObjectBasicLimitInformation = 2, JobObjectExtendedLimitInformation = 9 ); TJobObjectBasicLimitInformation = record PerProcessUserTimeLimit: TLargeInteger; PerJobUserTimeLimit:

我有作业API的基本翻译,如下所示:

type
  TJobObjectInfoClass = (
    JobObjectBasicLimitInformation = 2,
    JobObjectExtendedLimitInformation = 9
  );

  TJobObjectBasicLimitInformation = record
    PerProcessUserTimeLimit: TLargeInteger;
    PerJobUserTimeLimit: TLargeInteger;
    LimitFlags: DWORD;
    MinimumWorkingSetSize: DWORD;
    MaximumWorkingSetSize: DWORD;
    ActiveProcessLimit: DWORD;
    Affinity: DWORD;
    PriorityClass: DWORD;
    SchedulingClass: DWORD;
  end;

  TIOCounters = record
    ReadOperationCount: UInt64;
    WriteOperationCount: UInt64;
    OtherOperationCount: UInt64;
    ReadTransferCount: UInt64;
    WriteTransferCount: UInt64;
    OtherTransferCount: UInt64;
  end;

  TJobObjectExtendedLimitInformation = record
    BasicLimitInformation: TJobObjectBasicLimitInformation;
    IoInfo: TIOCounters;
    ProcessMemoryLimit: DWORD;
    JobMemoryLimit: DWORD;
    PeakProcessMemoryUsed: DWORD;
    PeakJobMemoryUsed: DWORD;
  end;

const
  CREATE_BREAKAWAY_FROM_JOB = $01000000;
  JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = $00002000;

function AssignProcessToJobObject(const hJob, hProcess: THandle): BOOL; stdcall;
external kernel32 name 'AssignProcessToJobObject';

function CreateJobObject(const lpJobAttributes: PSecurityAttributes;
  const lpName: PChar): THandle; stdcall;
external kernel32 name {$IFDEF UNICODE}'CreateJobObjectW'{$ELSE}'CreateJobObjectA'{$ENDIF};

function SetInformationJobObject(const hJob: THandle;
  const JobObjectInformationClass: TJobObjectInfoClass;
  const lpJobObjectInformation: Pointer;
  const cbJobObjectInformationLength: DWORD): BOOL; stdcall;
external kernel32 name 'SetInformationJobObject';
当我按如下方式使用它时,它工作得很好:

Job := CreateJobObject(nil, nil);
if Job = 0 then
  RaiseLastOSError;

ZeroMemory(@JELI, SizeOf(JELI));
JELI.BasicLimitInformation.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
Win32Check(SetInformationJobObject(
  Job, JobObjectExtendedLimitInformation, @JELI, SizeOf(JELI))
);
由于我只设置了
basiclitinformation
,因此我希望能够调用
SetInformationJobObject
,只需这样做:

ZeroMemory(@JBLI, SizeOf(JBLI));
JBLI.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
Win32Check(SetInformationJobObject(
  Job, JobObjectBasicLimitInformation, @JBLI, SizeOf(JBLI))
);
MSDN上的文档没有给我任何不支持的指示。那么为什么它会失败,代码为87(“参数不正确”)


我最好的猜测是,我的记录与Windows期望的结构不完全匹配,这意味着一些位位于错误的位置。然而,当它嵌入到另一个中时,它工作得很好。在这里,它是第一个字段,因此不太可能是填充造成的。

来自以下文档:

[
JOB\u OBJECT\u LIMIT\u KILL\u ON\u JOB\u CLOSE
]需要使用
JOBOBJECT\u EXTENDED\u LIMIT\u INFORMATION
结构。其
basiclitinformation
成员是
JOBOBJECT\u BASIC\u LIMIT\u INFORMATION
结构。”

extended
结构以一个
basic
结构开始,因此这两个结构至少部分兼容,这就是为什么不能得到随机结果的原因

这将给出正确的结果:

ZeroMemory(@JELI, SizeOf(JELI));
JELI.BasicLimitInformation.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
Win32Check(SetInformationJobObject(
  Job, JobObjectBasicLimitInformation, @JELI, SizeOf(JELI))
);

不是经常使用MSDN,并且忘记检查此特定标志的注释。这就是原因;谢谢!