Executing a vbs file with arguments created by python - python

I would like to convert dozens of excel sheets to csv files at once. I have a working .vbs file which makes the conversion, and I would like to execute this .vbs file on the different sheets with the help of a python code. I have the following 2 versions of the python code:
Version 1:
import os
import sys
import subprocess
FolderName=sys.argv[1]
FileList=os.listdir(FolderName)
NewList=[]
for i in FileList:
NewItem=i.split('.xls')
NewXls=FolderName+"\\"+NewItem[0]+".xlsx "
NewCsv=FolderName+"\\"+NewItem[0]+".csv"
NewCommand="C:\\Users\\user\\XlsToCsv.vbs "+sys.argv[2]+" "+NewXls+NewCsv
subprocess.call(NewCommand)
Version 2:
import os
import sys
import subprocess
def main(directory,extension,sheet):
for filename in os.listdir(directory):
if filename.endswith(extension):
path = os.path.join(directory, filename)
base = os.path.join(directory, filename[:len(filename)-len(extension)])
print base
new_xls = base + extension
new_csv = base + '.csv'
subprocess.call(['C:\\Users\\user\\XlsToCsv.vbs', sheet, new_xls, new_csv])
main(sys.argv[1],sys.argv[2],sys.argv[3])
It does not matter, which I try, I get the same error message:
Traceback (most recent call last):
File "C:/Users/user/Desktop/Work/XlsDir.py", line 16, in <module>
subprocess.call(NewCommand)
File "C:\Python27\lib\subprocess.py", line 524, in call
return Popen(*popenargs, **kwargs).wait()
File "C:\Python27\lib\subprocess.py", line 711, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 948, in _execute_child
startupinfo)
WindowsError: [Error 193] %1 er ikke et gyldigt Win32-program
The last line of the error message means approximately, that it is not a valid Win32-program.
What I have tried so far:
If I run the .vbs file from command prompt with the right arguments (sheet, name of the .xls file and name of the .csv file) then it works fine.
If I print the commands that python generates and copy them into command prompt, they work fine.
I tried every combinations of '\' and '\' within the different paths, and nothing got any better.
I tried to execute the programs with replacing the sys.argv[i] arguments with specific arguments and then execute the .py file from command prompt. I get the same error message.
I hope some of you can help me. Thanks a lot!

