Windows의 응용 프로그램에 Ctrl-C (SIGINT)를 보낼 수 있습니까?


91

나는 (과거에), 명령 줄에서 시작했을 때, 사용자 입력 처리 크로스 플랫폼 (윈도우 / 유닉스) 응용 프로그램을 작성했습니다 Ctrl- C(즉 깨끗하게 응용 프로그램을 종료) 같은 방법으로 조합.

Windows에서 Ctrl- C/ SIGINT / Equivalent to a process from another (unrelated) process to request at cleanly (자원을 정리할 수있는 기회 등) 요청하는 것이 가능합니까?


1
스레드 덤프를 얻기 위해 Ctrl-C를 Java 서비스 프로세스에 보내는 데 관심이있었습니다. jstack이 특정 문제에 대해 대신 안정적으로 사용할 수있는 것으로 보입니다 . stackoverflow.com/a/47723393/603516
Vadzim

답변:


31

제가 가장 가까운 해결책은 SendSignal 타사 앱입니다. 작성자는 소스 코드와 실행 파일을 나열합니다. 64 비트 창 (32 비트 프로그램으로 실행, 다른 32 비트 프로그램 종료)에서 작동하는지 확인했지만 코드를 Windows 프로그램에 삽입하는 방법 (32 비트 또는 64 비트).

작동 원리 :

디버거를 자세히 살펴본 후 ctrl-break와 같은 신호와 관련된 동작을 실제로 수행하는 진입 점이 kernel32! CtrlRoutine이라는 것을 발견했습니다. 이 함수는 ThreadProc와 동일한 프로토 타입을 가지고 있으므로 코드를 삽입하지 않고도 CreateRemoteThread와 함께 직접 사용할 수 있습니다. 그러나 이것은 내 보낸 심볼이 아닙니다! 다른 버전의 Windows에서 다른 주소에 있으며 이름도 다릅니다. 무엇을해야합니까?

내가 마침내 생각해 낸 해결책은 다음과 같습니다. 내 앱에 콘솔 ctrl 핸들러를 설치 한 다음 앱에 대한 ctrl-break 신호를 생성합니다. 핸들러가 호출되면 스택의 맨 위를 돌아보고 kernel32! BaseThreadStart에 전달 된 매개 변수를 찾습니다. 첫 번째 매개 변수는 원하는 스레드의 시작 주소 인 kernel32! CtrlRoutine의 주소입니다. 그런 다음 핸들러에서 돌아와서 신호를 처리했으며 앱을 종료하지 않아야 함을 나타냅니다. 메인 스레드로 돌아가서 kernel32! CtrlRoutine의 주소가 검색 될 때까지 기다립니다. 일단 가져 오면 발견 된 시작 주소로 대상 프로세스에 원격 스레드를 만듭니다. 이로 인해 대상 프로세스의 ctrl 처리기가 마치 ctrl-break가 눌린 것처럼 평가됩니다!

좋은 점은 대상 프로세스 만 영향을 받고 모든 프로세스 (윈도우 프로세스 포함)를 대상으로 지정할 수 있다는 것입니다. 한 가지 단점은 내 작은 앱을 배치 파일에서 사용할 수 없다는 것입니다. kernel32! CtrlRoutine의 주소를 찾기 위해 ctrl-break 이벤트를 보낼 때 앱을 죽이기 때문입니다.

( start배치 파일에서 실행하는 경우 먼저 사용하십시오.)


2
+1-연결된 코드는 Ctrl-C가 아닌 Ctrl-Break를 사용하지만 그 표면 (GenerateConsoleCtrlEvent에 대한 설명서 참조)은 Ctrl-C에 맞게 조정할 수 있습니다.
Matthew Murdoch

8
실제로이 작업을 수행하는 기능이 있습니다. "GenerateConsoleCtrlEvent"입니다. 참조 : msdn.microsoft.com/en-us/library/ms683155(v=vs.85).aspx 여기에서 내 회신도 참조하십시오 : serverfault.com/a/501045/10023
Triynko

1
위 답변과 관련된 Github 링크 : github.com/walware/statet/tree/master/…
meawoppl

