Giter VIP home page Giter VIP logo

ctrlc's Introduction

ctrlc

Helper program to terminate processes gracefully.

I was making a GUI program in Python and wanted to run console apps without any window and terminate them gracefully. No big deal on Linux and Mac, you just send SIGINT. But Windows makes it hard. You need to create a subprocess with CREATE_NEW_PROCESS_GROUP flag and then you can send CTRL_BREAK_EVENT. But that event doesn't work with everything, you won't stop ping with it, you need CTRL_C_EVENT. But the default handler for that event is disabled when you use CREATE_NEW_PROCESS_GROUP flag. And if you add PyInstaller into the mix then even CTRL_BREAK_EVENT stops working (unless I missed some flag).

You can read more about that mess here:
https://bugs.python.org/issue33245
https://bugs.python.org/issue23948

Code for gracefully killing used in the example below and in ctrlc itself taken from:
https://stackoverflow.com/a/60795888/2428152

Below is the example use. ctrlc.exe is used only on Windows and if the code is frozen with PyInstaller.

import os
import sys
import signal
import subprocess
import threading

from time import sleep
from functools import partial


def terminate(p):
    p.terminate()
    print("terminated", p.args)


if os.name == 'nt':
    DEFAULT_KWARGS = {
        "creationflags": subprocess.CREATE_NEW_CONSOLE,
        "startupinfo": subprocess.STARTUPINFO(
            dwFlags=subprocess.STARTF_USESHOWWINDOW, wShowWindow=subprocess.SW_HIDE
        ),
    }
else:
    DEFAULT_KWARGS = {}


if __name__ == "__main__":
    p = subprocess.Popen(
        [
            "aria2c",
            "-o",
            r"test.iso",
            "https://releases.ubuntu.com/20.04.3/ubuntu-20.04.3-desktop-amd64.iso"
        ],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        **DEFAULT_KWARGS,
    )

    sleep(5)

    if os.name == 'nt':  # Windows
        if getattr(sys, 'frozen', False):  # when using PyInstaller
            command = ["ctrlc"]
        else:
            command = [
                sys.executable,
                "-c",
                "import ctypes, 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)",
            ]

        p2 = subprocess.Popen([*command, str(p.pid)], **DEFAULT_KWARGS)

        watchdog = threading.Timer(5, partial(terminate, p2))
        watchdog.start()
        p2.wait()
        watchdog.cancel()
    else:  # Linux or Mac
        p.send_signal(signal.SIGINT)

    watchdog = threading.Timer(5, partial(terminate, p))
    watchdog.start()
    exitcode = p.wait()
    watchdog.cancel()

    print(exitcode)  # should be 7 if the download link is correct
    # save to file in case PyInstaller is used with `--noconsole`
    with open("exitcode.txt", "w") as f:
        f.write(str(exitcode))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.