跳到主要内容

Windows 启动时自动运行多个 Python 脚本


Windows 启动时自动运行多个 Python 脚本

这篇记录几种常用启动方式。先按脚本是否需要登录前运行、是否需要可见窗口来选择入口;同一个后端脚本只保留一种自动启动方式,避免服务、任务计划和 Startup 同时拉起重复进程。

  • A. 登录前就在后台运行 → 对长期守护型脚本可使用 Windows Service;这里用第三方 NSSM 做包装
  • B. 用户登录后运行并显示窗口 → 使用任务计划程序 + .bat
  • C. 后台运行、登录后只看状态 → 后端由 A 负责,前台只查看日志或监控界面

如果脚本不需要真正的服务生命周期,也可以直接用任务计划程序的“系统启动时”触发器,不必为了开机运行就一定引入 NSSM。

下文使用一组示例路径,按实际安装位置和脚本名称替换:

Python (conda env) : D:\ProgramData\anaconda3\envs\csyh\python.exe
脚本目录           : D:\opcua\csyh
脚本文件           : OPCUA_1R_A.py OPCUA_1R.py OPCUA_2R_A.py OPCUA_2R.py OPCUA_KP_A.py OPCUA_KP.py

0. 先决准备(必做)

  1. 确认 Python 路径正确。直接运行目标解释器检查版本最直观:

    "D:\ProgramData\anaconda3\envs\csyh\python.exe" --version

    如果提示找不到文件,就改为本机实际的解释器绝对路径。

  2. 确认脚本能在命令行单独正常运行:

    "D:\ProgramData\anaconda3\envs\csyh\python.exe" "D:\opcua\csyh\OPCUA_1R_A.py"
  3. 在 D:\opcua\csyh 下创建一个 logs 文件夹:用于写入日志(服务模式强烈建议)。

    mkdir D:\opcua\csyh\logs
  4. 按运行方式收集输出。前台运行时保留控制台输出;服务运行时可在 nssm 的 I/O 页配置标准输出和标准错误文件,配合 Python 的 -u 参数减少缓冲。不要统一把 sys.stdout 改到文件后,又期待前台窗口继续显示 print 输出。

    业务日志可以单独使用 logging 同时写文件和控制台。以下是初始化片段,后续使用 logging.info(…) 等记录日志:

    import logging
    from logging.handlers import RotatingFileHandler
    from pathlib import Path
    
    logdir = Path(r"D:\opcua\csyh\logs")
    logdir.mkdir(parents=True, exist_ok=True)
    handler = RotatingFileHandler(
        logdir / (Path(__file__).name + ".log"),
        maxBytes=5_000_000,
        backupCount=3,
        encoding="utf-8",
    )
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(levelname)s %(message)s",
        handlers=[handler, logging.StreamHandler()],
    )
    logging.info("SCRIPT STARTED")

    该片段不会自动接管已有的 print;nssm 的输出文件与应用日志应使用不同文件名,避免同时写同一个文件。


A. 开机立即运行(登录前)——使用 Windows 服务(nssm)

优点:电脑上电 / 系统启动后就运行;不依赖用户登录;适合守护进程。
缺点:系统服务不能显示 GUI / 控制台窗口到用户桌面(安全限制)。

A.1 下载并安装 nssm(Non-Sucking Service Manager)

  • 将适合架构的 nssm.exe 放在自己的工具目录,例如 D:\tools\nssm,并将该目录加入所用终端的 PATH,或在命令中使用完整路径。
  • 确认在管理员 cmd 可以运行 nssm。

A.2 注册服务(为每个脚本建服务)

以 管理员 身份打开命令提示符(右键“以管理员身份运行”),然后对每个脚本运行:

示例(为 OPCUA_1R_A.py 注册):

nssm install OPCUA_1R_A

会弹出 GUI 输入框,填写:

  • Path: D:\ProgramData\anaconda3\envs\csyh\python.exe
  • Startup directory: D:\opcua\csyh
  • Arguments: -u D:\opcua\csyh\OPCUA_1R_A.py

