t33st33r
t33st33r

Reputation: 307

Is it possible to cancel Ctrl+C default action in another process' console?

I want to disable the Ctrl+C default action (stop/close/kill) in an external console application on Windows. I have read about "SetConsoleCtrlHandler" and "Console.TreatCtrlCAsInput" but none of them seem to be valid for an external process.

Is there some alternative? Am I ignoring some detail that makes it possible using some of the discarded options?

My idea for this application is to be a non-interactive app, and to be opened as child from the console app (cmd.exe/cscript.exe/etc.). And it watches parent process of been closed to close itself too.

This is what I have now:

using System.Threading;                     //Thread
using System.Runtime.InteropServices;       //DllImport

// A delegate type to be used as the handler routine for SetConsoleCtrlHandler.
public delegate bool HandlerRoutine(CtrlTypes CtrlType);

// An enumerated type for the control messages sent to the handler routine.
public enum CtrlTypes {
 CTRL_C_EVENT = 0,
 CTRL_BREAK_EVENT = 1,
 CTRL_CLOSE_EVENT = 2,
 CTRL_LOGOFF_EVENT = 5,
 CTRL_SHUTDOWN_EVENT = 6
}

public class all {
    [DllImport("Kernel32")] public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool AttachConsole(uint dwProcessId);

    [DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]
    static extern bool FreeConsole();

/*
    //Maybe I will need GetConsoleWindow after.
    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();
*/

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType) {
        // Put your own handler here
        return true;
    }

    private void WaitThread(int mls) {
        Thread.Sleep(mls);
    }

    static void Main() {
        const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;
        Thread waitThread;
        //System.Console.WriteLine("!");
        //AttachConsole(ATTACH_PARENT_PROCESS);
        AttachConsole(ATTACH_PARENT_PROCESS);
        SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
        
        while(true) {
            waitThread = new Thread(() => WaitThread(100));
            waitThread.Start();                    
            waitThread.Join();
        }
        
        // Next lines are ignored. I will close the process manually while it's in WIP(Work In Progress) phase.
        CloseApp();
    }

    static void CloseApp() {
        FreeConsole();
        System.Environment.Exit(0);
    }
}

I found the "sleep routine" here: http://bresleveloper.blogspot.com/2012/05/console-applicationdoevents-solved.html

I am getting errors:

(49,29): error CS1525: El término de la expresión ')' no es válido

(49,32): error CS1525: El término de la expresión '>' no es válido

(49,34): error CS1026: Se esperaba ) (49,49): error CS1002: Se esperaba ;

(49,49): error CS1525: El término de la expresión ')' no es válido

Line 49 is the first one inside the "while(true)". I am new to C#, please consider this.

Upvotes: 0

Views: 220

Answers (1)

Jonghyun Yoon
Jonghyun Yoon

Reputation: 46

If external console application is not the program you wrote, you can handle it through global keyboard hooking.

Upvotes: 1

Related Questions