如果我使用Process.Kill()
,则该进程被终止。但是,我想终止它。
我尝试使用GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, Process.Id)
API,但没有成功。
如果我将False
设置为CreateNoWindow
标记,当我从键盘发送Ctrl + C时,程序会显示"Caught signal: 2; Terminating"
。所以它等待“2”信号终止。
我该怎么做?
答案 0 :(得分:1)
有一个解决方案。我会试着为你描述一下:
当您编写包装整个控制台的应用程序时 - 控制台由于某种原因无法接收控制代码(问题转到Microsoft),但控制台仍然可以接收这些事件。怎么样?来自外部应用程序。
这是cas.exe的代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleAppStopper
{
class cas
{
[STAThread]
static void Main( string[] args )
{
if (args.Length < 2)
{
Help ();
return;
}
int processId = int.Parse (args[0]);
ConsoleCtrlEvent CtrlEvent = (ConsoleCtrlEvent)int.Parse(args[1]);
FreeConsole ();
AttachConsole (processId);
GenerateConsoleCtrlEvent (CtrlEvent, 0);
}
static void Help()
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine ("Console Application Eventer(Stopper)");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine ("cas.exe ProcessId ControlEvent");
Console.WriteLine ("Events:");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine ("\tCTRL_C - 0");
Console.WriteLine ("\tCTRL_BREAK - 1");
Console.WriteLine ("\tCTRL_LOGOFF - 5");
Console.ResetColor ();
}
public enum ConsoleCtrlEvent
{
CTRL_C = 0, // From wincom.h
CTRL_BREAK = 1,
CTRL_CLOSE = 2,
CTRL_LOGOFF = 5,
CTRL_SHUTDOWN = 6
}
[DllImport ("kernel32.dll")]
static extern bool GenerateConsoleCtrlEvent( ConsoleCtrlEvent sigevent,
int dwProcessGroupId );
[DllImport ("kernel32.dll")]
static extern bool FreeConsole();
[DllImport ("kernel32.dll")]
static extern bool AttachConsole( int dwProcessId );
}
}
以及如何使用它:
public void SendConsoleEvent( ConsoleCtrlEvent ev )
{
if (!Running)
return;
try
{
String current_dir = System.Environment.CurrentDirectory;
String stopper = "cas.exe";
String args = pr.Id + " " + (int)ev;
CommandExecutor ex = new CommandExecutor (null, null);
ex.Start (current_dir, stopper, args);
// sometimes stop prevent CAS do work. just throw cas and forget about
//Timer.DelayCall (TimeSpan.FromSeconds (10), ex.Stop);
//ex.Stop ();
}
catch (Exception e)
{
Log ("SendConsoleEvent: " + e.ToString ());
}
}
这里,CommandExecutor
是我围绕Process的线程包装器。
pr.Id是以前使用Process Console启动的ID(我们需要发送CTRL_C或其他事件