我正在努力将pinvoke'ing CreateJobObject和SetInformationJobObject的工作示例放在一起。通过各种谷歌搜索(包括俄语和中文帖子!)我拼凑了以下代码。我认为JOBOBJECT_BASIC_LIMIT_INFORMATION的定义根据平台(32/64位)而变化。CreateJobObject/AssignProcessToJobObject * 似乎 * 可以工作。SetInformationJobObject失败-错误为24或87。
Process myProcess // POPULATED SOMEWHERE ELSE
// Create Job & assign this process and another process to the job
IntPtr jobHandle = CreateJobObject( null , null );
AssignProcessToJobObject( jobHandle , myProcess.Handle );
AssignProcessToJobObject( jobHandle , Process.GetCurrentProcess().Handle );
// Ensure that killing one process kills the others
JOBOBJECT_BASIC_LIMIT_INFORMATION limits = new JOBOBJECT_BASIC_LIMIT_INFORMATION();
limits.LimitFlags = (short)LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
IntPtr pointerToJobLimitInfo = Marshal.AllocHGlobal( Marshal.SizeOf( limits ) );
Marshal.StructureToPtr( limits , pointerToJobLimitInfo , false );
SetInformationJobObject( job , JOBOBJECTINFOCLASS.JobObjectBasicLimitInformation , pionterToJobLimitInfo , ( uint )Marshal.SizeOf( limits ) )
...
[DllImport( "kernel32.dll" , EntryPoint = "CreateJobObjectW" , CharSet = CharSet.Unicode )]
public static extern IntPtr CreateJobObject( SecurityAttributes JobAttributes , string lpName );
public class SecurityAttributes
{
public int nLength; //Useless field = 0
public IntPtr pSecurityDescriptor; //хз))
public bool bInheritHandle; //Возможность наследования
public SecurityAttributes()
{
this.bInheritHandle = true;
this.nLength = 0;
this.pSecurityDescriptor = IntPtr.Zero;
}
}
[DllImport( "kernel32.dll" )]
static extern bool SetInformationJobObject( IntPtr hJob , JOBOBJECTINFOCLASS JobObjectInfoClass , IntPtr lpJobObjectInfo , uint cbJobObjectInfoLength );
public enum JOBOBJECTINFOCLASS
{
JobObjectAssociateCompletionPortInformation = 7 ,
JobObjectBasicLimitInformation = 2 ,
JobObjectBasicUIRestrictions = 4 ,
JobObjectEndOfJobTimeInformation = 6 ,
JobObjectExtendedLimitInformation = 9 ,
JobObjectSecurityLimitInformation = 5
}
[StructLayout( LayoutKind.Sequential )]
struct JOBOBJECT_BASIC_LIMIT_INFORMATION
{
public Int64 PerProcessUserTimeLimit;
public Int64 PerJobUserTimeLimit;
public Int16 LimitFlags;
public UIntPtr MinimumWorkingSetSize;
public UIntPtr MaximumWorkingSetSize;
public Int16 ActiveProcessLimit;
public Int64 Affinity;
public Int16 PriorityClass;
public Int16 SchedulingClass;
}
public enum LimitFlags
{
JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x00000008 ,
JOB_OBJECT_LIMIT_AFFINITY = 0x00000010 ,
JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x00000800 ,
JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x00000400 ,
JOB_OBJECT_LIMIT_JOB_MEMORY = 0x00000200 ,
JOB_OBJECT_LIMIT_JOB_TIME = 0x00000004 ,
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000 ,
JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = 0x00000040 ,
JOB_OBJECT_LIMIT_PRIORITY_CLASS = 0x00000020 ,
JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x00000100 ,
JOB_OBJECT_LIMIT_PROCESS_TIME = 0x00000002 ,
JOB_OBJECT_LIMIT_SCHEDULING_CLASS = 0x00000080 ,
JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000 ,
JOB_OBJECT_LIMIT_WORKINGSET = 0x00000001
}
[DllImport( "kernel32.dll" )]
[return: MarshalAs( UnmanagedType.Bool )]
static extern bool AssignProcessToJobObject( IntPtr hJob , IntPtr hProcess );
[StructLayout( LayoutKind.Sequential )]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
字符串
4条答案
按热度按时间ux6nzvsh1#
这可能有点晚,但仍然。
我尝试了这里的所有示例,但没有人同时在32位和64位模式下为我工作。最后,我需要自己检查所有签名并创建相应的PInvoke例程。我想,其他人会觉得这很有帮助。
免责声明:解决方案基于Matt Howells' answer。
字符串
8cdiaqws2#
改进 Alexandria 的答案,这里有一个使用
SafeHandle
的版本。这是一个CriticalFinalizerObject
,它使使用句柄更加安全。.NET API(如Process
类)始终使用SafeHandle
s和P/Invoke,而不是IntPtr
s。字符串
pbgvytdp3#
总而言之, Alexandria Yezutov提出的签名在x86和x64下都可以工作。Matt Howells签名使用了许多UInt 32,而UIntPtr应该被使用。我为CloseHandle使用了以下P/Invoke签名,看起来工作得很好:
字符串
以下内容必须添加到Mas发布的app.manifest中:
型
最后,当从Visual Studio启动时,这将不起作用(至少在Win 7下)。父进程必须从Windows资源管理器启动。
sczxawaw4#
有一篇文章使用了你正在尝试使用的API。也许你可以从中得到一些启示。
Kill child process when parent process is killed