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)
};
///