To elaborate on Ansgar's remedy:
Starting a .vbs from the command line 'works', because the shell associates the extension .vbs with an application (e.g. cscript/wscript; see ftype, assoc, cscript //E, cescript //S).
subprocess.call() does not open a shell, so either specify the application (c|wscript.exe) or start the shell yourself:
import subprocess
#subprocess.call("notepad") # works
#subprocess.call("dir") # [Error 2] The system cannot find the file specified
# no shell, no intrinsics
#subprocess.call("19112944.vbs") # [Error 193] %1 is not a valid Win32 application
# no shell, can't associate .vbs with c|wscript.exe
subprocess.call("cscript 19112944.vbs") # works
subprocess.call("cmd /c 19112944.vbs") # works
# have shell, can associate .vbs with c|wscript.exe

Try running the script with cscript.exe:
subprocess.call(['cscript.exe', 'C:\\Users\\user\\XlsToCsv.vbs', sheet, new_xls, new_csv])

Related

Subprocess.run() cannot find file, even if path.exists() returns true

I found these two pages:
Subprocess.run() cannot find path
Python3 Subprocess.run cannot find relative referenced file
but it didn't help. The first page talks about using \\ but I already do, and the second one talks about double quotes around one of the arguments.
work = Path("R:\\Work")
resume = work.joinpath("cover_letter_resume_base.doc")
current_date = construct_current_date()
company_name = gather_user_information(question="Company name: ",
error_message="Company name cannot be empty")
position = gather_user_information(question="Position: ",
error_message="Position cannot be empty")
# Construct destination folder string using the company name, job title, and current date
destination = work.joinpath(company_name).joinpath(position).joinpath(current_date)
# Create the destintion folder
os.makedirs(destination, exist_ok=True)
# Construct file name
company_name_position = "{0}_{1}{2}".format(company_name.strip().lower().replace(" ", "_"),
position.strip().lower().replace(" ", "_"), resume.suffix)
resume_with_company_name_job_title = resume.stem.replace("base", company_name_position)
destination_file = destination.joinpath(resume_with_company_name_job_title)
# Copy and rename the resume based on the company and title.
shutil.copy2(src=resume, dst=destination_file)
if destination_file.exists():
print(f"{destination_file} created.")
#subprocess.run(["open", str(destination_file)], check=True)
The program gets the company name and position from the user, generates the current date, creates the directories, and then moves/renames the base resume based on the user input.
Output and Results:
Company name: Microsoft
Position: Software Eng
R:\Work\Microsoft\Software Engineer\20190722\cover_letter_resume_microsoft_software_eng.doc
created.
Error Message:
[WinError 2] The system cannot find the file specified
Traceback (most recent call last):
File "c:/Users/Kiska/python/job-application/main.py", line 59, in <module>
main()
File "c:/Users/Kiska/python/job-application/main.py", line 53, in main
raise error
File "c:/Users/Kiska/python/job-application/main.py", line 48, in main
subprocess.run(["start", str(destination_file)], check=True)
File "C:\Program Files (x86)\Python37-32\lib\subprocess.py", line 472, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Program Files (x86)\Python37-32\lib\subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "C:\Program Files (x86)\Python37-32\lib\subprocess.py", line 1178, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
The if statement returns True but subprocess.run() cannot see the file, but I'm not really sure why.
On which operating system are you? The backslashes in your path suggest that you're on Windows and you're using open to open the document with its default application. However, looking at this question Open document with default OS application in Python, both in Windows and Mac OS you should use start instead of open for Windows:
subprocess.run(["start", str(destination_file)], check=True, shell=True)
Also you need to add shell=True for start to work. However, you should read https://docs.python.org/3/library/subprocess.html#security-considerations beforehand.
(I suspect, the error [WinError 2] The system cannot find the file specified appears, because Windows cannot find open - it's not about the document you're trying to open.)

Error Running Python Script from Batch File FileNotFoundError: [Errno 2] No such file or directory: '[]'

When I try to run my batch file for python script I get the error
D:\Sandbox\Python\Python Scripts>AQACompareBooks.py "D:/Sandbox/AQA/OrderAnalysis/Customer 1 OrderAnalysis -1 2018-05-08.xlsx"
[]
Traceback (most recent call last):
File "D:\Sandbox\Python\Python Scripts\AQACompareBooks.py", line 33, in <module>
xls = pd.ExcelFile(file)
File "D:\Dev\Sandbox\Python\lib\site-packages\pandas\io\excel.py", line 260, in __init__
self.book = xlrd.open_workbook(io)
File "D:\Dev\Sandbox\Python\lib\site-packages\xlrd\__init__.py", line 116, in open_workbook
with open(filename, "rb") as f:
FileNotFoundError: [Errno 2] No such file or directory: '[]'
Batch File
AQACompareBooks.py "D:\Sandbox\AQA\OrderAnalysis\Customer1 OrderAnalysis -1 2018-05-08.xlsx"
Python Code
import pandas as pd
import numpy as np
import os
import sys
print(sys.argv[1:])
file = format(sys.argv[1:])
xls = pd.ExcelFile(file)
If I set the path manually in the code I everything works fine.
i.e.
file = 'D:\Sandbox\AQA\OrderAnalysis\Customer1 OrderAnalysis -1 2018-05-08.xlsx'
Has anyone experienced this issue before?
Batch file and script are in the same folder.
The files I want to load is not
This looks a lot like it's a Windows issue with the extension association for .py files. In one Windows installation I checked where a test Python script did receive arguments, the registry key HKEY_CLASSES_ROOT\Python.File\Shell\open\command is set to "C:\WINDOWS\py.exe" "%L" %* (including those quotes). The trailing %* is what passes the arguments that Python then stores in sys.argv.
Second is the part with format(sys.argv[1:]); that slice will always produce a list, whereas the filename you wanted is stored in the single element sys.argv[1]. Simply use that instead.
With thanks to tdelaney for pointing them out, the associations can be checked (and, if administrator, set) using the assoc and ftype commands:
C:\Users\yann>assoc .py
.py=Python.File
C:\Users\yann>ftype Python.File
Python.File="C:\WINDOWS\py.exe" "%L" %*

Python. Send Uploaded File To Remote Server

In My Flask App, i want to upload a file to a remote server.
i tried this code but i get an error
import subprocess
import os
c_dir = os.path.dirname(os.path.abspath(__file__))
myfile = open(c_dir + '\\cape-kid.png')
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)
this was just a test file. there's an image in the same directory as my test python file. the error said:
Traceback (most recent call last): File
"C:\Users\waite-ryan-m\Desktop\remote-saving\test-send.py", line 20,
in
p = subprocess.Popen(["scp", c_dir + '\cape-kid.png', 'destination']) File
"C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\subprocess.py",
line 711, in init
errread, errwrite) File "C:\Users\waite-ryan-m\Desktop\WPython\WinPython-64bit-2.7.12.1Zero\python-2.7.12.amd64\lib\subprocess.py",
line 959, in _execute_child
startupinfo) WindowsError: [Error 2] The system cannot find the file specified
With open() you open an file to read or write on it. What you want is to concatinate the string and use this as parameter for scp. Maybe the file you want to copy also doesn't exist - have you tried printing the path you constructed and checking it manually?
And have you defined destination anywhere? This message could also mean, that the system cannot find scp.

