이 주제에 대해 조사를 해봤는데 예상보다 더 인기가 많았습니다. KindDragon의 답변은 핵심 포인트 중 하나였습니다.
나는 주제에 대한 더 긴 블로그 게시물 을 작성하고 작동하는 데모 프로그램을 만들었습니다.이 프로그램은 이러한 유형의 시스템을 사용하여 몇 가지 멋진 방식으로 명령 줄 응용 프로그램을 닫는 것을 보여줍니다. 그 게시물은 또한 내가 연구에 사용한 외부 링크를 나열합니다.
간단히 말해, 이러한 데모 프로그램은 다음을 수행합니다.
- .Net을 사용하여 보이는 창으로 프로그램을 시작하고, pinvoke로 숨기기, 6 초 동안 실행, pinvoke로 표시, .Net으로 중지.
- .Net을 사용하여 창없이 프로그램을 시작하고 6 초 동안 실행 한 다음 콘솔을 연결하고 ConsoleCtrlEvent를 실행하여 중지합니다.
편집 : 현재 코드에 관심이있는 사람들을위한 KindDragon의 수정 된 솔루션입니다. 첫 번째 프로그램을 중지 한 후 다른 프로그램을 시작하려는 경우 Ctrl-C 처리를 다시 활성화해야합니다. 그렇지 않으면 다음 프로세스가 부모의 비활성화 된 상태를 상속하고 Ctrl-C에 응답하지 않습니다.
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
delegate bool ConsoleCtrlDelegate(CtrlTypes CtrlType);
enum CtrlTypes : uint
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
public void StopProgram(Process proc)
{
if (AttachConsole((uint)proc.Id))
{
SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
FreeConsole();
proc.WaitForExit(2000);
SetConsoleCtrlHandler(null, false);
}
}
또한 AttachConsole()
전송 된 신호가 실패 할 경우 비상 솔루션을 계획 하십시오.
if (!proc.HasExited)
{
try
{
proc.Kill();
}
catch (InvalidOperationException e){}
}
jstack
이 특정 문제에 대해 대신 안정적으로 사용할 수있는 것으로 보입니다 . stackoverflow.com/a/47723393/603516