Stop console process using Ctrl+C.
https://msdn.microsoft.com/en-us/library/ms686016(VS.85).aspx
private void Button1_OnClick(object sender, RoutedEventArgs e)
{
var file = new FileInfo(@"C:\temp\video.mp4");
if (file.Exists)
{
file.Delete();
}
ct = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
var pInfo = new ProcessStartInfo("cmd.exe",
string.Format("/c {0} \"{1}\"", new object[] {"adb.bat", file.Name}));
pInfo.CreateNoWindow = true;
pInfo.UseShellExecute = false;
pInfo.RedirectStandardError = true;
pInfo.RedirectStandardOutput = true;
pInfo.RedirectStandardInput = true;
var p = Process.Start(pInfo);
ct.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(10));
try
{
if (p.HasExited)
{
Trace.WriteLine("terminated normally");
}
else
{
NativeMethods.StopProgram(p);
p.StandardInput.WriteLine(string.Format("Y"));
p.WaitForExit(1000);
}
outmsg = p.StandardOutput.ReadToEnd();
errmsg = p.StandardError.ReadToEnd();
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
Trace.WriteLine(outmsg);
Trace.WriteLine(errmsg);
return 1;
}, ct.Token, TaskCreationOptions.None, TaskScheduler.Default)
.ContinueWith(
r =>
{
TextBlock1.Text += outmsg;
TextBlock1.Text += errmsg;
var p = Process.Start(new ProcessStartInfo("cmd.exe", "/c pull.bat " + file.FullName));
p.WaitForExit();
var p2 = Process.Start(new ProcessStartInfo(file.FullName));
ct.Dispose();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
internal static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetConsoleCtrlHandler(
[In] [Optional] [MarshalAs(UnmanagedType.FunctionPtr)] HandlerRoutine HandlerRoutine,
[In] [MarshalAs(UnmanagedType.Bool)] bool Add);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
public static void StopProgram(Process proc)
{
//This does not require the console window to be visible.
if (AttachConsole((uint) proc.Id))
{
//Disable Ctrl-C handling for our program
SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
//Must wait here. If we don't and re-enable Ctrl-C
//handling below too fast, we might terminate ourselves.
proc.WaitForExit(2000);
FreeConsole();
//Re-enable Ctrl-C handling or any subsequently started
//programs will inherit the disabled state.
SetConsoleCtrlHandler(null, false);
}
}
// Enumerated type for the control messages sent to the handler routine
private enum CtrlTypes : uint
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
internal enum ControlSignalType : uint
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}
[return: MarshalAs(UnmanagedType.Bool)]
internal delegate bool HandlerRoutine([In] [MarshalAs(UnmanagedType.U4)] ControlSignalType dwCtrlType);
}
댓글
댓글 쓰기