3
Windows가 예전처럼 오래되었지만 Microsoft는 콘솔 응용 프로그램 B에서 콘솔 응용 프로그램 B의 신호를 수신 할 수있는 메커니즘을 제공하지 않았기 때문에 콘솔 응용 프로그램 B가 콘솔 응용 프로그램 A에게 완전히 종료하도록 지시 할 수 있습니다. 어쨌든 MS-bashing을 제쳐두고 SendSignal을 시도하고 "CreateRemoteThread failed with 0x00000005"를 얻었습니다. 응용 프로그램 A를 코딩하여 신호 (편리한 신호)를 수신하는 방법과 신호를 보내는 방법에 대한 다른 아이디어가 있습니까?
David I. McIntosh

3
@ DavidI.McIntosh 두 프로세스 모두에서 명명 된 이벤트를 생성하려는 것 같습니다. 그런 다음 서로 신호를 보낼 수 있습니다. CreateEvent에 대한 문서 확인
arolson101 2014-08-09

58

이 주제에 대해 조사를 해봤는데 예상보다 더 인기가 많았습니다. 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);

// Enumerated type for the control messages sent to the handler routine
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)
{
  //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);

    //Moved this command up on suggestion from Timothy Jannace (see comments below)
    FreeConsole();

    // Must wait here. If we don't and re-enable Ctrl-C
    // handling below too fast, we might terminate ourselves.
    proc.WaitForExit(2000);

    //Re-enable Ctrl-C handling or any subsequently started
    //programs will inherit the disabled state.
    SetConsoleCtrlHandler(null, false); 
  }
}

또한 AttachConsole()전송 된 신호가 실패 할 경우 비상 솔루션을 계획 하십시오.

if (!proc.HasExited)
{
  try
  {
    proc.Kill();
  }
  catch (InvalidOperationException e){}
}

4
이것에 영감을 받아 "독립 실행 형"cpp 앱을 만들었 습니다 : 유용 할 경우를 대비해 gist.github.com/rdp/f51fb274d69c5c31b6be . 그리고 예,이 메서드는 분명히 "모든"pid에 ctrl + c 또는 ctrl + break를 보낼 수 있습니다.
rogerdpack

DLL 중 하나가 누락되면 "SetConsoleCtrlHandler"를 가져 오지만 작동합니다.
Derf Skren 2015 년

훌륭한 포스트. 훌륭한 블로그. 실험 프로그램에서 StopProgramWithInvisibleWindowUsingPinvoke 함수를 완료하는 것이 좋습니다. 나는 거의 당신이 해결책을 발견하지 않은 아이디어를 생각 포기
윌머 세인트

피하기 위해 다시 활성화 Ctrl-C ( )를 wait()제거했습니다 . 몇 가지 테스트 (여러 호출, 이미 종료 된 프로세스에 대해서도)를 수행했지만 부작용이 발견되지 않았습니다 (아직?). SetConsoleCtrlHandler(null, false);
56ka

FreeConsole은 GenerateConsoleCtrlEvent를 보낸 후 즉시 호출되어야합니다. 호출 될 때까지 애플리케이션이 다른 콘솔에 연결됩니다. 다른 콘솔이 종료되기 전에 종료되면 응용 프로그램도 종료됩니다!
Timothy Jannace

17

나는이 질문에 조금 늦었지만 어쨌든 같은 문제가있는 사람을 위해 무언가를 쓸 것입니다. 이것은 내가이 질문에 준 것과 같은 대답 입니다.

내 문제는 내 응용 프로그램이 GUI 응용 프로그램이기를 원하지만 실행되는 프로세스는 대화 형 콘솔 창을 연결하지 않고 백그라운드에서 실행되어야한다는 것입니다. 이 솔루션은 부모 프로세스가 콘솔 프로세스 일 때도 작동해야한다고 생각합니다. 하지만 "CREATE_NO_WINDOW"플래그를 제거해야 할 수도 있습니다.

