这是 Windows 定时任务最常见的问题,核心原因是任务运行时的工作目录、权限或执行环境和你双击运行时不一样。下面按「从最常见到最隐蔽」的顺序,一步步排查修复:
🔍 第一步:优先修复「工作目录问题」(90% 的情况都是这个)
你双击 exe 时,程序的当前工作目录 就是 exe 所在的文件夹,所以能找到 config.json 并生成日志。
但定时任务默认的工作目录是 C:\Windows\System32,程序在这里找不到 config.json,直接静默退出,自然也不会生成日志。
修复方法:
- 打开任务属性 → 切换到「操作」选项卡
- 选中你的任务,点击「编辑」
- 关键设置:在「起始于(可选)」输入框中,填写你的 exe 所在文件夹的完整路径
- 比如你的 exe 在
D:\scripts\file_mover,就填D:\scripts\file_mover - 注意:不要加引号,不要写 exe 文件名,只写文件夹路径
- 比如你的 exe 在
- 点击「确定」保存,再运行任务测试
🔍 第二步:权限问题(第二常见原因)
如果程序需要读取/写入某些目录,而定时任务的权限不足,会导致静默失败。
修复方法:
- 打开任务属性 → 切换到「常规」选项卡
- 勾选以下两个选项:
- ✅「使用最高权限运行」
- ✅「不管用户是否登录都要运行」(如果服务器经常没人登录,必须勾这个)
- 点击「更改用户或组」,选择你的管理员账号,确保有权限访问源/目标目录
🔍 第三步:路径写法问题(容易踩坑)
你的脚本里,config.json 和日志文件是相对路径写法,依赖当前工作目录。如果第一步的「起始于」设置正确就没问题,但可以做个兜底优化:
临时快速验证方法:
把你的脚本改成绝对路径读取配置和日志,彻底避免路径问题:
python
# 在脚本开头,获取 exe 所在目录(打包后也生效)
import sys
import os
BASE_DIR = os.path.dirname(os.path.abspath(sys.argv[0]))
CONFIG_PATH = os.path.join(BASE_DIR, "config.json")
LOG_PATH = os.path.join(BASE_DIR, "run_log.log")
# 然后修改日志配置和加载配置的地方,使用 LOG_PATH 和 CONFIG_PATH
# 日志配置部分:
log_handler = TimedRotatingFileHandler(
filename=LOG_PATH,
when="midnight",
interval=1,
backupCount=30,
encoding="utf-8",
delay=True
)
# 加载配置部分:
def load_config():
if not os.path.exists(CONFIG_PATH):
# 这里可以改成写入错误日志到 BASE_DIR
print(f"配置文件不存在: {CONFIG_PATH}")
raise FileNotFoundError(...)
with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
return json.load(f)
修改后重新打包 exe,再测试定时任务。
🔍 第四步:排查程序是否真的启动了
- 打开「任务管理器」→「详细信息」,手动运行定时任务,看
file_mover.exe是否出现 - 如果进程一闪而过,说明程序启动了但立刻退出了,大概率是找不到配置文件;如果完全不出现,说明任务根本没触发
- 打开「事件查看器」→「Windows 日志」→「系统/应用程序」,筛选来源为「TaskScheduler」的事件,看任务是否有报错记录
🔍 第五步:其他隐蔽问题排查
- 防病毒软件拦截:部分服务器的安全软件会拦截定时任务启动的 exe,检查杀毒软件的日志,把你的 exe 加入白名单
- 任务设置里的「条件」选项卡:取消勾选「只有计算机使用交流电源时才启动此任务」,服务器可能默认开启了节能设置
- 任务设置里的「设置」选项卡:勾选「允许按需运行任务」,并设置「如果任务已在运行,则停止现有实例」为「并行运行」
快速排查顺序建议
先做第一步(设置「起始于」路径),再做第二步(最高权限运行),90% 的问题都能解决。如果还是不行,用修改后的脚本(绝对路径)重新打包测试,就能彻底定位问题。
需要我帮你写一个带「绝对路径兜底」的完整脚本,直接替换原来的代码吗?