Call a command in the VS developer command prompt programmatically

Viewed 722

Introduction

I am trying to call a command ('nmake') that needs to be run from inside the VS Developer Command Prompt using Subprocess.Popen in python.

Setting the path for it won't work for my case.

I tried reading the docs and it didn't seem like there is a way to use something other than the default CMD.exe.

My code

import subprocess

command = ['nmake']
with subprocess.Popen(["nmake"],
                      executable=r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsMSBuildCmd.bat",
                      stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                      universal_newlines=True) as process:
    print(process.stdout.readlines())
    print(process.stderr.readlines())

Exception

It currently throws

'nmake' is not recognized as an internal or external command

so it's not actually using the executable provided there.

Notes

System used : Windows 10, python3.8

2 Answers

This probably happens in the cases in handling quotes in path filename. Few things which you can try:

  1. In popen argument add shell=True this causes subprocess to spawn an intermediate shell process, and tell it to run the command
  2. Use executable = [r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsMSBuildCmd.bat"]

I FINALLY(!!) managed to get this kind of thing done, with cmake. I've been struggling with this thing for the whole day, nothing on google was able to solve this in such a concise manner.

I use the VS Developer Command Prompt to run cmake with -GNinja for my CMake project in Windows, like "cmake -GNinja" but I needed to use python to run this automatically, here's how:

For running without Python, just in a regular cmd.exe / powershell, what you should do is run this, notice the "&" to chain the commands:

C:\"Program Files (x86)"\"Microsoft Visual Studio"\2019\BuildTools\Common7\Tools\VsDevCmd.bat "&" cmake ..\src -GNinja

You can put this in a .bat file to run that file from some script, or do something like this in Python:

os.chdir("C:\\git\\project\\build") # Changing to the build dir next to the project's src dir to build it with cmake.

os.system('C:\\"Program Files (x86)"\\"Microsoft Visual Studio"\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat' + "&" + 'cmake ..\\src -GNinja')  # Running cmake inside VS Developer CMD Prompt to get all the necessary libs and compilers automatically.

Example output from pycharm:

"C:\Program Files\Python38\python.exe" C:/git/automation/123.py
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.10.3
** Copyright (c) 2021 Microsoft Corporation
**********************************************************************
-- The C compiler identification is MSVC 19.29.30038.1
-- The CXX compiler identification is MSVC 19.29.30038.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.29.30037/bin/Hostx86/x86/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.29.30037/bin/Hostx86/x86/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/git/project/build

Process finished with exit code 0

Afterwards if you want to use the ninja "make" to build some targets it's the same thing:

os.system('C:\\"Program Files (x86)"\\"Microsoft Visual Studio"\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat' + "&" + 'ninja <targetName>')

I assume that for your nmake it will be something similar to this:

os.system('C:\\"Program Files (x86)"\\"Microsoft Visual Studio"\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat' + "&" + 'nmake')

Hope it solves your problem as it has for me.

Related