(按 Install service 保存)

对其他脚本重复(用不同服务名,如 OPCUA_1R 等)。

A.3 设置自动启动(开机自动)

在管理员 cmd 中运行:

sc config OPCUA_1R_A start= auto
sc config OPCUA_1R start= auto
sc config OPCUA_2R_A start= auto
sc config OPCUA_2R start= auto
sc config OPCUA_KP_A start= auto
sc config OPCUA_KP start= auto

A.4 启动 / 停止 / 查看服务状态

启动某服务:

net start OPCUA_1R_A

停止:

net stop OPCUA_1R_A

查看服务状态:

sc query OPCUA_1R_A

A.5 日志与调试

  • 因为服务没有窗口,检查 D:\opcua\csyh\logs\OPCUA_1R_A.py.log(参考上面 Python 日志写法)。
  • 若想捕获更多输出,在 nssm 的 I/O 页可以配置 Stdout/Err 重定向文件。

B. 用户登录后自动弹出窗口(可见)——任务计划程序 + .bat / VBS

目标:用户一登录后立刻看到控制台窗口或 GUI(比如你想观察输出)。

关键点:需要交互窗口时,使用目标用户的交互登录会话,选择“仅当用户登录时运行”。“以最高权限运行”控制权限级别,不会因勾选它就自动转到 Session 0;是否提权按脚本实际需要决定。

B.1 在脚本目录下创建 run_all.bat

路径:D:\opcua\csyh\run_all.bat,内容(详尽版:含延时、工作目录、窗口标题):

@echo off
title OPCUA 启动脚本总控
REM 延时等待桌面完全加载(必要时调整秒数)
timeout /t 10 >nul

REM 切换到脚本目录
cd /d "D:\opcua\csyh"

REM 逐个启动并让窗口最大化显示(每个窗口标题有区分)
start "OPCUA_1R_A" /max cmd /k "D:\ProgramData\anaconda3\envs\csyh\python.exe D:\opcua\csyh\OPCUA_1R_A.py"
start "OPCUA_1R" /max   cmd /k "D:\ProgramData\anaconda3\envs\csyh\python.exe D:\opcua\csyh\OPCUA_1R.py"
start "OPCUA_2R_A" /max cmd /k "D:\ProgramData\anaconda3\envs\csyh\python.exe D:\opcua\csyh\OPCUA_2R_A.py"
start "OPCUA_2R" /max   cmd /k "D:\ProgramData\anaconda3\envs\csyh\python.exe D:\opcua\csyh\OPCUA_2R.py"
start "OPCUA_KP_A" /max cmd /k "D:\ProgramData\anaconda3\envs\csyh\python.exe D:\opcua\csyh\OPCUA_KP_A.py"
start "OPCUA_KP" /max   cmd /k "D:\ProgramData\anaconda3\envs\csyh\python.exe D:\opcua\csyh\OPCUA_KP.py"

REM 可选:暂停以防窗口马上关闭(仅当脚本本身结束时需要)
REM pause
exit

说明:

  • start "title" cmd /k "python ...":用 cmd 打开并保持窗口(不立即关闭)。
  • timeout /t 10:建议延时 10 秒,可根据机器速度调整。

B.2 (可选)激活已经打开的窗口

创建 D:\opcua\csyh\bring_front.vbs,仅用于尝试激活同一交互会话中已经存在的窗口。先由 B.1 创建窗口,再调用它,不在这里重复启动 run_all.bat:

Set WshShell = CreateObject("WScript.Shell")
' 激活各个窗口(按窗口标题)
On Error Resume Next
WshShell.AppActivate "OPCUA_1R_A"
WScript.Sleep 500
WshShell.AppActivate "OPCUA_1R"
WScript.Sleep 500
WshShell.AppActivate "OPCUA_2R_A"
' 根据需要继续 AppActivate

AppActivate 是激活窗口,不是始终置顶。目标窗口必须已经创建,且标题匹配;它不能修复会话隔离,也不保证绕过系统的焦点限制。

