I am trying to build a program that mimics the 'run' feature of Windows in a Windows environment. Now I know that sounds a bit silly, but we are on 'limited' computers, and the cmd is completely locked so we don't have any choice but to build our own program files for our needs.
Specifically, what I am trying to do is a little utility that will ask for the drive, subject, and course number, and based on that open the full path.
i.e. W Python 47 -> w://courses/subjects/python/classes/47 - Arrays & Pointers
I have done most of the work in Python and reached the last stage where I need to get the full path based only on the number with the code being something like:
os.system(start 'drive + '://courses/subjects/' + subject + '/classes/' + class')
Where drive, subject, and class are variables that hold the data of the current path.
The problem is that when there is a space in the file path, Windows can't find it, and produces an error.
The simple solution would be to put double quotes, but for some reason double quotes on the start command is considered as a cmd command which is blocked..
Any ideas on a workaround, or maybe Python is not the way to go, and so any ideas on a different language, that would be easier. (I have basic knowledge in C++, Python, Java)
p.s. This is not the exact code, that I am using, I will post that tomorrow.
The first argument after start is the name of the newly created command prompt window, and the second and third should be the path to the application and its parameters, respectively.
start "" "c:\path with spaces\app.exe" param1 "param with spaces"
If you want to use os.system, you could try:
norm_path = os.path.normpath("{0}://courses/subjects/{1}/classes/{2}".format (drive, subject, class_name))
os.system('start "" "' + norm_path + '"')
But I would probably use os.startfile:
norm_path = os.path.normpath("{0}://courses/subjects/{1}/classes/{2}".format (drive, subject, class_name))
os.startfile( norm_path )
Please note: you should not use a variable named class.
Related
I am creating a code editor, and I am trying to create a run feature. Right now I see that the problems come when I encounter a folder with a space in its name. It works on the command line, but not with os.system().
def run(event):
if open_status_name != False:
directory_split = open_status_name.split("/")
for directory in directory_split:
if directory_split.index(directory) > 2:
true_directory = directory.replace(" ", "\s")
print(true_directory)
data = os.system("cd " + directory.replace(" ", "\s"))
print(data)
I tried to replace the space with the regex character "\s" but that also didn't work.
os.system runs the command in a shell. You'd have to add quotes to get the value though: os.system(f'cd "{directory}"'). But the cd would only be valid for that subshell for the brief time it exists - it would not change the directory of your python program. Use os.chdir(directory) instead.
Note - os.chdir can be risky as any relative paths you have in your code suddenly become invalid once you've done that. It may be better to manage your editor's "current path" on your own.
I have tried so many variants of a theme to get this explorer window open at the P:\ drive, from what my little knowledge tells me, the fact the path to the folder is anywhere but the C:\ drive means it fails (it works with C:) so perhaps the path is wrong? the code below shows some of the tries i have made but still no luck, "P:" is mapped the same on all machines.
def Open_Win_Explorer_and_Select_Dir():
import subprocess
fldrname = os.path.basename(currentproject.get())
print(fldrname)
#subprocess.Popen('c:\windows\EXPLORER.EXE', cwd=(P:/Projects 2013/)
#subbprocess.Popen('c:\\windows\\EXPLORER.EXE' cwd=('P:\\Projects_2013\\')fldrname)
#subprocess.Popen(r'C:/Windows/explorer.exe', cwd=r'//WRDBSVR/Project_Data/Projects_2013/'+fldrname)
subprocess.Popen('explorer /n, /select r"\\192.168.0.27\\Project_Data\\Projects_2013\\"'+fldrname)
#subprocess.Popen('explorer /n, /select r"P:\\Project_Data\\Projects_2013\\"'+fldrname)
well to open My pc (for windows) try:
import subprocess
subprocess.Popen('explorer ""')
"#if subprocess.Popen('explorer "{0}".format(full_path)') is struck at pc\my documents.
where full_path=os.path.join("your/path")"
Appart from the fact that Ashish Nitin Patil's answer is definitly better, as using a variable for paths is always a good idea, you have a problem with your quotes:
# This line is not correct
'explorer /n, /select r"\\192.168.0.27\\Project_Data\\Projects_2013\\"'+fldrname
# ^you start a new string without ending previous one
# this one is correct
'explorer /n, /select ' + r'\192.168.0.27\Project_Data\Projects_2013\' + fldrname
# ^first ending string start
Besides, using raw strings (r"xxx") means that \ will not escape characters, so you shall not double them. If you want to double them, you do not need prepend r.
Last remark: take care to avoid string concatenation (+) when working with paths; you should use os.path.join() instead.
Following should do the job.
import subprocess
subprocess.Popen('explorer "{0}"'.format(full_folder_path))
Update -
Tested on my system -
full_path = os.path.join("P:/Project_Data/Projects_2013/",fldrname)
print full_path # Verify that it is correct
subprocess.Popen('explorer "{0}"'.format(full_path))
In IronPython 2.6*, I'm trying to build a function that "corrects" a string; I have two arguments, FILE and EXTN. The idea is for them to be concatenated as necessary later in the program, but you know some people don't read instructions and you're bound to have someone enter "FILE.*" as their FILE, which would mess everything up.
I'm looking for a way to take FILE, have my function detect and strip .* (any extension of any length) from FILE if .* exists; It doesn't need to be in the string, and the user will be entering the same extension into EXTN**, so it needs not be prepared, merely consistently stripped.
My current method has me passing FILE and EXTN separately, but it's not inconceivable to redo things to take FILE.EXTN and break that into FILE and EXTN if need be; I don't want to if I don't have to, though, as my program is built around the former system.
*A note regarding IronPython 2.6; I'm trying to avoid IronPython-specific codes and use as simple of ones as possible, for UNIX-WIN cross-compatibility's sake. So far, everything I've done works in Python 2.7 IDE's, but obviously will not work in Python 3.x
**A note regaring EXTN; I want users to enter the proper extension into EXTN too, but as we know, we can't be sure of this and so the method for stripping .i from FILE must not automatically include EXTN as part of it.
Here is a snippet of code that may help as a reference for what I have so far. The FILE and EXTN variables have been added, and in practice, are pulled in through a middle-man program from an XML file into the script at run-time.
FILE = "test"
PATH = "C:\\"
EXTN = ".txt"
def CheckCorrect_FILE(srcFile): #Check-corrects FILE
#Meh, I got nothin'...
def CheckCorrect_PATH(srcPath): #Check-corrects PATH
if srcPath.endswith('\\') == False:
srcPath = srcPath + "\\"
else:
srcPath = srcPath
return srcPath
You can do this using os.path.splitext. The following will always remove an extension if one exists (and do nothing if it doesn't):
import os
FILE = os.path.splitext(FILE)[0]
Trying to call a python script on Vba and I am a newb. I tried converting the main script to an exe using py2exe and then calling it from VBA (shell) but the main script calls other scripts therefore it becomes complicated and I messed it up (my exe is not functional). Besides, the the main script is a large file and I do not want to revise it a lot.
Bottomline, is there a way to call the main script from excel vba, without converting the script to an exe file.
So far, I tried:
RetVal = Shell("C:\python27\python.exe " & "import " & "C:\\" & "MainScriptFile")
It starts python.exe but does nothing else. Then I tried:
RetVal = Shell("C:\Windows\System32\cmd.exe " & "python " & "C:\\Python27\\hello.py")
It starts command prompt but does not even start python.
P.S. I checked all the related questions in the forum, they do not solve my prob.
Try this:
RetVal = Shell("<full path to python.exe> " & "<full path to your python script>")
Or if the python script is in the same folder as the workbook, then you can try :
RetVal = Shell("<full path to python.exe> " & ActiveWorkBook.Path & "\<python script name>")
All details within <> are to be given. <> - indicates changeable fields
I guess this should work. But then again, if your script is going to call other files which are in different folders, it can cause errors unless your script has properly handled it. Hope it helps.
I just came across this old post. Nothing listed above actually worked for me. I tested the script below, and it worked fine on my system. Sharing here, for the benefit of others who come to this spot after me.
Sub RunPython()
Dim objShell As Object
Dim PythonExe, PythonScript As String
Set objShell = VBA.CreateObject("Wscript.Shell")
PythonExe = """C:\your_path\Python\Python38\python.exe"""
PythonScript = "C:\your_path\from_vba.py"
objShell.Run PythonExe & PythonScript
End Sub
There are a couple of ways to solve this problem
Pyinx - a pretty lightweight tool that allows you to call Python from withing the excel process space
http://code.google.com/p/pyinex/
I've used this one a few years ago (back when it was being actively developed) and it worked quite well
If you don't mind paying, this looks pretty good
https://datanitro.com/product.html
I've never used it though
Though if you are already writting in Python, maybe you could drop excel entirely and do everything in pure python? It's a lot easier to maintain one code base (python) rather than 2 (python + whatever excel overlay you have).
If you really have to output your data into excel there are even some pretty good tools for that in Python. If that may work better let me know and I'll get the links.
To those who are stuck wondering why a window flashes and goes away without doing anything the python script is meant to do after calling the shell command from VBA:
In my program
Sub runpython()
Dim Ret_Val
args = """F:\my folder\helloworld.py"""
Ret_Val = Shell("C:\Users\username\AppData\Local\Programs\Python\Python36\python.exe " & " " & args, vbNormalFocus)
If Ret_Val = 0 Then
MsgBox "Couldn't run python script!", vbOKOnly
End If
End Sub
In the line args = """F:\my folder\helloworld.py""", I had to use triple quotes for this to work. If I use just regular quotes like: args = "F:\my folder\helloworld.py" the program would not work. The reason for this is that there is a space in the path (my folder). If there is a space in the path, in VBA, you need to use triple quotes.
This code will works:
your_path= ActiveWorkbook.Path & "\your_python_file.py"
Shell "RunDll32.Exe Url.Dll,FileProtocolHandler " & your_path, vbNormalFocus
ActiveWorkbook.Path return the current directory of the workbook. The shell command open the file through the shell of Windows.
You can also try ExcelPython which allows you to manipulate Python object and call code from VBA.
Try this:
retVal = Shell("python.exe <full path to your python script>", vbNormalFocus)
replace <full path to your python script> with the full path
To those who are stuck wondering why a window flashes and goes away without doing anything, the problem may related to the RELATIVE path in your Python script. e.g. you used ".\". Even the Python script and Excel Workbook is in the same directory, the Current Directory may still be different. If you don't want to modify your code to change it to an absolute path. Just change your current Excel directory before you run the python script by:
ChDir ActiveWorkbook.Path
I'm just giving a example here. If the flash do appear, one of the first issues to check is the Current Working Directory.
ChDir "" was the solution for me. I use vba from WORD to launch a python3 script.
In my case, as I have my script in a different directory than my ms access document and, in that script I import variables from other scripts, I had to change the directory first. Then I can use correctly the shell function.
ChDir "C:\Users\directory_where_the_script_is"
Call Shell("C:\Users\...\python.exe " & "your_script_name.py", 1)
for me this not working
RetVal = Shell(" " & ActiveWorkBook.Path & "<python script name>")
for me this :
RetVal = Shell("python3" & " " & "C:\a\b\c\xyz.py")
I think above answers have a catastrophic problem:
after running the macro,cmd window would close automatically, instantly. In case output is not as expected you would have absolutely zero debug information.
Finally I found a better way in which case, cmd window remains open and shows all the information (print of python) and error log.
code as below:
Sub RunPythonScript()
cwd = ActiveWorkbook.Path 'current working directory
workbookName = ActiveWorkbook.Name
pythonScriptName = "main.py"
workbookNameWithPath = cwd & "\" & workbookName
pythonScriptNameWithPath = cwd & "\" & pythonScriptName
pythonExePath = "C:\Users\USERNAME\AppData\Local\Programs\Python\Python39\python.exe" ' change path as output of "where python"
Shell "cmd.exe /k """"" & pythonExePath & """ """ & pythonScriptNameWithPath & """""", vbNormalFocus
End Sub
I've got a problem with some VB scripting - it doesn't seem like it should be terribly difficult to solve, but even after trudging through many a page of Google I have yet to find a solution.
[The problem]
Here is my python file (test.py), simplified to just show the problem:
f = open("testing.txt", 'w')
f.write("oh hai\n")
f.close()
Of course, when run directly from the command line, this generates the file as you'd expect.
However, when run in a simple .vbs script (WARNING: My vbs skills are lacking. This is probably why I am having a problem. So far I haven't had many issues, apart from hating life from using XP to code when I'm used to using vim)
Set WshShell = WScript.CreateObject("WScript.Shell")
cmd = "C:\Python27\python test.py"
WshShell.Run cmd
no output file is generated! At all! It's infuriating, as when I input that exact command ("C:\Python27\python test.py") into the run program from the start menu, it works!
[System info]
At work, so they're on Windows XP. Everything else is pretty standard, or so I'm lead to believe.
EDIT: Changed "C:\Python27\testing.py" to just "testing.py". This was left over from when I was trying to solve it, and thought maybe it was putting the files somewhere outside of the destination folder.
First, your Python script looks suspicious, I doubt the backslashes work in a simple string. At least, in my test, it didn't work, I just replaced them with forward slashes.
Next, you can see the error message by prepending cmd with cmd /k, the run window remains on screen. You can see the .py file isn't found, because it isn't in the current directory. You have to specify an absolute path to this file, perhaps by getting the current path from the script.
[EDIT] I finally got a working code (my VBS is a bit rusty...)
Dim wshShell, fso, loc, cmd
Set fso = CreateObject("Scripting.FileSystemObject")
loc = fso.GetAbsolutePathName(".")
WScript.Echo loc
'~ cmd = "%ComSpec% /k C:\Languages\Python\python.exe " + loc + "\test.py"
cmd = "C:\Languages\Python\python.exe " + loc + "\test.py"
WScript.Echo cmd
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run cmd
You can also check the arguments if a path is provided:
if WScript.Arguments.Count = 0 then
loc = fso.GetAbsolutePathName(".")
else
loc = WScript.Arguments(0)
end if
Such script is better run with cscript instead of default wscript.
Try
f = open("C:\\Python27\\testing.txt", 'w')
instead of your first line.