래퍼 앱과 함께 GenerateConsoleCtrlEvent ()를 사용하여이 문제를 해결했습니다 . 까다로운 부분은 문서가 정확히 어떻게 사용되는지와 그 함정에 대해 명확하지 않다는 것입니다.

내 솔루션은 여기 에 설명 된 내용을 기반으로 합니다 . 그러나 그것은 실제로 모든 세부 사항을 설명하지 못했으며 오류가 있으므로 여기에 작동하는 방법에 대한 세부 정보가 있습니다.

새 도우미 응용 프로그램 "Helper.exe"를 만듭니다. 이 애플리케이션은 애플리케이션 (부모)과 종료 할 수있는 하위 프로세스 사이에 위치합니다. 또한 실제 자식 프로세스를 생성합니다. 이 "중간자"프로세스가 있어야합니다. 그렇지 않으면 GenerateConsoleCtrlEvent ()가 실패합니다.

일종의 IPC 메커니즘을 사용하여 도우미가 자식 프로세스를 닫아야한다는 부모에서 도우미 프로세스로 통신합니다. 도우미가이 이벤트를 받으면 "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)"를 호출하여 자신과 자식 프로세스를 닫습니다. 부모가 자식 프로세스를 취소하려고 할 때 완료하는 이벤트 개체를 직접 사용했습니다.

Helper.exe를 만들려면 CREATE_NO_WINDOW 및 CREATE_NEW_PROCESS_GROUP을 사용하여 만듭니다. 그리고 자식 프로세스를 만들 때 플래그 (0)없이 만들면 부모로부터 콘솔이 파생됩니다. 이렇게하지 않으면 이벤트가 무시됩니다.

각 단계가 이와 같이 수행되는 것이 매우 중요합니다. 나는 모든 다른 종류의 조합을 시도해 왔지만이 조합이 작동하는 유일한 조합입니다. CTRL_C 이벤트를 보낼 수 없습니다. 성공을 반환하지만 프로세스에서 무시됩니다. CTRL_BREAK 만 작동합니다. 둘 다 결국 ExitProcess ()를 호출하기 때문에 실제로 중요하지 않습니다.

또한 도우미 프로세스가 계속 유지되도록 직접 자식 프로세스 ID의 프로세스 그룹 ID로 GenerateConsoleCtrlEvent ()를 호출 할 수 없습니다. 이것도 실패합니다.

나는 이것을 작동시키기 위해 하루 종일을 보냈다. 이 솔루션은 저에게 효과적이지만 다른 사람이 추가 할 것이 있으면 수행하십시오. 나는 비슷한 문제를 가진 많은 사람들을 찾았지만 문제에 대한 확실한 해결책은 찾지 못했다. GenerateConsoleCtrlEvent () 작동 방식도 약간 이상하므로 자세한 내용을 아는 사람이 있으면 공유하십시오.


6
솔루션에 감사드립니다! 이것은 끔찍한 엉망인 Windows API의 또 다른 예입니다.
vitaut 2011 년

8

편집하다:

GUI 앱의 경우 Windows 개발에서이를 처리하는 "일반적인"방법은 WM_CLOSE 메시지를 프로세스의 기본 창에 보내는 것입니다.

콘솔 앱의 경우 SetConsoleCtrlHandler 를 사용 하여 CTRL_C_EVENT.

애플리케이션이이를 따르지 않으면 TerminateProcess를 호출 할 수 있습니다.


명령 줄 앱 (창 없음)에서이 작업을 수행하고 싶습니다. TerminateProcess는 강제 종료 메커니즘 (SIGKILL과 유사)이므로 종료 응용 프로그램에 정리할 기회를주지 않습니다.
Matthew Murdoch

@Matthew Murdoch : 콘솔 앱에서이를 처리하는 방법에 대한 정보를 포함하도록 업데이트되었습니다. 동일한 메커니즘을 통해 Windows 종료 또는 콘솔 종료 등의 다른 이벤트를 포착 할 수도 있습니다. 자세한 내용은 MSDN을 참조하십시오.
Reed Copsey

