运行 来自 windows 任务调度程序的虚拟环境中的 python 脚本

Run a python script in virtual environment from windows task scheduler

我正在尝试通过 windows 任务计划程序设置重复性 Python 任务。

当我输入 'python.exe' 的路径并将脚本的路径作为参数提供给 windows 任务计划程序时,我已经成功了(见下面的屏幕截图)

但是,我希望能够选择一个特定的虚拟环境来 运行 脚本。我对 venv 了解不多,我通常通过在所需的虚拟环境目录中打开 cmd 和 运行ning Scripts\activate.bat 来使用它。

如何使用 windows 任务计划程序完成 'run task x in venvxxx every 24 hours'?

使用这些命令创建批处理文件:

c:\__full_path_to_virtualenv__\Scripts\activate.bat && python __full_path_to_python_script__.py

&& 表示 运行 command2 如果 command1 成功完成。

然后将该批处理文件设置为脚本 运行。您不需要在任务计划程序中设置任何其他参数(或者您可以在批处理文件中设置它们)并且可以设置 Start in 如果脚本必须从特定的 read/write目录并使用相对路径。

虽然上面 mx0 的回答似乎有效,但我已经将任务计划程序设置为 运行 启动时的烧瓶网络应用程序。在这种情况下,手动开始可以正常工作,但手动结束则不行。结束任务会终止设置虚拟环境的 cmd.exe 任务,但 python.exe 会继续 运行。

我发现有效的解决方案来自 this reddit post,它跳过虚拟环境激活直接调用 python 可执行文件:

path\to\venv\Scripts\python.exe path\to\script.py

我不确定这会有多稳健,但至少这样结束任务会结束 python.exe

这比较冗长但很容易理解,而且 - 我发现最重要的 - 比在有很多脚本时使用 Windows 任务计划程序设置容易得多。要创建另一个,您只需复制 .bat 文件并更改一行。

将其另存为 .bat 文件并在 Actions > Start a Program > Program/Script: 下指向它,无需参数或 "Start in" 必要。

set original_dir=%CD%
set venv_root_dir="C:\Python-Venvs\env-name"
cd %venv_root_dir%
call %venv_root_dir%\Scripts\activate.bat

python your_script.py <arg1> <arg2>

call %venv_root_dir%\Scripts\deactivate.bat
cd %original_dir%
exit /B 1

对于已安装的命令行程序,您可以将 python your_script.py <arg1> <arg2> ... 替换为 <program name> <arg1> <arg2> ...

此外,在下一行添加另一个脚本很简单,而不是尝试将顺序脚本解析为任务计划程序的一行。

我尝试了 mx0 的答案,只要您的脚本完成时间不会太长,它就可以正常工作。

我在任务计划程序中使用了不同的方法,而不是使用批处理文件:

在 "Program/script" 文本框中,您将路径设置为 Python 可执行文件(在我的例子中是在 virtualenv 文件夹中)。

"Add arguments" => 只是您的 Python 脚本的名称 (name.ppy).

"Start in" => Python 脚本的完整路径(没有 name.py)。

这样脚本运行并等待结束。

我的解决方案与mx0 几乎相同,但我添加了一个额外的步骤来确保每次都设置环境参数。为 app_path 变量编辑 path/to/app

每次都检查环境设置可能有点多余,但我喜欢确保我的环境已设置好。

只需在 cmd 提示符中安排 execute_app.bat 文件或 运行。除非从 Anaconda 提示中 运行ning,否则不需要停用命令。如果您使用 path/to/app 的完整路径,则可以从任何目录执行此文件。我还有一个 Linux 解决方案,使用下面的 execute_app.sh 文件来自终端。

这个答案已经过编辑以简化,并使用变量使其更容易适应新项目。

应用结构:
app/bin/app.py
app/bin/execute_app.bat
app/env/requirements.txt

# execute_app.bat file
# windows solution

SETLOCAL
set app_path=path/to/app
set env_path=%app_path%/env
set activ=%env_path%/Scripts/activate.bat
set req=%env_path%/requirements.txt
set app=%app_path%/bin/app.py

py -m venv %env_path% && %activ% && python -m pip install --upgrade pip && pip install -r %req% && python %app%
ENDLOCAL
#!/bin/bash

# execute_app.sh file
# Linux solution

app_path='path/to/app'
env_path=$app_path'/env'
activ=$env_path'/bin/activate'
req=$env_path'/requirements.txt'
app=$app_path'/bin/app.py'

python3 -m venv $env_path &&
. $activ &&
python3 -m pip install --upgrade pip &&
pip install -r $req &&
python $app &&
deactivate
REM Windows batch script to run 1+ Python program/scripts, sequentially, within
REM their virtual environment. This can be called from Windows Task Scheduler.
        
set original_dir=%CD%

set venv_root_dir="C:\Users\myUsername\myProjects\nameOfProject"
        
cd %venv_root_dir%
        
call %venv_root_dir%\Scripts\activate.bat
        
python nameOfPythonProgram.py
        
call %venv_root_dir%\Scripts\deactivate.bat
        
cd %original_dir%
    
exit /B 1

从 github 上的 nmpowell 复制了这个,它工作正常。 运行 来自任务计划程序

创建 bat 文件以启动 Python 脚本在启动进程时起作用,但在停止进程时不起作用。当 taskengine.exe 决定停止工作时,bat 进程被终止,Python.exe 将成为稻草。

恕我直言,最好的方法是创建一个实用程序模块,例如patch_conda_path 根据 sys.base_exec_prefix.
修补 os.environ 中的 PATH 例如

import is, sys
conda_base = sys.base_exec_prefix
subps = [";", "library\mingw-w64\bin;", "library\usr\bin;", "library\bin;", "scripts;", "bin;", "condabin;"]
conda_paths = ""
for p in subps :
    _p = os.path.join(conda_base, p)
    if _p in os.environ["PATH"]:
        continue
    else:
        conda_paths += _p
os.environ["PATH'"] = conda_paths + os.environ["PATH"]

在主脚本的最开始导入这个模块。 将 task scheduler 中的 program 设置为 ... conda path...\python.exe,将 arguments 设置为您的 py 脚本文件名,并将 start in 设置为您的 py 脚本文件夹。

这也适用于 conda3 中女服务员的烧瓶脚本 运行。

这个问题选择的答案不正确。如果您查看评论,就会发现问题所在。

我的回答基于@Nick P 的回答(目前排名第二)。他的批处理文件可以工作,但如果您希望 Windows 任务计划程序报告任务已成功完成,您需要将退出代码从 1 更改为 0。此外,仅在“Program/Script”行调用 .bat 文件将不起作用。相反,您需要将您的 shell 的名称作为“Program/Script”添加到 运行(例如,cmd),然后添加“/c name-of-batch-file.bat”进入“添加参数(可选):”字段。最后,将批处理文件的路径(减去文件名)放在“开始于(可选):”字段中。

它应该看起来像这样: