Skip to content

Instantly share code, notes, and snippets.

@rdp
Last active February 28, 2025 13:15
Show Gist options
  • Save rdp/f51fb274d69c5c31b6be to your computer and use it in GitHub Desktop.
Save rdp/f51fb274d69c5c31b6be to your computer and use it in GitHub Desktop.

Revisions

  1. rdp revised this gist Oct 21, 2019. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions send_ctrl_c.c
    Original file line number Diff line number Diff line change
    @@ -37,7 +37,7 @@ void logLastError()
    void sendCtrlC(int pid)
    {
    //This does not require the console window to be visible.
    printf("sending ctrl+c to pid %d", pid); // have to log here or we'll be sending it to the other console with printf [!] XXX could maybe duplicate descriptors first or some odd...oh well.
    printf("sending ctrl+c to pid %d", pid); // if we want to log anything at all, have to log here or we'll be sending it to the other console with printf [!] XXX could maybe duplicate descriptors first or some odd...oh well.
    FreeConsole(); // free ourselves from our current console, in case we're being run from a cmd.exe otherwise can't attach to another (at most one). And we probably are...if it fails because we don't have one, that's OK too.
    if (AttachConsole(pid))
    {
    @@ -48,7 +48,7 @@ void sendCtrlC(int pid)
    // could also send it *another* ctrl_c_event, for instance if you're trying to interrupt something in a batch file and it has that ugly "Batch file interrupted, continue [y/n]" [?]
    }
    else {
    logLastError();
    logLastError(); // failure, PID might no longer exist, show a GUI error window
    }
    }

  2. rdp renamed this gist Jan 30, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. rdp revised this gist Jan 29, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion send_ctrl_c.cpp
    Original file line number Diff line number Diff line change
    @@ -44,7 +44,7 @@ void sendCtrlC(int pid)
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...though that might not hurt currently...
    SetConsoleCtrlHandler(NULL, true);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT , 0); // these get sent to every process attached to this console, FWIW...
    // TODO could wait here for process to exit, hard kill it after a pause, etc. see http://stackoverflow.com/a/31020562/32453
    // TODO could wait here for process to exit, hard kill it after a sufficient wait, etc. see http://stackoverflow.com/a/31020562/32453
    // could also send it *another* ctrl_c_event, for instance if you're trying to interrupt something in a batch file and it has that ugly "Batch file interrupted, continue [y/n]" [?]
    }
    else {
  4. rdp revised this gist Jun 25, 2015. 1 changed file with 7 additions and 4 deletions.
    11 changes: 7 additions & 4 deletions send_ctrl_c.cpp
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    // attribution: http://stackoverflow.com/a/15281070/32453
    // you can compile this with gcc [mingw or mingw-w64] and probably other compilers as well

    #include <stdlib.h> // NULL
    #include <stdbool.h> // false
    #include <windows.h> // AttachConsole, CTRL_C_EVENT, etc.
    @@ -35,14 +38,14 @@ void sendCtrlC(int pid)
    {
    //This does not require the console window to be visible.
    printf("sending ctrl+c to pid %d", pid); // have to log here or we'll be sending it to the other console with printf [!] XXX could maybe duplicate descriptors first or some odd...oh well.
    FreeConsole(); // free current console, in case we're being run from a cmd.exe otherwise can't attach to another (at most one). And we probably are...if it fails because we don't have one, that's OK too.
    FreeConsole(); // free ourselves from our current console, in case we're being run from a cmd.exe otherwise can't attach to another (at most one). And we probably are...if it fails because we don't have one, that's OK too.
    if (AttachConsole(pid))
    {
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...though that might not hurt currently...
    SetConsoleCtrlHandler(NULL, true);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT , 0); // these get sent to every process attached to this console, FWIW...
    // could also send CTRL_BREAK_EVENT
    // TODO could wait here for process to exit, hard kill it (TerminateProcess) after a pause (pause info: http://stackoverflow.com/a/31020562/32453)
    // TODO could wait here for process to exit, hard kill it after a pause, etc. see http://stackoverflow.com/a/31020562/32453
    // could also send it *another* ctrl_c_event, for instance if you're trying to interrupt something in a batch file and it has that ugly "Batch file interrupted, continue [y/n]" [?]
    }
    else {
    logLastError();
  5. rdp revised this gist Jun 24, 2015. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions send_ctrl_c.cpp
    Original file line number Diff line number Diff line change
    @@ -41,6 +41,7 @@ void sendCtrlC(int pid)
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...
    SetConsoleCtrlHandler(NULL, true);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT , 0); // these get sent to every process attached to this console, FWIW...
    // could also send CTRL_BREAK_EVENT
    // TODO could wait here for process to exit, hard kill it (TerminateProcess) after a pause (pause info: http://stackoverflow.com/a/31020562/32453)
    }
    else {
  6. rdp revised this gist Jun 24, 2015. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions send_ctrl_c.cpp
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    #include <stdlib.h> // NULL
    #include <stdbool.h> // false
    #include <windows.h> // AttachConsole, CTRL_C_EVENT, etc.
    @@ -42,7 +41,7 @@ void sendCtrlC(int pid)
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...
    SetConsoleCtrlHandler(NULL, true);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT , 0); // these get sent to every process attached to this console, FWIW...
    // TODO could wait here for process to exit, hard kill it after a pause, etc. see http://stackoverflow.com/a/31020562/32453
    // TODO could wait here for process to exit, hard kill it (TerminateProcess) after a pause (pause info: http://stackoverflow.com/a/31020562/32453)
    }
    else {
    logLastError();
  7. rdp revised this gist Jun 24, 2015. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions send_ctrl_c.cpp
    Original file line number Diff line number Diff line change
    @@ -41,9 +41,8 @@ void sendCtrlC(int pid)
    {
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...
    SetConsoleCtrlHandler(NULL, true);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // these get sent to every process attached to this console, FWIW...
    // TODO could wait here for process to exit, hard kill it, etc.
    // don't know how to do that, so...just exit this program, basically.
    GenerateConsoleCtrlEvent(CTRL_C_EVENT , 0); // these get sent to every process attached to this console, FWIW...
    // TODO could wait here for process to exit, hard kill it after a pause, etc. see http://stackoverflow.com/a/31020562/32453
    }
    else {
    logLastError();
  8. rdp created this gist Jun 24, 2015.
    61 changes: 61 additions & 0 deletions send_ctrl_c.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,61 @@

    #include <stdlib.h> // NULL
    #include <stdbool.h> // false
    #include <windows.h> // AttachConsole, CTRL_C_EVENT, etc.
    #include <stdio.h> // printf

    #include <strsafe.h>
    void logLastError()
    {
    LPTSTR errorText = NULL;

    FormatMessage(
    // use system message tables to retrieve error text
    FORMAT_MESSAGE_FROM_SYSTEM
    // allocate buffer on local heap for error text
    |FORMAT_MESSAGE_ALLOCATE_BUFFER
    // Important! will fail otherwise, since we're not
    // (and CANNOT) pass insertion parameters
    |FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL, // unused with FORMAT_MESSAGE_FROM_SYSTEM
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR)&errorText, // output
    0, // minimum size for output buffer
    NULL); // arguments - see note

    if ( NULL != errorText )
    {
    printf("failure: %s", errorText);
    LocalFree(errorText);
    errorText = NULL;
    }
    }

    void sendCtrlC(int pid)
    {
    //This does not require the console window to be visible.
    printf("sending ctrl+c to pid %d", pid); // have to log here or we'll be sending it to the other console with printf [!] XXX could maybe duplicate descriptors first or some odd...oh well.
    FreeConsole(); // free current console, in case we're being run from a cmd.exe otherwise can't attach to another (at most one). And we probably are...if it fails because we don't have one, that's OK too.
    if (AttachConsole(pid))
    {
    // Disable Ctrl-C handling for our own program, so we don't "kill" ourselves on accident...
    SetConsoleCtrlHandler(NULL, true);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // these get sent to every process attached to this console, FWIW...
    // TODO could wait here for process to exit, hard kill it, etc.
    // don't know how to do that, so...just exit this program, basically.
    }
    else {
    logLastError();
    }
    }

    int main( int argc, const char* argv[] ) {
    // assume they know the pid...
    if (argc != 2) {
    printf("syntax: pid");
    return 1;
    }
    int pid = atoi(argv[1]);
    sendCtrlC(pid);
    }