如何在Windows 10中检测特定进程执行并触发程序自动运行?
在Windows 10下实现这个需求,有两种核心思路,以下是你优先考虑的几种语言的具体实现,以及一个无需编程的备选方案:
核心思路
- 后台进程监听:运行一个后台程序,持续检测系统中是否存在A.exe进程,一旦检测到启动事件就自动运行B.exe
- 启动器包装:编写一个中间程序,先启动B.exe,再启动A.exe,将原A.exe的入口替换为这个启动器
Python 实现
方式1:后台进程监听
依赖psutil库实现进程检测,先通过pip install psutil安装依赖:
import psutil import subprocess import time # 替换为你的实际路径/进程名 A_EXE_NAME = "A.exe" B_EXE_PATH = r"C:\full\path\to\B.exe" last_running = False def check_and_start_b(): global last_running # 遍历系统进程检测A.exe是否运行 a_running = any(proc.name() == A_EXE_NAME for proc in psutil.process_iter(['name'])) if a_running and not last_running: # 启动B.exe subprocess.Popen(B_EXE_PATH, shell=False) print("B.exe started alongside A.exe") last_running = a_running if __name__ == "__main__": # 持续检测,可调整检测间隔 while True: check_and_start_b() time.sleep(2)
打包成后台exe:用pyinstaller --onefile --windowed --noconsole monitor.py,将生成的exe添加到Windows开机启动项(任务计划程序或用户启动文件夹)。
方式2:启动器包装
编写一个启动器,先启动B再启动A,替换原A.exe的入口:
import subprocess import sys # 替换为你的实际路径 A_EXE_PATH = r"C:\full\path\to\A.exe" B_EXE_PATH = r"C:\full\path\to\B.exe" # 启动B.exe(后台运行) subprocess.Popen(B_EXE_PATH, shell=False) # 启动A.exe并传递原命令行参数 subprocess.call([A_EXE_PATH] + sys.argv[1:])
打包:pyinstaller --onefile launcher.py,将原A.exe重命名为A_original.exe,把生成的launcher.exe改名为A.exe即可。
Node.js 实现
方式1:后台进程监听
依赖ps-node库,先通过npm install ps-node安装:
const ps = require('ps-node'); const { exec } = require('child_process'); const path = require('path'); const A_EXE_NAME = 'A.exe'; const B_EXE_PATH = path.resolve('C:\\full\\path\\to\\B.exe'); let lastRunning = false; function checkAndStartB() { ps.lookup({ command: A_EXE_NAME }, (err, resultList) => { if (err) throw err; const isARunning = resultList.length > 0; if (isARunning && !lastRunning) { exec(`start "" "${B_EXE_PATH}"`, (err) => { err ? console.error('Failed to start B.exe:', err) : console.log('B.exe started'); }); } lastRunning = isARunning; }); } // 每隔2秒检测一次 setInterval(checkAndStartB, 2000);
打包成exe:用pkg工具,npm install -g pkg后执行pkg monitor.js --targets node18-win-x64,将生成的exe添加到开机启动。
方式2:启动器包装
const { spawn } = require('child_process'); const path = require('path'); const A_EXE_PATH = path.resolve('C:\\full\\path\\to\\A.exe'); const B_EXE_PATH = path.resolve('C:\\full\\path\\to\\B.exe'); // 后台启动B.exe spawn(B_EXE_PATH, [], { detached: true, stdio: 'ignore' }).unref(); // 启动A.exe并传递命令行参数 spawn(A_EXE_PATH, process.argv.slice(2), { stdio: 'inherit' });
打包:pkg launcher.js --targets node18-win-x64,同样替换原A.exe为启动器。
Rust 实现
方式1:后台进程监听
Cargo.toml添加依赖:
[dependencies] sysinfo = "0.29" tokio = { version = "1.0", features = ["full"] }
代码:
use sysinfo::{ProcessExt, System, SystemExt}; use std::process::Command; use std::time::Duration; #[tokio::main] async fn main() { let a_exe_name = "A.exe"; let b_exe_path = "C:\\full\\path\\to\\B.exe"; let mut sys = System::new_all(); let mut last_running = false; loop { sys.refresh_processes(); let is_a_running = sys.processes_by_name(a_exe_name).next().is_some(); if is_a_running && !last_running { match Command::new(b_exe_path).spawn() { Ok(_) => println!("B.exe started"), Err(e) => eprintln!("Failed to start B.exe: {}", e), } } last_running = is_a_running; tokio::time::sleep(Duration::from_secs(2)).await; } }
编译:cargo build --release,将target/release下的exe添加到开机启动。
方式2:启动器包装
Cargo.toml添加依赖:
[dependencies] stdprocess = "0.2"
代码:
use std::env; use stdprocess::Command; fn main() { let a_exe_path = "C:\\full\\path\\to\\A.exe"; let b_exe_path = "C:\\full\\path\\to\\B.exe"; // 启动B.exe if let Err(e) = Command::new(b_exe_path).spawn() { eprintln!("Failed to start B.exe: {}", e); } // 启动A.exe并传递命令行参数 let args: Vec<String> = env::args().skip(1).collect(); let _ = Command::new(a_exe_path).args(args).status(); }
编译:cargo build --release,替换原A.exe为启动器。
Java 实现
方式1:后台进程监听
通过wmic命令查询进程,无需额外依赖:
import java.io.IOException; import java.util.concurrent.TimeUnit; public class ProcessMonitor { private static final String A_EXE_NAME = "A.exe"; private static final String B_EXE_PATH = "C:\\full\\path\\to\\B.exe"; private static boolean lastRunning = false; public static void main(String[] args) throws Exception { while (true) { boolean isARunning = checkProcessRunning(A_EXE_NAME); if (isARunning && !lastRunning) { new ProcessBuilder(B_EXE_PATH).start(); System.out.println("B.exe started"); } lastRunning = isARunning; TimeUnit.SECONDS.sleep(2); } } private static boolean checkProcessRunning(String processName) throws IOException { Process process = new ProcessBuilder("wmic", "process", "where", "name='" + processName + "'", "get", "name") .redirectErrorStream(true) .start(); String output = new String(process.getInputStream().readAllBytes()); return output.contains(processName); } }
打包:用javac ProcessMonitor.java编译后,用launch4j工具将jar打包成exe,添加到开机启动。
方式2:启动器包装
import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Launcher { public static void main(String[] args) throws IOException { String aExePath = "C:\\full\\path\\to\\A.exe"; String bExePath = "C:\\full\\path\\to\\B.exe"; // 启动B.exe new ProcessBuilder(bExePath).start(); // 启动A.exe并传递参数 List<String> cmd = new ArrayList<>(); cmd.add(aExePath); for (String arg : args) { cmd.add(arg); } new ProcessBuilder(cmd).inheritIO().start(); } }
编译打包后替换原A.exe即可。
无需编程的备选方案
使用Windows任务计划程序:
- 创建新任务,触发器选择「当特定程序启动时」,程序路径选择A.exe
- 操作选择「启动程序」,路径选择B.exe
- 配置任务为「不管用户是否登录都运行」,并勾选「隐藏」选项
内容的提问来源于stack exchange,提问作者jjangga