B.3 在“任务计划程序”中创建任务(非常详细步骤)

  1. 打开:Win + R → 输入 taskschd.msc → 回车。
  2. 右侧 点击:创建任务…(不是“创建基本任务”)。
  3. 常规(General)选项卡:
    • 名称:OPCUA Login Launch
    • 描述:登录后启动 OPCUA 脚本(任选)
    • 安全选项:选择你的用户账户(默认你的当前用户)。
    • 选择:仅当用户登录时运行(非常关键,保证窗口可见)。
    • 权限级别:是否勾选“以最高权限运行”取决于实际需要,不能把它与会话是否交互混为一谈
    • 配置为:Windows 10/11。
  4. 触发器(Triggers) → 新建(New…):
    • 开始任务:At log on(登录时)
    • 用户:Any user 或指定用户
    • 高级设置:延迟任务执行:10 秒(建议)
    • 点击 确定。
  5. 操作(Actions) → 新建(New…):
    • 操作:Start a program
    • 程序或脚本(Program/script):cmd.exe
    • 添加参数(Add arguments):
      /c "D:\opcua\csyh\run_all.bat"
      (使用 /c 会运行并关闭 cmd;如果你想保留 master 窗口也可以直接填写 bat 路径,但用 cmd /c 更可靠用于显示)
    • 起始于(Start in):D:\opcua\csyh
    • 确定。
  6. 条件(Conditions):取消不必要限制,如“仅在使用交流电时”等。
  7. 设置(Settings):勾选“如果任务失败,重试”等按需设置。
  8. 保存。选择“仅当用户登录时运行”时通常不需要额外保存账户密码;如果改成“无论用户是否登录都要运行”,才会涉及保存对应账户凭据等额外配置。
  9. 测试:右键任务 → 运行,应该立即在桌面看到多个窗口弹出。

B.4 验证

  • 退出当前账户并重新登录或重启并登录,等待大约 10 秒,观察窗口是否自动弹出。
  • 若没有弹出,检查任务历史(在任务上右键 -> 查看历史)和 run_all.bat 是否有错误输出。

C. 混合方案:后端运行,前台只监控

同一个后端脚本只由一个入口负责启动。采用服务方案时,登录任务不再运行启动这些后端的 run_all.bat,而是打开日志查看器或单独的监控界面。

例如,日志文件已由服务或应用创建后,在前台 PowerShell 中查看:

Get-Content -LiteralPath "D:\opcua\csyh\logs\OPCUA_1R_A.py.log" -Tail 50 -Wait

日志路径按实际配置填写;Ctrl+C 仅停止查看,不会停止后台服务。独立 GUI 可以通过后端提供的状态接口显示数据,不能为了“显示窗口”再启动一份相同业务逻辑。

原文的“绑定端口后立刻关闭 socket”只能检查当时的端口状态,不能作为单实例锁;两个进程都可能检查通过。端口被其他程序占用也不代表同一个脚本已启动。

需要单实例保护时,在程序中使用明确命名、原子获取并在整个运行期持有的互斥量或文件锁;失败时区分“实例已存在”与权限等其他错误。检查 PID 文件存在本身也不够,还涉及陈旧文件和竞争条件。计划任务中的“不启动新实例”只约束该任务,不能同时约束另外的服务入口。

D. 备用方法(注册表、Startup folder)简要说明

  • Startup folder(shell:startup): 把 .bat 或快捷方式放进去,用户登录后会运行(等同于 B 的 simpler 版本)。
  • 注册表:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run 可添加启动项(专业但不推荐用于复杂脚本)。
    这些方法都需要用户登录才能显示前台。

