The goal is to open a particular excel file using a python shell subprocess. The code cannot be more simple yet I cannot figure out what is wrong:
import subprocess
arg1 = "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\EXCEL.EXE"
arg2 = "C:\\Users\\user\\Documents\\test.xlsm"
p = subprocess.Popen(["start", arg1, arg2], shell=False)
The command works perfectly directly on the shell but when done through subprocess throws the following error:
FileNotFoundError: [WinError 2] The system cannot find the file specified
I have also tried the below which works equally fine directly on the shell but the behavior is different:
p = subprocess.Popen([arg1, arg2], shell=False)
The following failed assertion pops up from Excel:
snapshopt error
My next try was:
import os
os.system("C:\\Users\\user\\Documents\\test.xlsm")
Which replicates the same assertion error as above plus returns a code 3 which based on
System Error Codes (0-499)
is a path not found.
Again same path works on shell, at this stage I run out of ideas, any help?
os.startfile is actually a better way to do it. As specified in the documentation -
os.startfile(path[, operation])
Start a file with its associated application.
When operation is not specified or 'open', this acts like
double-clicking the file in Windows Explorer, or giving the file name
as an argument to the start command from the interactive command
shell: the file is opened with whatever application (if any) its
extension is associated.
When another operation is given, it must be a “command verb” that
specifies what should be done with the file. Common verbs documented
by Microsoft are 'print' and 'edit' (to be used on files) as well as
'explore' and 'find' (to be used on directories)
You can just do the following -
import os
os.startfile("C:\\Users\\user\\Documents\\test.xlsm")
Related
I am making use of Beyond Compare 3 to see the difference between two XML files. I am willing to make a small python script which on executing will open files ready to compare in Beyond Compare tool.
So far I tried invoking BC3 from command line syntax as below and it works:
BCompare.exe "c:\Ref-2.xml" "c:\Cop-2.xml"
but when I try to execute same syntax from python script as shown below, It throws error
from subprocess import check_output
check_output('BCompare.exe "c:\Ref-2.xml" "c:\Cop-2.xml"', shell=True)
The error which is shown is:
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'BCompare.exe "c:\Ref-2.xml" "c:\Cop-2.xml"' returned non-zero exit status 1
am I missing something? I tried different solutions to open command line instructions using this tutorial and many others but its not working.
Do something like this. Give Absolute path of .exe
check_output(absolute_path_of_beyond_compare "c:\Ref-2.xml" "c:\Cop-2.xml"', shell=True)
I am able to open the Beyond Compare using following code:
from subprocess import check_output
check_output("BCompare.exe Test1.txt Test2.txt", shell=True)
where BCompare.exe path is added in path variable and Test1.txt Test2.txt are present in the same directory from where i have executed the program.
import subprocess
subprocess.Popen([r"C:\Program Files\Beyond Compare 4\BCompare.exe", r"FullFilePath_File1", r"FullFilePath_File2"])
I tested on mine, and it works.
Instead of checkout, I am using Popen.
I am using Jupyter notebook by installing Anaconda3-5.2.0-Windows-x86_64
Python version = 3.6.5
use exact path where the beyond compare is installed or add that to your environment variable "Path".
in case using exact path of installation put something line "\"C:\Program Files\Beyond Compare 4\BCompare.exe\" test1.txt test2.txt"
the \" enables to read the special characters and extra spaces in path
With Python 3.4.2 on Windows I want to open the explorer with the folder of the currently running script like this:
import os, subprocess
subprocess.check_call(['explorer', os.path.dirname(__file__)])
Instead I see that the explorer is opened by with a default folder
"C:\Users\XX\Documents" and an error is thrown:
Traceback (most recent call last):
File "C:/XXX/YYY.py", line 9, in <module>
subprocess.check_call(['explorer', os.path.dirname(__file__)])
File "C:\Python34\lib\subprocess.py", line 561, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['explorer', 'C:/XXX']' returned non-zero exit status 1
and although os.path.dirname returns paths with slashes on Windows (backslashes are path seperators) you can copy and paste it into the explorer and it will open the location just fine. (XXX is the path part, YYY the file name part)
Furthermore, if you manually write the path as it is in the explorer (with backslashes), even then the command fails.
subprocess.check_call(['explorer', r'C:\Users'])
But at least the explorer will open the right directory despite of throwing the same error (so maybe using call instead of check_call).
What's going on here? How can I show the folder of the running Python script file in the explorer?
You need to send the absolute path to the directory by calling os.path.abspath, and switch check_call with call (as you suspected).
import os
import subprocess
dirname = (os.path.dirname(os.path.abspath(__file__)))
subprocess.call(['explorer', dirname])
subprocess.check_call raises an exception if the return code of the process is nonzero. Even when explorer doesn't actually have an error, it has a non-zero return status, so you get an exception.
That's actually unrelated to the problem, though. The problem is that you were passing a string with forward slashes to explorer. This would have happened if you called your script like python path/to/script.py instead of python path\to\script.py. If you pass the absolute path to subprocess.call, explorer will open in the right directory. You would get the same error if you passed an empty string as the second arg to subprocess.call.
You need to use backslashes in your paths for windows explorer to undestand them. Testing from the command line, this works:
> explorer C:\Users
But this doesn't
> explorer C:/Users
Use os.path.normpath to convert the forward slashes into back slashes
Note that abspath, according to the docs, is implemented as normpath(join(os.getcwd(), path)), so the other solution also addresses this issue.
I am attempting to scrape a terminal window of the list of fonts installed on the curent hosting server. I have written the following code:
import subprocess
cmd = 'fc-list'
output = subprocess.Popen(cmd, stdout=subprocess.PIPE ).communicate()[0]
but when i call this code, an exception is raised:
[Errno 2] No such file or directory
I can open a terminal window, and this works fine. What am i doing wrong?
You need to provide the absolute path to the executable. When you open a terminal window you then have a shell running which will search in $PATH to find the program. When you run the program directly, via subprocess, you do not have a shell to search $PATH. (note: it is possible to tell subprocess that you do want a shell, but usually this leads to security vulnerabilities)
Here is what you would want to use:
import subprocess
cmd = '/usr/local/bin/fc-list'
output = subprocess.Popen(cmd, stdout=subprocess.PIPE ).communicate()[0]
I am trying to run a simple command in python:
from subprocess import *
check_output("ls")
When I run this it raises
Error:
WindowsError: [Error 2] The system cannot find the file specified
ls doesn’t exist on Windows; dir does. Furthermore, you may need to pass shell=True, since it’s built in to cmd.exe.
If it’s not a test and you just want to get the contents of a directory, use os.listdir instead.
I have this simple script..that does not work
import subprocess
subprocess.call(["C:\Program Files\Oracle\VirtualBox\VBoxManage.exe", "VBoxManage startvm WIN7"])
I have the same thing in a bat file...which works perfectly.
cd C:\Program Files\Oracle\VirtualBox
VBoxManage startvm "WIN7"
I have the VBoxManage.exe in the PATH of Windows 8.1 (My host OS).
The python script understands the VBoxManage executable and spits out it's manual and then this ..
Syntax error: Invalid command 'VBoxManage startvm WIN7'
Could you give me a way to start a VM from inside a python script, either by invoking the .exe directly or by running the .bat file ?
Note: I have searched for the vboxshell.py file but not found it anywhere...:[
subprocess.call() expects a list of arguments, like so:
subprocess.call(['C:\Program Files\Oracle\VirtualBox\VBoxManage.exe',
'startvm',
'WIN7'])
Your code passes 'VBoxManage startvm WIN7' as a single argument to VBoxManage.exe, which expects to find only a command (e.g. 'startvm') there. The subsequent arguments ('WIN7' in this case) need to be passed separately.
In addition, there is no need to repeat the executable name when using subprocess.call(). The example from the Python docs invokes the UNIX command "ls -l" as follows:
subprocess.call(['ls', '-l'])
In other words, you don't need to repeat the 'VBoxManage' part.
The trick is to pass the command as separate arguments
import subprocess
subprocess.call(["C:\Program Files\Oracle\VirtualBox\VBoxManage.exe", "startvm", "WIN7"])