@Reed Copsey :하지만 별도의 프로세스에서 시작하고 싶습니다. (SetConsoleCtrlHandler에서 참조) GenerateConsoleCtrlEvent를 살펴 봤지만 종료되는 프로세스가 종료를 수행하는 프로세스와 동일한 '프로세스 그룹'에있는 경우에만 작동하는 것 같습니다. 어떤 아이디어가 있습니까?
Matthew Murdoch

1
Matthew : 내가 가진 유일한 아이디어는 프로세스를 찾고, 부모 (콘솔)를 찾고, 부모의 기본 창 핸들 (콘솔)을 가져 와서 SendKeys를 사용하여 Ctrl + C를 직접 보내는 것입니다. 그러면 콘솔 프로세스가 CTRL_C_EVENT를 수신하게됩니다. 그래도 시도하지 않았습니다-얼마나 잘 작동하는지 확실하지 않습니다.
Reed Copsey

다음은 C입니다 ++에서 SendKeys에 해당 stackoverflow.com/questions/6838363/... 참조 stackoverflow.com/questions/10407769/... 가 그렇다하더라도 작동하지 않을 비록 분명히 ...
rogerdpack

7

GenerateConsoleCtrlEvent()다른 프로세스에 대해 호출하면 어떻게 든 오류를 반환하지만 다른 콘솔 응용 프로그램에 연결하고 모든 하위 프로세스에 이벤트를 보낼 수 있습니다.

void SendControlC(int pid)
{
    AttachConsole(pid); // attach to process console
    SetConsoleCtrlHandler(NULL, TRUE); // disable Control+C handling for our app
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // generate Control+C event
}

제어권을 반환하는 방법? 그런 다음 control-c, stopar 프로그램을 보내지 만 그의 손으로는 아무것도 할 수 없습니다.
Yaroslav L.

제어권을 반환 할 위치는 어디입니까?
KindDragon 2013-07-17

SetConsoleCtrlHandler (NULL, FALSE)를 호출하여 처리기를 제거하고 다양한 다른 응답을 참조하십시오.
rogerdpack

6

다음은 내 C ++ 앱에서 사용하는 코드입니다.

긍정적 인 점 :

  • 콘솔 앱에서 작동
  • Windows 서비스에서 작동
  • 지연이 필요하지 않습니다
  • 현재 앱을 닫지 않습니다.

부정적인 점 :

  • 주 콘솔이 손실되고 새 콘솔이 생성됩니다 ( FreeConsole 참조 ).
  • 콘솔 전환은 이상한 결과를 제공합니다 ...

// Inspired from http://stackoverflow.com/a/15281070/1529139
// and http://stackoverflow.com/q/40059902/1529139
bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent)
{
    bool success = false;
    DWORD thisConsoleId = GetCurrentProcessId();
    // Leave current console if it exists
    // (otherwise AttachConsole will return ERROR_ACCESS_DENIED)
    bool consoleDetached = (FreeConsole() != FALSE);

    if (AttachConsole(dwProcessId) != FALSE)
    {
        // Add a fake Ctrl-C handler for avoid instant kill is this console
        // WARNING: do not revert it or current program will be also killed
        SetConsoleCtrlHandler(nullptr, true);
        success = (GenerateConsoleCtrlEvent(dwCtrlEvent, 0) != FALSE);
        FreeConsole();
    }

    if (consoleDetached)
    {
        // Create a new console if previous was deleted by OS
        if (AttachConsole(thisConsoleId) == FALSE)
        {
            int errorCode = GetLastError();
            if (errorCode == 31) // 31=ERROR_GEN_FAILURE
            {
                AllocConsole();
            }
        }
    }
    return success;
}

사용 예 :

DWORD dwProcessId = ...;
if (signalCtrl(dwProcessId, CTRL_C_EVENT))
{
    cout << "Signal sent" << endl;
}

4
        void SendSIGINT( HANDLE hProcess )
        {
            DWORD pid = GetProcessId(hProcess);
            FreeConsole();
            if (AttachConsole(pid))
            {
                // Disable Ctrl-C handling for our program
                SetConsoleCtrlHandler(NULL, true);

                GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // SIGINT

                //Re-enable Ctrl-C handling or any subsequently started
                //programs will inherit the disabled state.
                SetConsoleCtrlHandler(NULL, false);

                WaitForSingleObject(hProcess, 10000);
            }
        }

