Skip to content

Commit

Permalink
actually catch process exits and allow them to be raised.
Browse files Browse the repository at this point in the history
  • Loading branch information
doubleyewdee committed Nov 23, 2018
1 parent 0929be7 commit 684f1be
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
38 changes: 38 additions & 0 deletions src/ConsoleBuffer/ConsoleWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace ConsoleBuffer
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;

Expand All @@ -17,6 +18,17 @@ public sealed class ConsoleWrapper : IDisposable, INotifyPropertyChanged
public short Width { get; set; }
public short Height { get; set; }

/// <summary>
/// True if the process is running.
/// </summary>
public bool Running { get; private set; }

/// <summary>
/// The exit code of the process once terminated.
/// </summary>
public uint ProcessExitCode { get; private set; }


/// <summary>
/// The handle from which we read data from the console.
/// </summary>
Expand Down Expand Up @@ -143,6 +155,32 @@ private void StartProcess()
{
ThrowForWin32Error(Marshal.GetLastWin32Error(), "Unable to start process.");
}

this.Running = true;
this.OnPropertyChanged("Running");

Task.Run(() =>
{
var ret = NativeMethods.WaitForSingleObject(this.processInfo.hProcess, uint.MaxValue);
if (ret != 0)
{
// XXX: do something smarter here.
Logger.Verbose($"Wait for process termination failed: {ret}");
return;
}
if (!NativeMethods.GetExitCodeProcess(this.processInfo.hProcess, out var exitCode))
{
Logger.Verbose($"Failed to get process exit code, errno={Marshal.GetLastWin32Error()}");
}
this.ProcessExitCode = exitCode;
this.Running = false;
this.OnPropertyChanged("Running");
// XXX: long-term I think we should have the presentation layer do this but let's dump it here for now
var msg = Encoding.UTF8.GetBytes($"\r\n[process terminated with code {exitCode}.]");
this.Buffer.Append(msg, msg.Length);
});
}

private void ReadConsoleTask()
Expand Down
16 changes: 12 additions & 4 deletions src/ConsoleBuffer/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ConsoleBuffer
namespace ConsoleBuffer
{
using Microsoft.Win32.SafeHandles;
using System;
Expand Down Expand Up @@ -97,7 +97,15 @@ internal static extern bool CreateProcess(string lpApplicationName, string lpCom

[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int ClosePseudoConsole(IntPtr hPC);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, IntPtr lpPipeAttributes, int nSize); }
}
internal static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, IntPtr lpPipeAttributes, int nSize);

[DllImport("kernel32.dll", SetLastError = true)]
internal static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);
}
}

0 comments on commit 684f1be

Please sign in to comment.