private void AssociateWithJob(WindowsApi.PROCESS_INFORMATION processInformation, bool throwOnError) { if (_jobHandle == IntPtr.Zero) { lock (_jobHandleLock) { if (_jobHandle == IntPtr.Zero) { _jobHandle = WindowsApi.CreateJobObject(IntPtr.Zero, null); var basic = new WindowsApi.JOBOBJECT_BASIC_LIMIT_INFORMATION { LimitFlags = WindowsApi.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE }; var extended = new WindowsApi.JOBOBJECT_EXTENDED_LIMIT_INFORMATION { BasicLimitInformation = basic }; int length = Marshal.SizeOf(typeof(WindowsApi.JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr extendedPointer = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(extended, extendedPointer, false); if (!WindowsApi.SetInformationJobObject(_jobHandle, WindowsApi.JOBOBJECTINFOCLASS.ExtendedLimitInformation, extendedPointer, (uint)length)) { throw new TorSharpException($"Unable to set information on the job object. Error: {WindowsUtility.GetLastErrorMessage()}."); } } } } lock (_processIdsLock) { _processIds.Add(processInformation.dwProcessId); } if (!WindowsApi.AssignProcessToJobObject(_jobHandle, processInformation.hProcess) && throwOnError) { throw new TorSharpException($"Unable to assign the process to the job object. Error: {WindowsUtility.GetLastErrorMessage()}."); } }
public void Stop() { if (_jobHandle != IntPtr.Zero) { lock (_jobHandleLock) { if (_jobHandle != IntPtr.Zero) { // terminate the job if (!WindowsApi.TerminateJobObject(_jobHandle, 0)) { throw new TorSharpException($"Unable to terminate the job object. Error: {WindowsUtility.GetLastErrorMessage()}."); } // wait for all jobs to complete lock (_processIdsLock) { while (_processIds.Any()) { if (Process.GetProcesses().All(p => p.Id != _processIds[0])) { _processIds.RemoveAt(0); } } } _jobHandle = IntPtr.Zero; } } } }
public void Stop() { if (_jobHandle != IntPtr.Zero) { lock (_jobHandleLock) { if (_jobHandle != IntPtr.Zero) { // terminate the job if (!WindowsApi.TerminateJobObject(_jobHandle, 0)) { throw new TorSharpException($"Unable to terminate the job object. Error: {WindowsUtility.GetLastErrorMessage()}."); } // wait for all jobs to complete lock (_processIdsLock) { var firstAttempt = true; while (_processIds.Any()) { if (!firstAttempt) { Thread.Sleep(100); } firstAttempt = false; var allProcessIds = Process .GetProcesses() .Select(x => x.Id) .ToList(); _processIds.IntersectWith(allProcessIds); } } _jobHandle = IntPtr.Zero; } } } }