diff --git a/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj b/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj index 88b6940cee..e901ac9b42 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj +++ b/samples/ConPTY/MiniTerm/MiniTerm/MiniTerm.csproj @@ -45,7 +45,8 @@ - + + diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs new file mode 100644 index 0000000000..a1b5228fed --- /dev/null +++ b/samples/ConPTY/MiniTerm/MiniTerm/Processes/Process.cs @@ -0,0 +1,74 @@ +using System; +using System.Runtime.InteropServices; +using static MiniTerm.Native.ProcessApi; + +namespace MiniTerm +{ + /// + /// Represents an instance of a process. + /// + internal sealed class Process : IDisposable + { + public Process(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) + { + StartupInfo = startupInfo; + ProcessInfo = processInfo; + } + + public STARTUPINFOEX StartupInfo { get; } + public PROCESS_INFORMATION ProcessInfo { get; } + + #region IDisposable Support + + private bool disposedValue = false; // To detect redundant calls + + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // dispose managed state (managed objects). + } + + // dispose unmanaged state + + // Free the attribute list + if (StartupInfo.lpAttributeList != IntPtr.Zero) + { + DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); + Marshal.FreeHGlobal(StartupInfo.lpAttributeList); + } + + // Close process and thread handles + if (ProcessInfo.hProcess != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hProcess); + } + if (ProcessInfo.hThread != IntPtr.Zero) + { + CloseHandle(ProcessInfo.hThread); + } + + disposedValue = true; + } + } + + ~Process() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(false); + } + + // This code added to correctly implement the disposable pattern. + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + // use the following line if the finalizer is overridden above. + GC.SuppressFinalize(this); + } + + #endregion + } +} diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs b/samples/ConPTY/MiniTerm/MiniTerm/Processes/ProcessFactory.cs similarity index 65% rename from samples/ConPTY/MiniTerm/MiniTerm/Process.cs rename to samples/ConPTY/MiniTerm/MiniTerm/Processes/ProcessFactory.cs index 40a703f638..f54805ba34 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Process.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Processes/ProcessFactory.cs @@ -24,6 +24,8 @@ namespace MiniTerm private static STARTUPINFOEX ConfigureProcessThread(IntPtr hPC, IntPtr attributes) { + // this method implements the behavior described in https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session#preparing-for-creation-of-the-child-process + var lpSize = IntPtr.Zero; var success = InitializeProcThreadAttributeList( lpAttributeList: IntPtr.Zero, @@ -93,72 +95,4 @@ namespace MiniTerm return pInfo; } } - - /// - /// Represents an instance of a process - /// - internal sealed class Process : IDisposable - { - public Process(STARTUPINFOEX startupInfo, PROCESS_INFORMATION processInfo) - { - StartupInfo = startupInfo; - ProcessInfo = processInfo; - } - - public STARTUPINFOEX StartupInfo { get; } - public PROCESS_INFORMATION ProcessInfo { get; } - - #region IDisposable Support - - private bool disposedValue = false; // To detect redundant calls - - void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // dispose managed state (managed objects). - } - - // dispose unmanaged state - - // Free the attribute list - if (StartupInfo.lpAttributeList != IntPtr.Zero) - { - DeleteProcThreadAttributeList(StartupInfo.lpAttributeList); - Marshal.FreeHGlobal(StartupInfo.lpAttributeList); - } - - // Close process and thread handles - if (ProcessInfo.hProcess != IntPtr.Zero) - { - CloseHandle(ProcessInfo.hProcess); - } - if (ProcessInfo.hThread != IntPtr.Zero) - { - CloseHandle(ProcessInfo.hThread); - } - - disposedValue = true; - } - } - - ~Process() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(false); - } - - // This code added to correctly implement the disposable pattern. - public void Dispose() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(true); - // use the following line if the finalizer is overridden above. - GC.SuppressFinalize(this); - } - - #endregion - } } diff --git a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs index 2077fb4c8a..df4bb21734 100644 --- a/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs +++ b/samples/ConPTY/MiniTerm/MiniTerm/Terminal.cs @@ -112,10 +112,10 @@ namespace MiniTerm /// /// Get an AutoResetEvent that signals when the process exits /// - private static AutoResetEvent WaitForExit(ProcessFactory.Process process) => + private static AutoResetEvent WaitForExit(Process process) => new AutoResetEvent(false) { - SafeWaitHandle = new SafeWaitHandle(process.ProcessInfo.hProcess, false) + SafeWaitHandle = new SafeWaitHandle(process.ProcessInfo.hProcess, ownsHandle: false) }; ///