private static OpenExistingResult OpenExistingWorker(string name, out EventWaitHandle?result) { #if TARGET_WINDOWS ArgumentException.ThrowIfNullOrEmpty(name); result = null; SafeWaitHandle myHandle = Interop.Kernel32.OpenEvent(AccessRights, false, name); if (myHandle.IsInvalid) { int errorCode = Marshal.GetLastPInvokeError(); myHandle.Dispose(); if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND || errorCode == Interop.Errors.ERROR_INVALID_NAME) { return(OpenExistingResult.NameNotFound); } if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND) { return(OpenExistingResult.PathNotFound); } if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE) { return(OpenExistingResult.NameInvalid); } throw Win32Marshal.GetExceptionForWin32Error(errorCode, name); } result = new EventWaitHandle(myHandle); return(OpenExistingResult.Success); #else throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); #endif }
internal static void CompleteInitialization(SafeCloseSocketAndEvent socketAndEventHandle) { SafeWaitHandle handle = socketAndEventHandle._waitHandle.GetSafeWaitHandle(); bool b = false; try { handle.DangerousAddRef(ref b); } catch { if (b) { handle.DangerousRelease(); socketAndEventHandle._waitHandle = null; b = false; } } finally { if (b) { handle.Dispose(); } } }
private void CreateSemaphoreCore(int initialCount, int maximumCount, string?name, out bool createdNew) { Debug.Assert(initialCount >= 0); Debug.Assert(maximumCount >= 1); Debug.Assert(initialCount <= maximumCount); #if TARGET_UNIX || TARGET_BROWSER if (name != null) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives); } #endif SafeWaitHandle myHandle = Interop.Kernel32.CreateSemaphoreEx(IntPtr.Zero, initialCount, maximumCount, name, 0, AccessRights); int errorCode = Marshal.GetLastPInvokeError(); if (myHandle.IsInvalid) { myHandle.Dispose(); if (!string.IsNullOrEmpty(name) && errorCode == Interop.Errors.ERROR_INVALID_HANDLE) { throw new WaitHandleCannotBeOpenedException( SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name)); } throw Win32Marshal.GetExceptionForLastWin32Error(); } createdNew = errorCode != Interop.Errors.ERROR_ALREADY_EXISTS; this.SafeWaitHandle = myHandle; }
internal static void CompleteInitialization(SafeCloseSocketAndEvent socketAndEventHandle) { SafeWaitHandle safeWaitHandle = socketAndEventHandle.waitHandle.SafeWaitHandle; bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { safeWaitHandle.DangerousAddRef(ref success); } catch { if (success) { safeWaitHandle.DangerousRelease(); socketAndEventHandle.waitHandle = null; success = false; } } finally { if (success) { safeWaitHandle.Dispose(); } } }
/// <summary>Gets or creates <see cref="Mutex" /> instance, allowing a <see cref="MutexSecurity" /> to be optionally specified to set it during the mutex creation.</summary> /// <param name="initiallyOwned"><see langword="true" /> to give the calling thread initial ownership of the named system mutex if the named system mutex is created as a result of this call; otherwise, <see langword="false" />.</param> /// <param name="name">The optional name of the system mutex. If this argument is set to <see langword="null" /> or <see cref="string.Empty" />, a local mutex is created.</param> /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local mutex is created; that is, when <paramref name="name" /> is <see langword="null" /> or <see cref="string.Empty" />. If <paramref name="name" /> has a valid non-empty value, this argument is set to <see langword="true" /> when the system mutex is created, or it is set to <see langword="false" /> if an existing system mutex is found with that name. This parameter is passed uninitialized.</param> /// <param name="mutexSecurity">The optional mutex access control security to apply.</param> /// <returns>An object that represents a system mutex, if named, or a local mutex, if nameless.</returns> /// <exception cref="ArgumentException">.NET Framework only: The length of the name exceeds the maximum limit.</exception> /// <exception cref="WaitHandleCannotBeOpenedException">A mutex handle with system-wide <paramref name="name" /> cannot be created. A mutex handle of a different type might have the same name.</exception> public static unsafe Mutex Create(bool initiallyOwned, string name, out bool createdNew, MutexSecurity mutexSecurity) { if (mutexSecurity == null) { return(new Mutex(initiallyOwned, name, out createdNew)); } uint mutexFlags = initiallyOwned ? Interop.Kernel32.CREATE_MUTEX_INITIAL_OWNER : 0; fixed(byte *pSecurityDescriptor = mutexSecurity.GetSecurityDescriptorBinaryForm()) { var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES { nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES), lpSecurityDescriptor = (IntPtr)pSecurityDescriptor }; SafeWaitHandle handle = Interop.Kernel32.CreateMutexEx( (IntPtr)(&secAttrs), name, mutexFlags, (uint)MutexRights.FullControl // Equivalent to MUTEX_ALL_ACCESS ); ValidateMutexHandle(handle, name, out createdNew); Mutex mutex = new Mutex(initiallyOwned); SafeWaitHandle old = mutex.SafeWaitHandle; mutex.SafeWaitHandle = handle; old.Dispose(); return(mutex); } }
public void Dispose() { if (_owner) { _hProcess.Dispose(); } }
protected virtual void Dispose(bool explicitDisposing) { if (!disposed) { // // This is only the case if the handle was never properly initialized // most likely a bug in the derived class // if (safe_wait_handle == null) { return; } lock (this){ if (disposed) { return; } disposed = true; if (safe_wait_handle != null) { safe_wait_handle.Dispose(); } } } }
/// <summary>Gets or creates an <see cref="Semaphore" /> instance, allowing a <see cref="SemaphoreSecurity " /> instance to be optionally specified to set it during the event creation.</summary> /// <param name="initialCount">The initial number of requests for the semaphore that can be satisfied concurrently.</param> /// <param name="maximumCount">The maximum number of requests for the semaphore that can be satisfied concurrently.</param> /// <param name="name">Optional argument to create a system semaphore. Set to <see langword="null" /> or <see cref="string.Empty" /> to create a local semaphore.</param> /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local semaphore is created; that is, when <paramref name="name" /> is <see langword="null" /> or <see cref="string.Empty" />. If <paramref name="name" /> has a valid, non-empty value, this argument is set to <see langword="true" /> when the system semaphore is created, or it is set to <see langword="false" /> if an existing system semaphore is found with that name. This parameter is passed uninitialized.</param> /// <param name="semaphoreSecurity">The optional semaphore access control security to apply.</param> /// <returns>An object that represents a system semaphore, if named, or a local semaphore, if nameless.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount" /> is a negative number. /// -or- /// <paramref name="maximumCount" /> is not a positive number.</exception> /// <exception cref="ArgumentException"><paramref name="initialCount" /> is greater than <paramref name="maximumCount" />.</exception> /// <exception cref="WaitHandleCannotBeOpenedException">A semaphore handle with the system-wide name '<paramref name="name" />' cannot be created. A semaphore handle of a different type might have the same name.</exception> public static unsafe Semaphore Create(int initialCount, int maximumCount, string?name, out bool createdNew, SemaphoreSecurity?semaphoreSecurity) { if (semaphoreSecurity == null) { return(new Semaphore(initialCount, maximumCount, name, out createdNew)); } if (initialCount < 0) { throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum); } if (maximumCount < 1) { throw new ArgumentOutOfRangeException(nameof(maximumCount), SR.ArgumentOutOfRange_NeedPosNum); } if (initialCount > maximumCount) { throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum); } fixed(byte *pSecurityDescriptor = semaphoreSecurity.GetSecurityDescriptorBinaryForm()) { var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES { nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES), lpSecurityDescriptor = (IntPtr)pSecurityDescriptor }; SafeWaitHandle handle = Interop.Kernel32.CreateSemaphoreEx( (IntPtr)(&secAttrs), initialCount, maximumCount, name, 0, // This parameter is reserved and must be 0. (uint)SemaphoreRights.FullControl // Equivalent to SEMAPHORE_ALL_ACCESS ); int errorCode = Marshal.GetLastPInvokeError(); if (handle.IsInvalid) { handle.Dispose(); if (!string.IsNullOrEmpty(name) && errorCode == Interop.Errors.ERROR_INVALID_HANDLE) { throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name)); } throw Win32Marshal.GetExceptionForLastWin32Error(); } createdNew = (errorCode != Interop.Errors.ERROR_ALREADY_EXISTS); return(CreateAndReplaceHandle(handle)); } }
internal static void CompleteInitialization(SafeCloseSocketAndEvent socketAndEventHandle) { SafeWaitHandle handle = socketAndEventHandle._waitHandle.GetSafeWaitHandle(); bool ignore = false; handle.DangerousAddRef(ref ignore); // TODO #3562: Investigate if this pattern is still correct. // Note that the handle still has a reference from the above DangerousAddRef. handle.Dispose(); }
/// <summary>Gets or creates an <see cref="Semaphore" /> instance, allowing a <see cref="SemaphoreSecurity " /> instance to be optionally specified to set it during the event creation.</summary> /// <param name="initialCount">The initial number of requests for the semaphore that can be satisfied concurrently.</param> /// <param name="maximumCount">The maximum number of requests for the semaphore that can be satisfied concurrently.</param> /// <param name="name">Optional argument to create a system semaphore. Set to <see langword="null" /> or <see cref="string.Empty" /> to create a local semaphore.</param> /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local semaphore is created; that is, when <paramref name="name" /> is <see langword="null" /> or <see cref="string.Empty" />. If <paramref name="name" /> has a valid, non-empty value, this argument is set to <see langword="true" /> when the system semaphore is created, or it is set to <see langword="false" /> if an existing system semaphore is found with that name. This parameter is passed uninitialized.</param> /// <param name="semaphoreSecurity">The optional semaphore access control security to apply.</param> /// <returns>An object that represents a system semaphore, if named, or a local semaphore, if nameless.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount" /> is a negative number. /// -or- /// <paramref name="maximumCount" /> is not a positive number.</exception> /// <exception cref="ArgumentException"><paramref name="initialCount" /> is greater than <paramref name="maximumCount" />.</exception> /// <exception cref="WaitHandleCannotBeOpenedException">A semaphore handle with the system-wide name '<paramref name="name" />' cannot be created. A semaphore handle of a different type might have the same name.</exception> public static unsafe Semaphore Create(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity) { if (semaphoreSecurity == null) { return(new Semaphore(initialCount, maximumCount, name, out createdNew)); } if (initialCount < 0) { throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum); } if (maximumCount < 1) { throw new ArgumentOutOfRangeException(nameof(maximumCount), SR.ArgumentOutOfRange_NeedPosNum); } if (initialCount > maximumCount) { throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum); } fixed(byte *pSecurityDescriptor = semaphoreSecurity.GetSecurityDescriptorBinaryForm()) { var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES { nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES), lpSecurityDescriptor = (IntPtr)pSecurityDescriptor }; SafeWaitHandle handle = Interop.Kernel32.CreateSemaphoreEx( (IntPtr)(&secAttrs), initialCount, maximumCount, name, 0, // This parameter is reserved and must be 0. (uint)SemaphoreRights.FullControl // Equivalent to SEMAPHORE_ALL_ACCESS ); ValidateHandle(handle, name, out createdNew); Semaphore semaphore = new Semaphore(initialCount, maximumCount); SafeWaitHandle old = semaphore.SafeWaitHandle; semaphore.SafeWaitHandle = handle; old.Dispose(); return(semaphore); } }
[Test] // bug #81529 public void Handle_Invalid() { AutoResetEvent are1 = new AutoResetEvent(false); SafeWaitHandle swh1 = are1.SafeWaitHandle; are1.Handle = (IntPtr)(-1); Assert.IsTrue(swh1 != are1.SafeWaitHandle, "#1"); Assert.IsFalse(swh1.IsClosed, "#2"); Assert.IsFalse(swh1.IsInvalid, "#3"); Assert.IsFalse(are1.SafeWaitHandle.IsClosed, "#4"); Assert.IsTrue(are1.SafeWaitHandle.IsInvalid, "#5"); are1.Close(); swh1.Dispose(); }
[Test] // bug #81529 public void SafeWaitHandle() { AutoResetEvent are1 = new AutoResetEvent(false); AutoResetEvent are2 = new AutoResetEvent(false); SafeWaitHandle swh1 = are1.SafeWaitHandle; SafeWaitHandle swh2 = are2.SafeWaitHandle; are1.SafeWaitHandle = are2.SafeWaitHandle; Assert.AreSame(are1.SafeWaitHandle, are2.SafeWaitHandle, "#1"); Assert.AreEqual(are1.Handle, are2.Handle, "#2"); Assert.IsFalse(are1.SafeWaitHandle.IsInvalid, "#3"); Assert.IsFalse(are1.SafeWaitHandle.IsClosed, "#4"); Assert.IsFalse(swh1.IsClosed, "#5"); Assert.IsFalse(swh1.IsInvalid, "#6"); swh1.Dispose(); are1.Close(); }
public static bool TryOpenExisting(string name, MutexRights rights, out Mutex result) { SafeWaitHandle myHandle = OpenMutex((uint)rights, false, name); result = null; if (myHandle.IsInvalid) { return(false); } result = new Mutex(initiallyOwned: false); SafeWaitHandle old = result.SafeWaitHandle; result.SafeWaitHandle = myHandle; old.Dispose(); return(true); }
private void Dispose(bool disposing) { if (disposed) { return; } disposed = true; GC.SuppressFinalize(this); if (IsCapturing) { Stop(); } positionEventHandle.Dispose(); positionEvent.Close(); terminated.Close(); }
/// <summary>Gets or creates an <see cref="EventWaitHandle" /> instance, allowing a <see cref="EventWaitHandleSecurity " /> instance to be optionally specified to set it during the event creation.</summary> /// <param name="initialState"><see langword="true" /> to set the initial state to signaled if the named event is created as a result of this call; <see langword="false" /> to set it to non-signaled.</param> /// <param name="mode">One of the enum values that determines whether the event resets automatically or manually.</param> /// <param name="name">The name, if the event is a system-wide synchronization event; otherwise, <see langword="null" /> or an empty string.</param> /// <param name="createdNew">When this method returns, this argument is always set to <see langword="true" /> if a local event is created; that is, when <paramref name="name" /> is <see langword="null" /> or <see cref="string.Empty" />. If <paramref name="name" /> has a valid, non-empty value, this argument is set to <see langword="true" /> when the system event is created, or it is set to <see langword="false" /> if an existing system event is found with that name. This parameter is passed uninitialized.</param> /// <param name="eventSecurity">The optional Windows access control security to apply.</param> /// <returns>An object that represents a system event wait handle, if named, or a local event wait handle, if nameless.</returns> /// <exception cref="ArgumentNullException">.NET Framework only: The <paramref name="name" /> length is beyond MAX_PATH (260 characters).</exception> /// <exception cref="ArgumentOutOfRangeException">The <paramref name="mode" /> enum value was out of legal range.</exception> /// <exception cref="DirectoryNotFoundException">Could not find a part of the path specified in <paramref name="name" />.</exception> /// <exception cref="WaitHandleCannotBeOpenedException">A system-wide synchronization event with the provided <paramref name="name" /> was not found. /// -or- /// An <see cref="EventWaitHandle" /> with system-wide name <paramref name="name" /> cannot be created. An <see cref="EventWaitHandle" /> of a different type might have the same name.</exception> /// <remarks>If a `name` is passed and the system event already exists, the existing event is returned. If `name` is `null` or <see cref="string.Empty" />, a new local event is always created.</remarks> public static unsafe EventWaitHandle Create(bool initialState, EventResetMode mode, string?name, out bool createdNew, EventWaitHandleSecurity?eventSecurity) { if (eventSecurity == null) { return(new EventWaitHandle(initialState, mode, name, out createdNew)); } if (mode != EventResetMode.AutoReset && mode != EventResetMode.ManualReset) { throw new ArgumentOutOfRangeException(nameof(mode)); } uint eventFlags = initialState ? Interop.Kernel32.CREATE_EVENT_INITIAL_SET : 0; if (mode == EventResetMode.ManualReset) { eventFlags |= Interop.Kernel32.CREATE_EVENT_MANUAL_RESET; } fixed(byte *pSecurityDescriptor = eventSecurity.GetSecurityDescriptorBinaryForm()) { var secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES { nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES), lpSecurityDescriptor = (IntPtr)pSecurityDescriptor }; SafeWaitHandle handle = Interop.Kernel32.CreateEventEx( (IntPtr)(&secAttrs), name, eventFlags, (uint)EventWaitHandleRights.FullControl); ValidateHandle(handle, name, out createdNew); EventWaitHandle ewh = new EventWaitHandle(initialState, mode); SafeWaitHandle old = ewh.SafeWaitHandle; ewh.SafeWaitHandle = handle; old.Dispose(); return(ewh); } }
public void Handle_Valid() { AutoResetEvent are1 = new AutoResetEvent(false); SafeWaitHandle swh1 = are1.SafeWaitHandle; Assert.IsFalse(swh1.IsClosed, "#1"); Assert.IsFalse(swh1.IsInvalid, "#2"); IntPtr dummyHandle = (IntPtr)2; are1.Handle = dummyHandle; Assert.AreEqual(are1.Handle, dummyHandle, "#3"); Assert.IsFalse(swh1.IsClosed, "#4"); Assert.IsFalse(swh1.IsClosed, "#5"); Assert.IsFalse(swh1.IsInvalid, "#6"); Assert.IsFalse(are1.SafeWaitHandle.IsClosed, "#7"); Assert.IsFalse(are1.SafeWaitHandle.IsInvalid, "#8"); are1.Close(); swh1.Dispose(); }
private static OpenExistingResult OpenExistingWorker(string name, out Mutex?result) { ArgumentException.ThrowIfNullOrEmpty(name); result = null; // To allow users to view & edit the ACL's, call OpenMutex // with parameters to allow us to view & edit the ACL. This will // fail if we don't have permission to view or edit the ACL's. // If that happens, ask for less permissions. SafeWaitHandle myHandle = Interop.Kernel32.OpenMutex(AccessRights, false, name); if (myHandle.IsInvalid) { int errorCode = Marshal.GetLastPInvokeError(); myHandle.Dispose(); #if TARGET_UNIX || TARGET_BROWSER if (errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE) { // On Unix, length validation is done by CoreCLR's PAL after converting to utf-8 throw new ArgumentException(SR.Argument_WaitHandleNameTooLong, nameof(name)); } #endif if (Interop.Errors.ERROR_FILE_NOT_FOUND == errorCode || Interop.Errors.ERROR_INVALID_NAME == errorCode) { return(OpenExistingResult.NameNotFound); } if (Interop.Errors.ERROR_PATH_NOT_FOUND == errorCode) { return(OpenExistingResult.PathNotFound); } if (Interop.Errors.ERROR_INVALID_HANDLE == errorCode) { return(OpenExistingResult.NameInvalid); } throw Win32Marshal.GetExceptionForWin32Error(errorCode, name); } result = new Mutex(myHandle); return(OpenExistingResult.Success); }
private IntPtr ExecuteFuntion(string module, string function, byte[] arguments, bool canWait = true) { SafeWaitHandle remoteThread = null; var argumentsAllocation = _memoryManager.Allocate( arguments.Length, MemoryProtectionType.ReadWrite, !canWait); if (argumentsAllocation.Address == IntPtr.Zero) { throw new Win32Exception("Failed to allocate memory in remote process."); } try { var processHandle = _process.SafeHandle; // Write the arguments buffer to our allocated address _memoryManager.WriteMemory(argumentsAllocation.Address.ToInt64(), arguments); // Execute the function call in a new thread remoteThread = ThreadHelper.CreateRemoteThread(processHandle, ThreadHelper.GetProcAddress(processHandle, module, function), argumentsAllocation.Address); if (canWait) { Interop.Kernel32.WaitForSingleObject( remoteThread, System.Threading.Timeout.Infinite); } return(argumentsAllocation.Address); } finally { remoteThread?.Dispose(); if (canWait) { _memoryManager.Deallocate(argumentsAllocation); } } }
private static OpenExistingResult OpenExistingWorker(string name, SemaphoreRights rights, out Semaphore?result) { ArgumentNullException.ThrowIfNull(name); if (name.Length == 0) { throw new ArgumentException(SR.Argument_EmptyName, nameof(name)); } result = null; SafeWaitHandle handle = Interop.Kernel32.OpenSemaphore((uint)rights, false, name); int errorCode = Marshal.GetLastPInvokeError(); if (handle.IsInvalid) { handle.Dispose(); return(errorCode switch { Interop.Errors.ERROR_FILE_NOT_FOUND or Interop.Errors.ERROR_INVALID_NAME => OpenExistingResult.NameNotFound, Interop.Errors.ERROR_PATH_NOT_FOUND => OpenExistingResult.PathNotFound, Interop.Errors.ERROR_INVALID_HANDLE => OpenExistingResult.NameInvalid, _ => throw Win32Marshal.GetExceptionForLastWin32Error() });
public ChildProcess(string FileName, string CommandLine, string Input) { JobHandle = CreateJobObject(IntPtr.Zero, IntPtr.Zero); if (JobHandle == null) { throw new Win32Exception(); } JOBOBJECT_EXTENDED_LIMIT_INFORMATION LimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); LimitInformation.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; int Length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr LimitInformationPtr = Marshal.AllocHGlobal(Length); Marshal.StructureToPtr(LimitInformation, LimitInformationPtr, false); if (SetInformationJobObject(JobHandle, JobObjectExtendedLimitInformation, LimitInformationPtr, Length) == 0) { throw new Win32Exception(); } SafeFileHandle StdInRead = null; SafeFileHandle StdOutWrite = null; SafeWaitHandle StdErrWrite = null; try { SECURITY_ATTRIBUTES SecurityAttributes = new SECURITY_ATTRIBUTES(); SecurityAttributes.bInheritHandle = 1; if (CreatePipe(out StdInRead, out StdInWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdInWrite, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (CreatePipe(out StdOutRead, out StdOutWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdOutRead, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (DuplicateHandle(GetCurrentProcess(), StdOutWrite, GetCurrentProcess(), out StdErrWrite, DUPLICATE_SAME_ACCESS, true, 0) == 0) { throw new Win32Exception(); } STARTUPINFO StartupInfo = new STARTUPINFO(); StartupInfo.cb = Marshal.SizeOf(StartupInfo); StartupInfo.hStdInput = StdInRead; StartupInfo.hStdOutput = StdOutWrite; StartupInfo.hStdError = StdErrWrite; StartupInfo.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION ProcessInfo = new PROCESS_INFORMATION(); try { if (CreateProcess(null, new StringBuilder("\"" + FileName + "\" " + CommandLine), IntPtr.Zero, IntPtr.Zero, true, CREATE_NO_WINDOW | CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB, new IntPtr(0), null, StartupInfo, ProcessInfo) == 0) { throw new Win32Exception(); } if (AssignProcessToJobObject(JobHandle, ProcessInfo.hProcess) == 0) { throw new Win32Exception(); } if (ResumeThread(ProcessInfo.hThread) == -1) { throw new Win32Exception(); } using (StreamWriter StdInWriter = new StreamWriter(new FileStream(StdInWrite, FileAccess.Write, 4096, false), Console.InputEncoding, 4096)) { if (!String.IsNullOrEmpty(Input)) { StdInWriter.WriteLine(Input); StdInWriter.Flush(); } } InnerStream = new FileStream(StdOutRead, FileAccess.Read, 4096, false); ReadStream = new StreamReader(InnerStream, Console.OutputEncoding); ProcessHandle = new SafeFileHandle(ProcessInfo.hProcess, true); } finally { if (ProcessInfo.hProcess != null && ProcessHandle == null) { CloseHandle(ProcessInfo.hProcess); } if (ProcessInfo.hThread != null) { CloseHandle(ProcessInfo.hThread); } } } finally { if (StdInRead != null) { StdInRead.Dispose(); StdInRead = null; } if (StdOutWrite != null) { StdOutWrite.Dispose(); StdOutWrite = null; } if (StdErrWrite != null) { StdErrWrite.Dispose(); StdErrWrite = null; } } }
public void Dispose() { InterruptWait(); _handle.Dispose(); }
public ChildProcess(string FileName, string WorkingDir, string CommandLine, string Input) { JobHandle = CreateJobObject(IntPtr.Zero, IntPtr.Zero); if (JobHandle == null) { throw new Win32Exception(); } JOBOBJECT_EXTENDED_LIMIT_INFORMATION LimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); LimitInformation.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; int Length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr LimitInformationPtr = Marshal.AllocHGlobal(Length); Marshal.StructureToPtr(LimitInformation, LimitInformationPtr, false); if (SetInformationJobObject(JobHandle, JobObjectExtendedLimitInformation, LimitInformationPtr, Length) == 0) { throw new Win32Exception(); } PROCESS_INFORMATION ProcessInfo = new PROCESS_INFORMATION(); try { lock (CreateProcessLock) { SafeFileHandle StdInRead = null; SafeFileHandle StdOutWrite = null; SafeWaitHandle StdErrWrite = null; try { SECURITY_ATTRIBUTES SecurityAttributes = new SECURITY_ATTRIBUTES(); SecurityAttributes.nLength = Marshal.SizeOf(SecurityAttributes); SecurityAttributes.bInheritHandle = 1; if (CreatePipe(out StdInRead, out StdInWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdInWrite, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (CreatePipe(out StdOutRead, out StdOutWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdOutRead, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (DuplicateHandle(GetCurrentProcess(), StdOutWrite, GetCurrentProcess(), out StdErrWrite, 0, true, DUPLICATE_SAME_ACCESS) == 0) { throw new Win32Exception(); } STARTUPINFO StartupInfo = new STARTUPINFO(); StartupInfo.cb = Marshal.SizeOf(StartupInfo); StartupInfo.hStdInput = StdInRead; StartupInfo.hStdOutput = StdOutWrite; StartupInfo.hStdError = StdErrWrite; StartupInfo.dwFlags = STARTF_USESTDHANDLES; if (CreateProcess(null, new StringBuilder("\"" + FileName + "\" " + CommandLine), IntPtr.Zero, IntPtr.Zero, true, CREATE_NO_WINDOW | CREATE_SUSPENDED, new IntPtr(0), WorkingDir, StartupInfo, ProcessInfo) == 0) { throw new Win32Exception(); } } finally { if (StdInRead != null) { StdInRead.Dispose(); StdInRead = null; } if (StdOutWrite != null) { StdOutWrite.Dispose(); StdOutWrite = null; } if (StdErrWrite != null) { StdErrWrite.Dispose(); StdErrWrite = null; } } } if (AssignProcessToJobObject(JobHandle, ProcessInfo.hProcess) == 0) { // Support for nested job objects was only addeed in Windows 8; prior to that, assigning processes to job objects would fail. Figure out if we're already in a job, and ignore the error if we are. int OriginalError = Marshal.GetLastWin32Error(); bool bProcessInJob; IsProcessInJob(GetCurrentProcess(), IntPtr.Zero, out bProcessInJob); if (!bProcessInJob) { throw new Win32Exception(OriginalError); } } if (ResumeThread(ProcessInfo.hThread) == -1) { throw new Win32Exception(); } using (StreamWriter StdInWriter = new StreamWriter(new FileStream(StdInWrite, FileAccess.Write, 4096, false), Console.InputEncoding, 4096)) { if (!String.IsNullOrEmpty(Input)) { StdInWriter.WriteLine(Input); StdInWriter.Flush(); } } InnerStream = new FileStream(StdOutRead, FileAccess.Read, 4096, false); ReadStream = new StreamReader(InnerStream, Console.OutputEncoding); ProcessHandle = new SafeFileHandle(ProcessInfo.hProcess, true); } finally { if (ProcessInfo.hProcess != null && ProcessHandle == null) { CloseHandle(ProcessInfo.hProcess); } if (ProcessInfo.hThread != null) { CloseHandle(ProcessInfo.hThread); } } }
private IntPtr ExecuteFuntion(string module, string function, byte[] arguments, bool canWait = true) { SafeWaitHandle hThread = null; using (var hProcess = GetProcessHandle(_processHandle.Id, Interop.Advapi32.ProcessOptions.PROCESS_CREATE_THREAD | Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION | Interop.Advapi32.ProcessOptions.PROCESS_VM_OPERATION | Interop.Advapi32.ProcessOptions.PROCESS_VM_READ | Interop.Advapi32.ProcessOptions.PROCESS_VM_WRITE)) { // Allocate space in the remote process for the DLL path. IntPtr remoteAllocAddr = Interop.Kernel32.VirtualAllocEx( hProcess, IntPtr.Zero, new UIntPtr((uint)arguments.Length), Interop.Kernel32.AllocationType.Commit | Interop.Kernel32.AllocationType.Reserve, Interop.Kernel32.MemoryProtection.ReadWrite); if (remoteAllocAddr == IntPtr.Zero) { throw new Win32Exception("Failed to allocate memory in remote process."); } try { // Write the DLL path to the allocated memory. bool result = Interop.Kernel32.WriteProcessMemory( hProcess, remoteAllocAddr, arguments, arguments.Length, out IntPtr bytesWritten); if (!result || bytesWritten.ToInt32() != arguments.Length) { throw new Win32Exception("Failed to allocate memory in remote process."); } // Create a thread in the process at LoadLibraryW and pass it the DLL path. hThread = Interop.Kernel32.CreateRemoteThread( hProcess, IntPtr.Zero, UIntPtr.Zero, GetWin32ProcAddress(module, function), remoteAllocAddr, 0, IntPtr.Zero); if (hThread.IsInvalid) { throw new Win32Exception("Failed to create thread in remote process."); } if (canWait) { const int infiniteWait = -1; Interop.Kernel32.WaitForSingleObject( hThread, infiniteWait); } return(remoteAllocAddr); } finally { hThread?.Dispose(); if (canWait) { Interop.Kernel32.VirtualFreeEx( hProcess, remoteAllocAddr, new UIntPtr(0), Interop.Kernel32.FreeType.Release); } } } }
public void Dispose() { _handle.Dispose(); }
/// <summary> /// Spawns a new managed process. /// </summary> /// <param name="FileName">Path to the executable to be run</param> /// <param name="CommandLine">Command line arguments for the process</param> /// <param name="WorkingDirectory">Working directory for the new process. May be null to use the current working directory.</param> /// <param name="Environment">Environment variables for the new process. May be null, in which case the current process' environment is inherited</param> /// <param name="Input">Text to be passed via stdin to the new process. May be null.</param> public ManagedProcess(string FileName, string CommandLine, string WorkingDirectory, IReadOnlyDictionary <string, string> Environment, string Input, ManagedProcessPriority Priority, ulong MemoryLimit) { // Create the job object that the child process will be added to JobHandle = CreateJobObject(IntPtr.Zero, IntPtr.Zero); if (JobHandle == null) { throw new Win32Exception(); } // Configure the job object to terminate the processes added to it when the handle is closed JOBOBJECT_EXTENDED_LIMIT_INFORMATION LimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); LimitInformation.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_PROCESS_MEMORY; LimitInformation.ProcessMemoryLimit = new UIntPtr(MemoryLimit); int Length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr LimitInformationPtr = Marshal.AllocHGlobal(Length); Marshal.StructureToPtr(LimitInformation, LimitInformationPtr, false); if (SetInformationJobObject(JobHandle, JobObjectExtendedLimitInformation, LimitInformationPtr, Length) == 0) { throw new Win32Exception(); } // Create the child process IntPtr EnvironmentBlock = IntPtr.Zero; SafeFileHandle StdInRead = null; SafeFileHandle StdOutWrite = null; SafeWaitHandle StdErrWrite = null; try { // Create stdin and stdout pipes for the child process. We'll close the handles for the child process' ends after it's been created. SECURITY_ATTRIBUTES SecurityAttributes = new SECURITY_ATTRIBUTES(); SecurityAttributes.bInheritHandle = 1; if (CreatePipe(out StdInRead, out StdInWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdInWrite, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (CreatePipe(out StdOutRead, out StdOutWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdOutRead, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (DuplicateHandle(GetCurrentProcess(), StdOutWrite, GetCurrentProcess(), out StdErrWrite, DUPLICATE_SAME_ACCESS, true, 0) == 0) { throw new Win32Exception(); } // Create the environment block for the child process, if necessary. if (Environment != null) { // The native format for the environment block is a sequence of null terminated strings with a final null terminator. List <byte> EnvironmentBytes = new List <byte>(); foreach (KeyValuePair <string, string> Pair in Environment) { EnvironmentBytes.AddRange(Encoding.UTF8.GetBytes(Pair.Key)); EnvironmentBytes.Add((byte)'='); EnvironmentBytes.AddRange(Encoding.UTF8.GetBytes(Pair.Value)); EnvironmentBytes.Add((byte)0); } EnvironmentBytes.Add((byte)0); // Allocate an unmanaged block of memory to store it. EnvironmentBlock = Marshal.AllocHGlobal(EnvironmentBytes.Count); Marshal.Copy(EnvironmentBytes.ToArray(), 0, EnvironmentBlock, EnvironmentBytes.Count); } // Set the startup parameters for the new process STARTUPINFO StartupInfo = new STARTUPINFO(); StartupInfo.cb = Marshal.SizeOf(StartupInfo); StartupInfo.hStdInput = StdInRead; StartupInfo.hStdOutput = StdOutWrite; StartupInfo.hStdError = StdErrWrite; StartupInfo.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION ProcessInfo = new PROCESS_INFORMATION(); try { // Get the flags to create the new process ProcessCreationFlags Flags = ProcessCreationFlags.CREATE_NO_WINDOW | ProcessCreationFlags.CREATE_SUSPENDED | ProcessCreationFlags.CREATE_BREAKAWAY_FROM_JOB; switch (Priority) { case ManagedProcessPriority.BelowNormal: Flags |= ProcessCreationFlags.BELOW_NORMAL_PRIORITY_CLASS; break; case ManagedProcessPriority.Normal: Flags |= ProcessCreationFlags.NORMAL_PRIORITY_CLASS; break; case ManagedProcessPriority.AboveNormal: Flags |= ProcessCreationFlags.ABOVE_NORMAL_PRIORITY_CLASS; break; } // Create the new process as suspended, so we can modify it before it starts executing (and potentially preempting us) if (CreateProcess(null, new StringBuilder("\"" + FileName + "\" " + CommandLine), IntPtr.Zero, IntPtr.Zero, true, Flags, EnvironmentBlock, WorkingDirectory, StartupInfo, ProcessInfo) == 0) { throw new Win32Exception(); } // Add it to our job object if (AssignProcessToJobObject(JobHandle, ProcessInfo.hProcess) == 0) { throw new Win32Exception(); } // Allow the thread to start running if (ResumeThread(ProcessInfo.hThread) == -1) { throw new Win32Exception(); } // If we have any input text, write it to stdin now using (StreamWriter StdInWriter = new StreamWriter(new FileStream(StdInWrite, FileAccess.Write, 4096, false), Console.InputEncoding, 4096)) { if (!String.IsNullOrEmpty(Input)) { StdInWriter.WriteLine(Input); StdInWriter.Flush(); } } // Create the stream objects for reading the process output InnerStream = new FileStream(StdOutRead, FileAccess.Read, 4096, false); ReadStream = new StreamReader(InnerStream, Console.OutputEncoding); // Wrap the process handle in a SafeFileHandle ProcessHandle = new SafeFileHandle(ProcessInfo.hProcess, true); } finally { if (ProcessInfo.hProcess != IntPtr.Zero && ProcessHandle == null) { CloseHandle(ProcessInfo.hProcess); } if (ProcessInfo.hThread != IntPtr.Zero) { CloseHandle(ProcessInfo.hThread); } } } finally { if (EnvironmentBlock != IntPtr.Zero) { Marshal.FreeHGlobal(EnvironmentBlock); EnvironmentBlock = IntPtr.Zero; } if (StdInRead != null) { StdInRead.Dispose(); StdInRead = null; } if (StdOutWrite != null) { StdOutWrite.Dispose(); StdOutWrite = null; } if (StdErrWrite != null) { StdErrWrite.Dispose(); StdErrWrite = null; } } }
private static int CreateMutexHandle(bool initiallyOwned, string name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) { bool flag = false; bool flag2 = false; bool flag3 = false; Label_0006: flag2 = false; flag3 = false; mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name); int num = Marshal.GetLastWin32Error(); if (!mutexHandle.IsInvalid || (num != 5)) { return(num); } RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { Thread.BeginThreadAffinity(); flag = true; } mutexHandle = Win32Native.OpenMutex(0x100001, false, name); if (!mutexHandle.IsInvalid) { num = 0xb7; if (Environment.IsW2k3) { SafeWaitHandle handle = Win32Native.OpenMutex(0x100001, false, name); if (!handle.IsInvalid) { RuntimeHelpers.PrepareConstrainedRegions(); try { uint num2 = 0; IntPtr ptr = mutexHandle.DangerousGetHandle(); IntPtr ptr2 = handle.DangerousGetHandle(); IntPtr[] handles = new IntPtr[] { ptr, ptr2 }; num2 = Win32Native.WaitForMultipleObjects(2, handles, true, 0); GC.KeepAlive(handles); if (num2 == uint.MaxValue) { if (Marshal.GetLastWin32Error() != 0x57) { mutexHandle.Dispose(); flag3 = true; } } else { flag2 = true; if ((num2 >= 0) && (num2 < 2)) { Win32Native.ReleaseMutex(mutexHandle); Win32Native.ReleaseMutex(handle); } else if ((num2 >= 0x80) && (num2 < 130)) { Win32Native.ReleaseMutex(mutexHandle); Win32Native.ReleaseMutex(handle); } mutexHandle.Dispose(); } goto Label_0166; } finally { handle.Dispose(); } } mutexHandle.Dispose(); flag3 = true; } } else { num = Marshal.GetLastWin32Error(); } } finally { if (flag) { Thread.EndThreadAffinity(); } } Label_0166: if ((flag2 || flag3) || (num == 2)) { goto Label_0006; } if (num == 0) { num = 0xb7; } return(num); }
/// <summary> /// Spawns a new managed process. /// </summary> /// <param name="Group">The managed process group to add to</param> /// <param name="FileName">Path to the executable to be run</param> /// <param name="CommandLine">Command line arguments for the process</param> /// <param name="WorkingDirectory">Working directory for the new process. May be null to use the current working directory.</param> /// <param name="Environment">Environment variables for the new process. May be null, in which case the current process' environment is inherited</param> /// <param name="Input">Text to be passed via stdin to the new process. May be null.</param> public ManagedProcess(ManagedProcessGroup Group, string FileName, string CommandLine, string WorkingDirectory, IReadOnlyDictionary <string, string> Environment, string Input, ManagedProcessPriority Priority) { // Create the child process IntPtr EnvironmentBlock = IntPtr.Zero; try { // Create the environment block for the child process, if necessary. if (Environment != null) { // The native format for the environment block is a sequence of null terminated strings with a final null terminator. List <byte> EnvironmentBytes = new List <byte>(); foreach (KeyValuePair <string, string> Pair in Environment) { EnvironmentBytes.AddRange(Encoding.UTF8.GetBytes(Pair.Key)); EnvironmentBytes.Add((byte)'='); EnvironmentBytes.AddRange(Encoding.UTF8.GetBytes(Pair.Value)); EnvironmentBytes.Add((byte)0); } EnvironmentBytes.Add((byte)0); // Allocate an unmanaged block of memory to store it. EnvironmentBlock = Marshal.AllocHGlobal(EnvironmentBytes.Count); Marshal.Copy(EnvironmentBytes.ToArray(), 0, EnvironmentBlock, EnvironmentBytes.Count); } PROCESS_INFORMATION ProcessInfo = new PROCESS_INFORMATION(); try { // Get the flags to create the new process ProcessCreationFlags Flags = ProcessCreationFlags.CREATE_NO_WINDOW | ProcessCreationFlags.CREATE_SUSPENDED; switch (Priority) { case ManagedProcessPriority.BelowNormal: Flags |= ProcessCreationFlags.BELOW_NORMAL_PRIORITY_CLASS; break; case ManagedProcessPriority.Normal: Flags |= ProcessCreationFlags.NORMAL_PRIORITY_CLASS; break; case ManagedProcessPriority.AboveNormal: Flags |= ProcessCreationFlags.ABOVE_NORMAL_PRIORITY_CLASS; break; } // Acquire a global lock before creating inheritable handles. If multiple threads create inheritable handles at the same time, and child processes will inherit them all. // Since we need to wait for output pipes to be closed (in order to consume all output), this can result in output reads not returning until all processes with the same // inherited handles are closed. lock (LockObject) { SafeFileHandle StdInRead = null; SafeFileHandle StdOutWrite = null; SafeWaitHandle StdErrWrite = null; try { // Create stdin and stdout pipes for the child process. We'll close the handles for the child process' ends after it's been created. SECURITY_ATTRIBUTES SecurityAttributes = new SECURITY_ATTRIBUTES(); SecurityAttributes.nLength = Marshal.SizeOf(SecurityAttributes); SecurityAttributes.bInheritHandle = 1; if (CreatePipe(out StdInRead, out StdInWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdInWrite, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (CreatePipe(out StdOutRead, out StdOutWrite, SecurityAttributes, 0) == 0 || SetHandleInformation(StdOutRead, HANDLE_FLAG_INHERIT, 0) == 0) { throw new Win32Exception(); } if (DuplicateHandle(GetCurrentProcess(), StdOutWrite, GetCurrentProcess(), out StdErrWrite, 0, true, DUPLICATE_SAME_ACCESS) == 0) { throw new Win32Exception(); } // Create the new process as suspended, so we can modify it before it starts executing (and potentially preempting us) STARTUPINFO StartupInfo = new STARTUPINFO(); StartupInfo.cb = Marshal.SizeOf(StartupInfo); StartupInfo.hStdInput = StdInRead; StartupInfo.hStdOutput = StdOutWrite; StartupInfo.hStdError = StdErrWrite; StartupInfo.dwFlags = STARTF_USESTDHANDLES; if (CreateProcess(null, new StringBuilder("\"" + FileName + "\" " + CommandLine), IntPtr.Zero, IntPtr.Zero, true, Flags, EnvironmentBlock, WorkingDirectory, StartupInfo, ProcessInfo) == 0) { throw new Win32Exception(); } } finally { // Close the write ends of the handle. We don't want any other process to be able to inherit these. if (StdInRead != null) { StdInRead.Dispose(); StdInRead = null; } if (StdOutWrite != null) { StdOutWrite.Dispose(); StdOutWrite = null; } if (StdErrWrite != null) { StdErrWrite.Dispose(); StdErrWrite = null; } } } // Add it to our job object if (AssignProcessToJobObject(Group.JobHandle, ProcessInfo.hProcess) == 0) { // Support for nested job objects was only addeed in Windows 8; prior to that, assigning processes to job objects would fail. Figure out if we're already in a job, and ignore the error if we are. int OriginalError = Marshal.GetLastWin32Error(); bool bProcessInJob; IsProcessInJob(GetCurrentProcess(), IntPtr.Zero, out bProcessInJob); if (!bProcessInJob) { throw new Win32Exception(OriginalError); } } // Allow the thread to start running if (ResumeThread(ProcessInfo.hThread) == -1) { throw new Win32Exception(); } // If we have any input text, write it to stdin now using (StreamWriter StdInWriter = new StreamWriter(new FileStream(StdInWrite, FileAccess.Write, 4096, false), Console.InputEncoding, 4096)) { if (!String.IsNullOrEmpty(Input)) { StdInWriter.WriteLine(Input); StdInWriter.Flush(); } } // Create the stream objects for reading the process output InnerStream = new FileStream(StdOutRead, FileAccess.Read, 4096, false); ReadStream = new StreamReader(InnerStream, Console.OutputEncoding); // Wrap the process handle in a SafeFileHandle ProcessHandle = new SafeFileHandle(ProcessInfo.hProcess, true); } finally { if (ProcessInfo.hProcess != IntPtr.Zero && ProcessHandle == null) { CloseHandle(ProcessInfo.hProcess); } if (ProcessInfo.hThread != IntPtr.Zero) { CloseHandle(ProcessInfo.hThread); } } } finally { if (EnvironmentBlock != IntPtr.Zero) { Marshal.FreeHGlobal(EnvironmentBlock); EnvironmentBlock = IntPtr.Zero; } } }
private void Dispose(bool disposing) { lock (_disposeLock) { if (!_isDisposed) { if (disposing) { // Dispose managed resources. // Dispose wait handles. if (_procSafeWaitHandle != null) { _procSafeWaitHandle.Dispose(); } // Abort monitor thread. if (_monitorThread != null) { _monitorThread.Abort(); } if (_consoleParams.IsAvailable) { // Close console window. unsafe { ConsoleParams *consoleParams = (ConsoleParams *)_consoleParams.Get(); if (consoleParams->ConsoleWindowHandle != IntPtr.Zero) { WinApi.SendMessage(consoleParams->ConsoleWindowHandle, WinApi.WM_CLOSE, IntPtr.Zero, IntPtr.Zero); } } } // Dispose shared memory objects. if (_consoleParams != null) { _consoleParams.Dispose(); } if (_consoleScreenInfo != null) { _consoleScreenInfo.Dispose(); } if (_consoleCursorInfo != null) { _consoleCursorInfo.Dispose(); } if (_consoleBufferInfo != null) { _consoleBufferInfo.Dispose(); } if (_consoleBuffer != null) { _consoleBuffer.Dispose(); } if (_consoleCopyInfo != null) { _consoleCopyInfo.Dispose(); } if (_consolePasteInfo != null) { _consolePasteInfo.Dispose(); } if (_consoleMouseEvent != null) { _consoleMouseEvent.Dispose(); } if (_consoleNewSizeInfo != null) { _consoleNewSizeInfo.Dispose(); } if (_consoleNewScrollPos != null) { _consoleNewScrollPos.Dispose(); } //// Kill console process. //if (_process != null) //{ // _process.Kill(); // _process.Dispose(); //} } // Dispose unmanaged resources. } _isDisposed = true; } }