如何从批处理文件 (parent.bat) 执行批处理脚本 (child.bat)?原始问题C# 以编程方式在 Venv 中运行 Pip 安装 用于运行多个 cmd 语句的 C# 代码它会创建一个批处理文件已创建批处理文件cmd 输出:

问题描述

我最初的问题是“C# 以编程方式在 Venv 中运行 Pip 安装”,但结果证明 C# 代码或 Pip 没有问题。但是使用批处理脚本。所以首先是经过编辑的问题以帮助他人,然后是我的原始问题,仅供记录。

使用命令运行批处理脚本以运行另一个批处理文件

child.bat

@echo off
echo Child Batch File is running !!!
echo Doing some Important Child Batch Stuff here . . . .
echo ✔ Child Batch Completed it. Voila !!
echo Now exiting Child.bat

parent.bat

@echo off
echo Parent Batch File is running !!!
echo Doing some Important Stuff here . . . .
echo ✔ Completed it. Voila !!
echo Now running Child.bat . . .

echo -------------------------------------------------------

child.bat

// Comment: Some how below statements are not executing
echo -------------------------------------------------------

echo ✔ Completed it. Voila !!
echo I believe all the this are complete.
echo I am Now exiting.

输出

C:\Users\abc> parent.bat

Parent Batch File is running !!!
Doing some Important Stuff here . . . .
✔ Completed it. Voila !!. .
Now running Child.bat . . .
-------------------------------------------------------
Child Batch File is running !!!
Doing some Important Child Batch Stuff here . . . .
✔ Child Batch Completed it. Voila !!
Now exiting Child.bat

C:\Users\abc>

其他 parent.bat echo 命令在哪里。

预期输出

Parent Batch File is running !!!
Doing some Important Stuff here . . . .
✔ Completed it. Voila !!. .
Now running Child.bat . . .
-------------------------------------------------------
Child Batch File is running !!!
Doing some Important Child Batch Stuff here . . . .
✔ Child Batch Completed it. Voila !!
Now exiting Child.bat
-------------------------------------------------------
Completed it. Voila !!
echo I believe all the this are complete.
echo I am Now exiting.


老问题只是记录

我有一个 C# 应用程序,它使用了一些 Python 脚本。要运行 python 脚本,我需要有一些依赖项。所以我创建了一个批处理文件来创建一个 VENV。但它从不运行 PIP 安装命令。

用于运行多个 cmd 语句的 C# 代码。它会创建一个批处理文件

        public void abc() {
            var batFileName = Path.Combine(Path.GetTempPath(),$"{Guid.NewGuid()}.bat");
            using (var batFile = new StreamWriter(batFileName))
            {
                var pythonPath = Path.Combine(LocalAppData,ProjectGuid,HolocronFolders["HolocronPython"]);
                var venv = Path.Combine(LocalAppData,HolocronFolders["HolocronVenv"]);
                batFile.WriteLine($"{pythonPath}\\python.exe -m venv {venv}");
                batFile.WriteLine($"{venv}\\Scripts\\activate.bat");
                batFile.WriteLine($"pip install rich"); //  Not running in venv
            }
            var process = new Process();
            var startInfo = new processstartinfo
            {
                FileName = "cmd.exe",Arguments = $"/C {batFileName}"
            };
            process.StartInfo = startInfo;
            process.Start();
            File.Delete(batFileName);
        }

已创建批处理文件

Path_to_python\python.exe -m venv path_to_venv_folder
Path_to_venv_folder\Scripts\activate.bat
pip install rich            --//-- Comments: Not running in Venv. Actually not running at all.

cmd 输出

c:\user\abc> Path_to_python\python.exe -m venv path_to_venv_folder
c:\user\abc> Path_to_venv_folder\Scripts\activate.bat
(path_to_venv_folder) c:\user\abc> 

解决方法

当从命令或脚本执行另一个批处理文件时,上下文将更改为该批处理文件,并且父文件命令以某种方式丢失。 正如 @Squashmas 所说“为了将控制权传递回父批处理文件,必须使用 CALL 命令调用子批处理文件”

child.bat

@echo off
echo Child Batch File is running !!!
echo Doing some Important Child Batch Stuff here . . . .
echo ✔ Child Batch Completed it. Voila !!
echo Now exiting Child.bat

父.bat

@echo off
echo Parent Batch File is running !!!
echo Doing some Important Stuff here . . . .
echo ✔ Completed it. Voila !!
echo Now running Child.bat . . .

echo -------------------------------------------------------

rem Comments: CALL will execute the .bat and return the cmd context back to the parent.bat for further execution.
CALL child.bat   

echo -------------------------------------------------------

echo ✔ Completed it. Voila !!
echo I believe all the this are complete.
echo I am now exiting.

记录的旧答案。

所以批处理脚本中的命令应该是:

Path_to_python\python.exe -m venv path_to_venv_folder
CALL Path_to_venv_folder\Scripts\activate.bat
pip install rich

CALL activate.bat 会将 cmd 上下文传递回父批处理文件。

我在这里所做的几乎与使用 CALL 相同。我不推荐这个。使用呼叫。

Path_venv_folder\Scripts\activate.bat && pip install rich

由于 && 操作符,在第一条命令运行后,由于命令尚未完成,因此父级调用的 cmd 上下文仍然存在,并且在这种情况下,cmd 上下文未传递给子批处理脚本 {{1 }} 直到执行整个命令并返回 activate.bat 或等效项。

使用 true 的输出是:

CALL

使用 c:\user\abc> Path_to_python\python.exe -m venv path_to_venv_folder c:\user\abc> CALL Path_to_venv_folder\Scripts\activate.bat (path_to_venv_folder) c:\user\abc> pip install rich installing rich.............. installing colorama.................... blah blah blah (path_to_venv_folder) c:\user\abc> 的输出是:

&&

请注意,执行 c:\user\abc> Path_to_python\python.exe -m venv path_to_venv_folder c:\user\abc> CALL Path_to_venv_folder\Scripts\activate.bat && pip install rich installing rich.............. installing colorama.................... blah blah blah (path_to_venv_folder) c:\user\abc> 命令后会显示 venv 激活的 cmd。尽管 pippip 的上下文中运行,但它并不准确,因此我不推荐它。

PS:我不是批处理脚本专家,所以如果我错了,请纠正我。我会尽快改进。

一些参考资料:

CALL | Microsoft Docs