前提
プロセスIDの変数pid
にはint
の他None
がアサインされることもある。
None
の場合は既にプロセスがkillされていると判断してFalse
を返すことにする。
それ以外では、プロセスIDをなんらかの方法で用いて生存を判断する。
標準ライブラリsubprocess
を使う場合
import subprocess
def exists_task(pid: "int | None") -> bool:
if pid is None:
return False
proc = subprocess.run(
# chcp437指定でコマンドの言語を英語に切り替える。
# これで実行環境が日本語でも`stdout`は英語バイト列になる
["chcp", "437", "|", "tasklist", "/fi", f"PID eq {pid}"],
stdout=subprocess.PIPE,
shell=True,
# エンコードを指定すると`UnicodeDecodeError`が発生する時がある
)
# 判断基準はバイト列の比較でこと足りる
return b"INFO: No tasks are running which match the specified criteria" not in proc.stdout
comtypes
を使う場合
import comtypes.client
# Microsoft WMI Scriptingのモジュール作成
comtypes.client.GetModule("wbemdisp.TLB")
# WbemScriptingを静的import
# `WbemScripting = comtypes.client.GetModule(...)`でも実行時に動く(IDEによる静的解析はできない)
from comtypes.gen import WbemScripting
def exists_task(pid: "int | None") -> bool:
if pid is None:
return False
wmi = comtypes.client.CreateObject(WbemScripting.SWbemLocator, interface=WbemScripting.ISWbemLocator)
wmi_service = wmi.ConnectServer(".", "root\\cimv2")
result = wmi_service.ExecQuery(f"SELECT * FROM Win32_Process WHERE ProcessId = {pid}")
return bool(result.Count)