最近在写一个很坑爹的工具,winform需要调用一个python写的工具。
我的方法是直接开个线程调用System.Diagnostics.Process启动一个cmd窗,然后往里面p.StandardInput.WriteLine(python ...)相关指令:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = false;
p.Start();//启动程序
p.StandardInput.WriteLine("set PATH=%PATH%;C:/Python27/;C:/Python27/Scripts;");
//向cmd窗口发送输入信息
p.StandardInput.WriteLine("python main.py" + "&exit");
p.StandardInput.AutoFlush = true;
不过发现这个屌工具老是卡死,很多bug,似乎是异常没有处理好。懒得改他的代码,于是老大让我去监视这个线程,发现超时没有响应就直接干掉他。。。
好吧,本来想根据这个process.Id杀掉这个线程,发现杀不掉。怀疑是这时候启动了python的缘故。最后没办法,只能去CTRL+C去关闭它了。
但是怎么去输入CTRL+C呢?
几番折腾,发现这个:
[DllImport("kernel32.dll")]
static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);
[DllImport("kernel32.dll")]
static extern bool AttachConsole(int dwProcessId);
AttachConsole(temp.process.Id);
SetConsoleCtrlHandler(IntPtr.Zero, true); //设置自己的ctrl+c处理,防止自己被终止
GenerateConsoleCtrlEvent(0, 0); // 发送ctrl+c(注意:这是向所有共享该console的进程发送)
Thread.Sleep(10);
SetConsoleCtrlHandler(IntPtr.Zero, false); //重置此参数
这样可以成功发送CTRL+C到cmd窗。。。