2

지금은 그렇지 않기 때문에 명확하게 만들어야합니다. Ctrl-C를 전송하는 SendSignal의 수정 및 컴파일 된 버전이 있습니다 (기본적으로 Ctrl + Break 전송 만 전송). 다음은 몇 가지 바이너리입니다.

(2014-3-7) : Ctrl-C로 32 비트와 64 비트 버전을 모두 만들었는데 SendSignalCtrlC.exe라고하는데 https://dl.dropboxusercontent.com/u/49065779/ 에서 다운로드 할 수 있습니다. sendsignalctrlc / x86 / SendSignalCtrlC.exe https://dl.dropboxusercontent.com/u/49065779/sendsignalctrlc/x86_64/SendSignalCtrlC.exe-Juraj Michalak


32 비트 버전 : https://www.dropbox.com/s/r96jxglhkm4sjz2/SendSignalCtrlC.exe?dl=0
64 비트 버전을 위해 해당 파일도 미러링했습니다 . https://www.dropbox.com /s/hhe0io7mcgcle1c/SendSignalCtrlC64.exe?dl=0

면책 조항 : 해당 파일을 빌드하지 않았습니다. 컴파일 된 원본 파일은 수정되지 않았습니다. 테스트 된 유일한 플랫폼은 64 비트 Windows 7 입니다. http://www.latenighthacking.com/projects/2003/sendSignal/ 에서 사용할 수있는 소스를 수정하고 직접 컴파일하는 것이 좋습니다 .


2

Java에서는 C ++ 솔루션과 유사한 Kernel32.dll 라이브러리와 함께 JNA를 사용합니다. CtrlCSender 메인 메서드를 프로세스로 실행하여 Ctrl + C 이벤트를 전송하고 이벤트를 생성하는 프로세스의 콘솔을 가져옵니다. 콘솔없이 별도로 실행되므로 Ctrl + C 이벤트를 비활성화하고 다시 활성화 할 필요가 없습니다.

CtrlCSender.java - Nemo1024KindDragon의 답변을 기반으로 합니다.

알려진 프로세스 ID가 주어지면이 콘솔 애플리케이션은 대상 프로세스의 콘솔을 연결하고 여기에 CTRL + C 이벤트를 생성합니다.

import com.sun.jna.platform.win32.Kernel32;    

public class CtrlCSender {

    public static void main(String args[]) {
        int processId = Integer.parseInt(args[0]);
        Kernel32.INSTANCE.AttachConsole(processId);
        Kernel32.INSTANCE.GenerateConsoleCtrlEvent(Kernel32.CTRL_C_EVENT, 0);
    }
}

메인 애플리케이션 -CtrlCSender를 별도의 콘솔 프로세스로 실행합니다.

ProcessBuilder pb = new ProcessBuilder();
pb.command("javaw", "-cp", System.getProperty("java.class.path", "."), CtrlCSender.class.getName(), processId);
pb.redirectErrorStream();
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
Process ctrlCProcess = pb.start();
ctrlCProcess.waitFor();

흠, powershell 프로세스에 대해 이것을 실행하면 프로세스가 살아 있습니다. 반면에 흥미롭게도 JVM에서 in-process를 실행하면 실제로 VM이 다운됩니다! powershell 프로세스가이 기술에 응답하지 않는 이유를 알고 있습니까?
Groostav


1

여기에서 찾은 해결책은 명령 줄에서 python 3.x를 사용할 수있는 경우 매우 간단합니다. 먼저 다음 내용으로 파일 (ctrl_c.py)을 저장합니다.

import ctypes
import sys

kernel = ctypes.windll.kernel32

pid = int(sys.argv[1])
kernel.FreeConsole()
kernel.AttachConsole(pid)
kernel.SetConsoleCtrlHandler(None, 1)
kernel.GenerateConsoleCtrlEvent(0, 0)
sys.exit(0)

그런 다음 전화 :

python ctrl_c.py 12345

