Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ociule
Created January 20, 2020 09:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ociule/8a48d2a6b15f49258a87b5f55be29250 to your computer and use it in GitHub Desktop.
Save ociule/8a48d2a6b15f49258a87b5f55be29250 to your computer and use it in GitHub Desktop.
import ctypes
import win32event, winerror
class ExitCodeProcess(ctypes.Structure):
_fields_ = [
('hProcess', ctypes.c_void_p), # HANDLE
('lpExitCode', ctypes.POINTER(ctypes.c_ulong)) # LPDWORD
]
def pid_exists(pid):
"""Check whether a process with the given pid exists. Works on Windows only.
Works even if the process is not owned by the current user."""
kernel32 = ctypes.windll.kernel32
process = kernel32.OpenProcess(win32event.SYNCHRONIZE, 0, pid)
if not process:
if kernel32.GetLastError() == winerror.ERROR_ACCESS_DENIED:
# Access is denied. This means the process exists!
return True
return False
ec = ExitCodeProcess()
out = kernel32.GetExitCodeProcess(process, ctypes.byref(ec))
if not out:
if kernel32.GetLastError() == winerror.ERROR_ACCESS_DENIED:
# Access is denied. This means the process exists!
kernel32.CloseHandle(process)
return True
kernel32.CloseHandle(process)
return False
elif bool(ec.lpExitCode):
# There is an exit code, it quit
kernel32.CloseHandle(process)
return False
# No exit code, it's running.
kernel32.CloseHandle(process)
return True
print(pid_exists(14444))
@mai1x9
Copy link

mai1x9 commented Feb 18, 2023

@ociule
the code does not always, if a process is launched by subprocess with detached mode, or shell=True, and then killing the process using task manager, will still show pid exists and returns true.

The below is the code i used to invoke pid_exits()

def check_parent_alive(proc_path=""):
    global pid_to_monitor
    while 1:
        process = pid_exists(pid_to_monitor)
        if process:
            print("[++] Process exists")
        else:
            print("Looks like process killed ... ", pid_to_monitor)
            proc = subprocess.Popen(['python', "example.py"],  # shell=True, start_new_session=True)
                                    creationflags=0x0000000)

            pid_to_monitor = proc.pid
        sleep(2)

which peridically checks if pid_to_monitor exits, if it does not then it launches example.py using subprocess, but then if the launched process is killed, it still detects process is running.

@ociule
Copy link
Author

ociule commented Feb 28, 2023

Sounds like a bug somewhere. I do not do much work nowadays with the win32 API so I'm not able to debug it, sorry. Hope you find a good solution to your issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment