My original question was "C# run Pip install in Venv programmatically" but it turns out there was no issue with C# code or the Pip thing. But with the Batch Script. SO first is the edited question to help others and then my original question for just a record.
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.
Output:
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>
Where are the other parent.bat
echo commands.
Expected Output:
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.
I have a C# application and it uses some python scripts. To run the python scripts I need to have some dependencies. So i created a batch file that creates a VENV. But it never runs PIP INSTALL COMMAND.
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, ProjectGuid, 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.
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>
When another batch file is executed from a command or a script the context is changed to that batch file and the parent file commands are lost somehow.
As @Squashmas says "In order for control to be passed back to the parent batch file, the child batch file must be invoked with the CALL
command"
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 -------------------------------------------------------
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.
So the commands in the batch script should be:
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
will pass the cmd context back to the parent batch file.
What I did here is almost the same as using CALL. I don't recommend this. Use CALL.
Path_venv_folder\Scripts\activate.bat && pip install rich
After the first command is run due to the &&
operator context is still with the parent invoked cmd as the command is yet complete and the cmd context is not passed to the child batch script in this case activate.bat
until the whole command is executed and true
or equivalent is returned.
The output using CALL
is:
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>
The output using &&
is:
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>
Notice the venv
activated cmd is shown after the pip
command is executed. Although the pip
ran in context of the venv
it is not accurate and so I don't recommend it.
PS: I am not a batch script expert so please correct me if I am wrong. I will improve it asap.
Some References: