I tried to open "Developer Command Prompt for VS 2017" from Python, write some command within like cd .., and then run an exe.
However it doesn't let me to write commands at all.
I have tried:
process = subprocess.Popen('C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\Tools\\VsDevCmd.bat',
shell=False, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=None)
process.stdin.write('1.txt'.encode(encoding='utf_8', errors='strict'));
output = process.stdout.readlines()
print(output)
When I open the developer command promtpt on my own it is directed to c:\>.
So, I saved c:\ in a text file called 1.txt to know if it's run the command within Python. However, in the Python console I only get the welcome text:
[b'**********************************************************************\r\n',
b'** Visual Studio 2017 Developer Command Prompt v15.5.2\r\n',
b'** Copyright (c) 2017 Microsoft Corporation\r\n',
b'**********************************************************************\r\n']
The issue is with VsDevCmd.bat closing before you can communicate with the generated subprocess as i believe
Your method works but it is better if you use communicate instead of directly sending input to stdin:
output = communicate('cd c: \n')[0]
Check the documentation on communicate
You can run the same code above using communicate and calling CMD instead :
process = subprocess.Popen('cmd',shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None)
output = process.communicate('dir\n')[0]
print output
Related
i have issue which drives me crazy.
i have a command to be executed which success in CMD and fails in windows power shell. i am trying to execute this command from python, but it seems that python executing it using powershell. is it possible to force it to use cmd?! also i need to read the output of the command.
command is :
sfdx force:org:list
Python code :
import subprocess
climain = "sfdx force:org:list"
query = subprocess.check_output(climain, shell=True)
return json.loads(query)
so i need to force python to use cmd instead of powershell and return the output.
UDPATE 1 :
i have tried this .. to force working with cmd
>>> import subprocess
>>> proc = subprocess.Popen('cmd.exe', stdin = subprocess.PIPE, stdout = subprocess.PIPE)
>>> stdout, stderr = proc.communicate('IPCONFIG')
>>> stdout
but its not printing the output of IPCONFIG command.. it just gives this.
Microsoft Windows [Version 10.0.17763.195] (c) 2018 Microsoft Corporation. All rights reserved. (venv) C:\Users\webapp\Desktop\ed1\ed1>More?
If I want to run my Python 3.8 program in Windows 10, I have to firstly load below commands in PowerShell:
PS> cmd
CMD> call [somePath]/environmentSettingScript.bat
CMD> set Path=%Path%;D:[someOtherPath]\win64
After that, I am able to run Python in the same window (still CMD running in PS) and load my third party libraries.
CMD> python
>>> from thirdPartyLibrary import something
or
CMD> python programThatUseThirdPartyLibrary.py
Of course, it works also, if I make call and set procedures from first snippet directly in CMD. Nevertheless, I don't like such kind of solutions. I want to automatize this procedure, in programThatUseThirdPartyLibrary.py code directly with Spyder IDE usage. To do this I try write something like that:
import subprocess
pipe = subprocess.Popen(r"cmd \c call [somePath]/environmentSettingScript.bat \c set Path=%Path%;D:[someOtherPath]\win64",
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
encoding='utf8',
shell=True)
stdout, stderr = pipe.communicate()
print("No stderr" if pipe.returncode == 0 else "Some stderr")
from thirdPartyLibrary import something
Unfortunately, stdout shows only the information about loading first line of cmd command:
Microsoft Windows [Version 10.0.17763.1697]
(c) 2018 Microsoft Corporation. All rights reserved.
D:\[workDir]>
and it looks like, that the rest of commands stuck in the pipe. I am quite confused, because print() and stderr shows that, everything goes ok - but import at the end of the script fails with error
ModuleNotFoundError: No module named thirdPartyLibrary
Here's the script snippet:
import subprocess
output = subprocess.run(["psexec.exe",
"\\\\<machine-name>",
"/u", "<machine-name>\\TestAdmin",
"/p", "<password>",
"cmd /c dir"],
capture_output=True,
text=True,
shell=True)
print(output.stdout)
print(output.stderr)
And here's the output I get:
E:\python-scripts>python runpsexec.py
PsExec v2.11 - Execute processes remotely
Copyright (C) 2001-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
The system cannot find the path specified.
Connecting to <machine-name>...
Starting PSEXESVC service on <machine-name>...
Connecting with PsExec service on <machine-name>...
Starting cmd /c dir on <machine-name>...
PsExec could not start cmd /c dir on <machine-name>:
I also tried passing in the -s option to run it as a system account. If I directly run psexec from cmd prompt, I'm able to run the same command and get the right output.
Are there any limitations in running psexec via subprocess.run()? Or am I missing something?
i have a powershell script i'm trying to execute via python subprocess. i use check_output imported from subprocess for other cmd line processes, so i am using it for the powershell script. inside my powershell script i'm loading some 3rd party modules and then executing a cmdlet from those modules. here is my python code..
from subprocess import Popen, STDOUT, check_output
cmd = 'C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe -nologo -file c:\\test.ps1'
cmd_output = check_output(cmd, stderr=STDOUT)
output = cmd_output.decode("utf-8").split('\n')
When the python code runs it takes some time where i assume it's loading the modules via the code i have in the powershell ps1 script , BUT i get an error that the cmdlet i was referencing inside my powershell script is "not recognized as the name of a cmdlet", which happens when the modules don't get loaded properly in the powershell script, so i don't think my modules are loading which is weird.. i also noticed when the ps1 script loads via python it runs for about 10 secs then returns, if i run the ps1 script (see further below) manually from command line it usually takes 60 secs to load the modules inside the ps1 script.
i also tried another method for sub proccess instead of check_output, see below, with no differences
cmd = Popen(['powershell.exe', '-nologo', '-file', 'c:\\test.ps1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
BUT i can open a cmd window and execute it manually perfectly fine using
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -nologo -file C:\test\test.ps1
which should be the same as i'm already doing in python :( so i'm at a loss why it's not working in python??
also my execution policy is as follows
PS C:\> Get-ExecutionPolicy -list
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Unrestricted
LocalMachine Unrestricted
Try using unrestricted ExecutionPolicy parameter :
# python 2.7 and 3.4
import subprocess
fname = "C:\\Demo\\test.ps1"
p = subprocess.Popen(["powershell", "-ExecutionPolicy", "unrestricted", "-nologo", "-file", "%s"%(fname)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode == 0:
print("buffer :")
print(out)
else:
print("error :")
print(err)
The content of 'C:\Demo\test.ps1'
write-host $env:USERPROFILE;
Get-ExecutionPolicy -list;
try{
Get-Module -Name VMware.VimAutomation.Core -ListAvailable | Import-Module;
write-host 'ok import VMware';
}catch{
write-host 'error import VMware';
write-host $_;
}
The output after script execution (note the Process policy)
buffer :
C:\Users\MyUserName
ok import VMware
Scope ExecutionPolicy
----- ---------------
... ...
... ...
Process Unrestricted
... ...
... ...
On system32 Module path is here:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\
Try using:
p = subprocess.Popen(["powershell", "-ExecutionPolicy", "unrestricted", "-nologo", "-command", "&{ Get-Module –ListAvailable }"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for showing all available modules
I'm getting a slightly weird result from calling subprocess.Popen that I suspect has a lot to do with me being brand-new to Python.
args = [ 'cscript', '%USERPROFILE%\\tools\\jslint.js','%USERPROFILE%\\tools\\jslint.js' ]
p = Popen(args, stdout=PIPE, shell=True).communicate()[0]
Results in output like the following (the trailing double \r\n is there in case it's important)
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\n
If I run that command from an interactive Python shell it looks like this
>>> args = ['cscript', '%USERPROFILE%\\tools\\jslint.js', '%USERPROFILE%\\tools\jslint.js']
>>> p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=True).communicate()[0]
Lint at line 5631 character 17: Unexpected /*member 'OpenTextFile'.
f = fso.OpenTextFile(WScript.Arguments(0), 1),
...
Lint at line 5649 character 17: Unexpected /*member 'Quit'.
WScript.Quit(1);
So there's all the output I really care about, but if I dump the value of the "p" variable I just set up...
>>> p
'Microsoft (R) Windows Script Host Version 5.8\r\nCopyright (C) Microsoft Corpor
ation. All rights reserved.\r\n\r\n'
>>>
Where'd all that data I want end up going? It definitely didn't end up in "p". Looks like it's going to stdout, but I didn't I explictly tell it not to do that?
I'm running this on Windows 7 x64 with Python 2.6.6
Is it going to stderr? Try redirecting:
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).communicate()[0]
It's probably going to stderr, as SimonJ suggested.
Also, the docs say not to use shell=True in Windows for your case:
The executable argument specifies the
program to execute. It is very seldom
needed: Usually, the program to
execute is defined by the args
argument. If shell=True, the
executable argument specifies which
shell to use. On Unix, the default
shell is /bin/sh. On Windows, the
default shell is specified by the
COMSPEC environment variable. The only
reason you would need to specify
shell=True on Windows is where the
command you wish to execute is
actually built in to the shell, eg
dir, copy. You don’t need shell=True
to run a batch file, nor to run a
console-based executable.
Later: oh wait. Are you using the shell to get those environment variables expanded? Okay, I take it back: you do need the shell=True.