Python read windows Command Line output

I am trying to execute a command in python and read its output on command line in windows.
I have written the following code so far:
def build():
command = "cobuild archive"
print "Executing build"
pipe = Popen(command,stdout=PIPE,stderr=PIPE)
while True:
line = pipe.stdout.readline()
if line:
print line
I want to execute the command cobuild archive in command line and read it's output. However, the above code is giving me this error.
File "E:\scripts\utils\build.py", line 33, in build
pipe = Popen(command,stdout=PIPE,stderr=PIPE)
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 893, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
The following code worked. I needed to pass shell=True for the arguments
def build():
command = "cobuild archive"
pipe = Popen(command,shell=True,stdout=PIPE,stderr=PIPE)
while True:
line = pipe.stdout.readline()
if line:
print line
if not line:
break
WindowsError: [Error 2] The system cannot find the file specified
This error says that the subprocess module is unable to locate your executable(.exe)
here "cobuild archive"
Suppose, if your executable in this path: "C:\Users\..\Desktop",
then, do,
import os
os.chdir(r"C:\Users\..\Desktop")
and then use your subprocess
Do you mind to post your code with the correct indentations please? They have a large effect in python - another way of doing this is:
import commands
# the command to execute
cmd = "cobuild archive"
# execute and get stdout
output = commands.getstatusoutput( cmd )
# do something with output
# ...
Update:
The commands module has been removed in Python 3, so this is a solution for python 2 only.
https://docs.python.org/2/library/commands.html

Windows subprocess.Popen a batch file without shell=True

I have a function that runs lessc (installed with npm install -g less):
>>> import subprocess
>>> subprocess.Popen(['lessc'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
Unfortunately, it doesn't work unless I add shell=True:
>>> subprocess.Popen(['lessc'], shell=True)
<subprocess.Popen object at 0x01F619D0>
What can I do to make lessc run without using shell=True?
From both https://docs.python.org/3/library/subprocess.html#subprocess.Popen and https://docs.python.org/2/library/subprocess.html#subprocess.Popen:
You do not need shell=True to run a batch file or console-based executable.
as already cited by #JBernardo.
So, lets try:
where lessc actually tells
C:\Users\myname\AppData\Roaming\npm\lessc
C:\Users\myname\AppData\Roaming\npm\lessc.cmd
That means, the file to execute is lessc.cmd, not some .bat file. And indeed:
>>> import subprocess
>>> subprocess.Popen([r'C:\Users\myname\AppData\Roaming\npm\lessc.cmd'])
<subprocess.Popen object at 0x035BA070>
>>> lessc: no input files
usage: lessc [option option=parameter ...] <source> [destination]
So, this does work if you specify the full path. I assume there was a typo involved when you had this experience. May be you wrote .bat instead of .cmd?
If you don't want to patch the full path of lessc into your script, you can bake yourself a where:
import plaform
import os
def where(file_name):
# inspired by http://nedbatchelder.com/code/utilities/wh.py
# see also: http://stackoverflow.com/questions/11210104/
path_sep = ":" if platform.system() == "Linux" else ";"
path_ext = [''] if platform.system() == "Linux" or '.' in file_name else os.environ["PATHEXT"].split(path_sep)
for d in os.environ["PATH"].split(path_sep):
for e in path_ext:
file_path = os.path.join(d, file_name + e)
if os.path.exists(file_path):
return file_path
raise Exception(file_name + " not found")
Then you can write:
import subprocess
subprocess.Popen([where('lessc')])
Change the file to lessc.bat, or create .bat file that calls lessc. That way the file will be recognized by Windows as a batch file and will be executed properly.
You may also need to set cwd in addition to this depending on where the .bat file is.

Categories

Resources