그래도 작동하지 않으면 windows-kill 프로젝트를 시도해 보는 것이 좋습니다 : https://github.com/alirdn/windows-kill


1

jimhark의 답변 과 여기의 다른 답변 덕분 에 PowerShell에서 수행하는 방법을 찾았습니다.

$ProcessID = 1234
$MemberDefinition = '
    [DllImport("kernel32.dll")]public static extern bool FreeConsole();
    [DllImport("kernel32.dll")]public static extern bool AttachConsole(uint p);
    [DllImport("kernel32.dll")]public static extern bool GenerateConsoleCtrlEvent(uint e, uint p);
    public static void SendCtrlC(uint p) {
        FreeConsole();
        if (AttachConsole(p)) {
            GenerateConsoleCtrlEvent(0, p);
            FreeConsole();
        }
        AttachConsole(uint.MaxValue);
    }'
Add-Type -Name 'dummyName' -Namespace 'dummyNamespace' -MemberDefinition $MemberDefinition
[dummyNamespace.dummyName]::SendCtrlC($ProcessID) }

어떤 일 작업이 전송되었습니다 만든 GenerateConsoleCtrlEvent를 대신 원하는 프로세스 그룹 all processes that share the console of the calling processAttachConsole 에 다시 the console of the parent of the current process.


0

제 친구가 문제를 해결하는 완전히 다른 방법을 제안했고 그것은 저에게 효과적이었습니다. 아래와 같은 vbscript를 사용하십시오. 시작 및 적용, 7 초 동안 실행하고 ctrl + c를 사용하여 닫습니다 .

'VBScript 예제

Set WshShell = WScript.CreateObject("WScript.Shell")

WshShell.Run "notepad.exe"

WshShell.AppActivate "notepad"

WScript.Sleep 7000

WshShell.SendKeys "^C"

이것은 응용 프로그램에 AppActive (전경으로 가져 오기) 할 수있는 창이있는 경우 작동합니다.
rogerdpack 2015 년

0

이 모든 것이 너무 복잡하다는 것을 발견하고 SendKeys 를 사용 하여 CTRL- C키 입력을 명령 줄 창 (예 : cmd.exe 창)에 해결 방법 으로 보냅니다 .


0
// Send [CTRL-C] to interrupt a batch file running in a Command Prompt window, even if the Command Prompt window is not visible,
// without bringing the Command Prompt window into focus.
// [CTRL-C] will have an effect on the batch file, but not on the Command Prompt  window itself -- in other words,
// [CTRL-C] will not have the same visible effect on a Command Prompt window that isn't running a batch file at the moment
// as bringing a Command Prompt window that isn't running a batch file into focus and pressing [CTRL-C] on the keyboard.
ulong ulProcessId = 0UL;
// hwC = Find Command Prompt window HWND
GetWindowThreadProcessId (hwC, (LPDWORD) &ulProcessId);
AttachConsole ((DWORD) ulProcessId);
SetConsoleCtrlHandler (NULL, TRUE);
GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0UL);
SetConsoleCtrlHandler (NULL, FALSE);
FreeConsole ();

0

SIGINT가 사용하는 프로그램으로 전송 될 수 있습니다 창 - 죽일 구문으로, windows-kill -SIGINT PID여기서 PID마이크로 소프트에 의해 얻을 수 pslist .

SIGINT 잡기와 관련하여 프로그램이 Python에 있으면이 솔루션 과 같이 SIGINT 처리 / 잡기를 구현할 수 있습니다 .


-1

프로세스 ID를 기반으로 프로세스에 신호를 보내 강제로 또는 정상적으로 종료하거나 다른 신호를 보낼 수 있습니다.

모든 프로세스 나열 :

C:\>tasklist

프로세스를 종료하려면 :

C:\>Taskkill /IM firefox.exe /F
or
C:\>Taskkill /PID 26356 /F

세부:

http://tweaks.com/windows/39559/kill-processes-from-command-prompt/


이것이 sigterm을 보내는 전제?
teknopaul

Taskkill은 CTRL-C를 보내지 않습니다. Windows 신호를 확인하십시오.
Josi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.