@@ -231,6 +231,11 @@ fn main() {
231231 }
232232 } ;
233233
234+ #[ cfg( target_os = "windows" ) ]
235+ if let Err ( e) = assign_to_job_object ( & mut child) {
236+ eprintln ! ( "警告: 无法设置进程保护: {}" , e) ;
237+ }
238+
234239 let child_arc: Arc < Mutex < Option < GroupChild > > > = Arc :: new ( Mutex :: new ( None ) ) ;
235240 let child_for_handler = child_arc. clone ( ) ;
236241
@@ -561,3 +566,43 @@ fn copy_dir_recursive(src: &Path, dst: &Path) -> std::io::Result<()> {
561566 }
562567 Ok ( ( ) )
563568}
569+
570+ #[ cfg( target_os = "windows" ) ]
571+ fn assign_to_job_object ( child : & mut GroupChild ) -> std:: io:: Result < ( ) > {
572+ use std:: os:: windows:: io:: AsRawHandle ;
573+ use std:: ptr;
574+ use winapi:: um:: handleapi:: CloseHandle ;
575+ use winapi:: um:: jobapi2:: * ;
576+ use winapi:: um:: winnt:: * ;
577+
578+ unsafe {
579+ let job = CreateJobObjectW ( ptr:: null_mut ( ) , ptr:: null ( ) ) ;
580+ if job. is_null ( ) {
581+ return Err ( std:: io:: Error :: last_os_error ( ) ) ;
582+ }
583+
584+ let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION = std:: mem:: zeroed ( ) ;
585+ info. BasicLimitInformation . LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE ;
586+
587+ let result = SetInformationJobObject (
588+ job,
589+ JobObjectExtendedLimitInformation ,
590+ & mut info as * mut _ as * mut _ ,
591+ std:: mem:: size_of_val ( & info) as u32 ,
592+ ) ;
593+
594+ if result == 0 {
595+ CloseHandle ( job) ;
596+ return Err ( std:: io:: Error :: last_os_error ( ) ) ;
597+ }
598+
599+ let handle = child. inner ( ) . as_raw_handle ( ) as * mut winapi:: ctypes:: c_void ;
600+ if AssignProcessToJobObject ( job, handle) == 0 {
601+ CloseHandle ( job) ;
602+ return Err ( std:: io:: Error :: last_os_error ( ) ) ;
603+ }
604+
605+ let _ = job;
606+ Ok ( ( ) )
607+ }
608+ }
0 commit comments