You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows 7下Python实现高效等待指定进程启动的方案问询

Great question! Polling works but it's definitely not the most efficient way to go—Windows has built-in system event mechanisms that let you listen for process creation passively, and Python can absolutely leverage these. Here are two solid approaches for Windows 7:

方法一:使用WMI(Windows Management Instrumentation)

This is the easiest route for most cases. WMI provides a high-level way to subscribe to system events, so you don't have to dig into low-level APIs.

Setup & Code:

First, install the required library:

pip install wmi

Then write your listener:

import wmi
import time

def handle_process_start(target_name):
    def event_callback(event):
        # Check if the newly created process matches our target
        if event.TargetInstance.Name.lower() == target_name.lower():
            print(f"✅ Target process {target_name} has started!")
            # Drop your custom logic here
            # run_your_action()
    return event_callback

if __name__ == "__main__":
    target_process = "notepad.exe"  # Replace with your process name
    wmi_client = wmi.WMI()
    
    # Subscribe to process creation events
    event_watcher = wmi_client.WatchForEvent(
        "__InstanceCreationEvent",
        within_interval=1,  # Adjust this if you need faster detection (0.5s works too)
        TargetInstance="Win32_Process",
        callback=handle_process_start(target_process)
    )
    
    print(f"🔍 Listening for {target_process} to start...")
    try:
        # Keep the main thread alive
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("\n🛑 Listening stopped")
        event_watcher.cancel()

Why this works:

Instead of you repeatedly checking the process list, WMI handles monitoring at the system level and triggers your callback only when a new process is created. The within_interval is just how often WMI checks for events—even at 1 second, this is way more efficient than polling because it doesn't waste CPU cycles on unnecessary checks.

方法二:Windows Native API (For Maximum Performance)

If you need ultra-low latency or want to avoid third-party libraries, you can call Windows' native event hooks directly using ctypes. This is more complex but gives you full control.

Code Example:

import ctypes
from ctypes import wintypes

# Load Windows API libraries
user32 = ctypes.WinDLL('user32', use_last_error=True)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

# Define the callback function type for Windows events
WinEventProc = ctypes.WINFUNCTYPE(
    None,
    wintypes.HWINEVENTHOOK,
    wintypes.DWORD,
    wintypes.HWND,
    wintypes.LONG,
    wintypes.LONG,
    wintypes.DWORD,
    wintypes.DWORD
)

# System event constant for object creation (includes processes)
EVENT_OBJECT_CREATE = 0x8000
# Hook flag to listen across all processes
WINEVENT_OUTOFCONTEXT = 0x0000

def process_creation_handler(hook, event, hwnd, id_obj, id_child, thread_id, event_time):
    if event == EVENT_OBJECT_CREATE:
        # Get the PID of the newly created process
        pid = wintypes.DWORD()
        user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
        pid = pid.value
        
        # Open the process to get its name
        process_handle = kernel32.OpenProcess(0x0400 | 0x0010, False, pid)  # Required permissions
        if process_handle:
            name_buffer = ctypes.create_unicode_buffer(260)
            kernel32.GetModuleFileNameExW(process_handle, None, name_buffer, ctypes.sizeof(name_buffer))
            process_name = name_buffer.value.split('\\')[-1]
            
            # Check if it's our target process
            target_process = "notepad.exe"
            if process_name.lower() == target_process.lower():
                print(f"✅ {target_process} started (PID: {pid})")
                # Add your custom actions here
                # execute_your_task()
            
            kernel32.CloseHandle(process_handle)

# Set up the event hook
event_callback_ptr = WinEventProc(process_creation_handler)
hook_handle = user32.SetWinEventHook(
    EVENT_OBJECT_CREATE,
    EVENT_OBJECT_CREATE,
    None,
    event_callback_ptr,
    0,
    0,
    WINEVENT_OUTOFCONTEXT
)

if not hook_handle:
    raise ctypes.WinError(ctypes.get_last_error())

print("🔍 Listening for process starts...")
try:
    # Run the message loop to keep the hook active
    msg = wintypes.MSG()
    while user32.GetMessageW(ctypes.byref(msg), None, 0, 0) != 0:
        user32.TranslateMessage(ctypes.byref(msg))
        user32.DispatchMessageW(ctypes.byref(msg))
except KeyboardInterrupt:
    print("\n🛑 Listening stopped")
finally:
    user32.UnhookWinEvent(hook_handle)

Notes:

  • This method taps directly into Windows' event system, so latency is minimal and resource usage is almost negligible.
  • You might need to run the script as an administrator to access information for certain protected processes.
  • The code is more verbose, but it's perfect if you need maximum efficiency or want to avoid external dependencies.

Final Thoughts

  • Go with the WMI method if you want simplicity and don't need ultra-low latency—it's quick to implement and works for 90% of use cases.
  • Use the native API method when performance is critical or you want full control over the event handling.

Both approaches are way better than polling because they're passive—your script only does work when the actual event you care about happens.

内容的提问来源于stack exchange,提问作者Ram Rachum

火山引擎 最新活动