E. 常见问题与排错

  1. 脚本运行但看不到任何输出
    • 检查是否为服务(服务不会显示窗口)。
    • 检查日志文件 D:\opcua\csyh\logs\*.log。
  2. 计划任务运行但窗口不显示
    • 确保任务“仅当用户登录时运行”。
    • 检查任务的登录类型和运行账户;AppActivate 不能把非交互会话的窗口带到当前桌面,也不能替代权限配置。
    • 确保“操作”使用 cmd.exe /c "path\to\run_all.bat" 并设置正确的 “起始于” 路径。
  3. “操作目录无效”错误
    • 在 .bat 中使用 cd /d "D:\opcua\csyh" 或 在任务的 “起始于” 填写目录。
  4. 脚本重复启动
    • 检查是否有服务、登录任务和 Startup 项同时启动同一后端。先保留一个启动入口;程序级保护需使用运行期持有的原子锁。
  5. 权限 / 环境变量问题(conda 环境)
    • 如果脚本依赖 conda 环境包,建议使用环境中 python.exe 的绝对路径,或在 .bat 中先激活环境(复杂),例如:
      call "D:\ProgramData\anaconda3\Scripts\activate.bat" csyh
      python D:\opcua\csyh\OPCUA_1R_A.py
    • 注意:在服务下激活 conda 有时会失败,直接使用 env 的 python.exe 更稳。
  6. 启动顺序 / 依赖(网络/盘未挂载)
    • 如果脚本依赖网络驱动器或云盘,同步尚未完成可能失败。为计划任务设置延迟(30s 或更长),或在脚本中重试逻辑。

F. 文件清单

  1. run_all.bat(前文给出)
  2. bring_front.vbs(可选,用于激活窗口)
  3. startup_opcua_service_setup.cmd(管理员运行,一次性注册服务的模板脚本)——示例内容:
@echo off
REM 请以管理员身份运行,先确认 nssm 在 PATH 中或改用完整路径

nssm install OPCUA_1R_A "D:\ProgramData\anaconda3\envs\csyh\python.exe" -u "D:\opcua\csyh\OPCUA_1R_A.py"
nssm install OPCUA_1R   "D:\ProgramData\anaconda3\envs\csyh\python.exe" -u "D:\opcua\csyh\OPCUA_1R.py"
nssm install OPCUA_2R_A "D:\ProgramData\anaconda3\envs\csyh\python.exe" -u "D:\opcua\csyh\OPCUA_2R_A.py"
nssm install OPCUA_2R   "D:\ProgramData\anaconda3\envs\csyh\python.exe" -u "D:\opcua\csyh\OPCUA_2R.py"
nssm install OPCUA_KP_A "D:\ProgramData\anaconda3\envs\csyh\python.exe" -u "D:\opcua\csyh\OPCUA_KP_A.py"
nssm install OPCUA_KP   "D:\ProgramData\anaconda3\envs\csyh\python.exe" -u "D:\opcua\csyh\OPCUA_KP.py"

REM 显式设置各服务的工作目录,不能依赖安装命令运行时的当前目录
for %%S in (OPCUA_1R_A OPCUA_1R OPCUA_2R_A OPCUA_2R OPCUA_KP_A OPCUA_KP) do nssm set %%S AppDirectory "D:\opcua\csyh"

sc config OPCUA_1R_A start= auto
sc config OPCUA_1R start= auto
sc config OPCUA_2R_A start= auto
sc config OPCUA_2R start= auto
sc config OPCUA_KP_A start= auto
sc config OPCUA_KP start= auto

echo Services created. You can start them via: net start OPCUA_1R_A
pause

NSSM 支持 nssm install <name> <program> [args] 的命令行安装方式;如果参数较复杂、包含较多引号,也可以改用 nssm install <name> 打开 GUI 填写。服务安装后不要随意移动正在使用的 nssm.exe。


G. 推荐顺序(快速部署建议)

  1. 在本地命令行测试每个脚本能否正常运行并写日志。
  2. 若需要“开机就运行(登录前)”,先用 nssm 注册服务(A)。测试并查看日志。
  3. 若选择前台方案,使用 B 启动后端;若后端已由 A 负责,登录任务仅打开日志或独立监控界面,不重复运行 run_all.bat。
  4. 最后优化:延时、错误重试、日志轮转、避免重复启动。

文章作者: 0xdadream
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 0xdadream !
赏
评论

评论将在接近此处时加载,也可点击立即加载。

  目录