Trouble running a Python script through VB - python

The objective is to receive an image path and pass that to a Python program as an argument, then receive the results.
This is done through a web app using VB (on the IIS server) and it works perfectly except when I import the python module OpenCV (imported in Python as cv2, more specifically).
What's even more confusing is that the script runs perfectly with the imported cv2 module when executed directly from cmd. It only fails to work when the VB code runs the script including the line import cv2.
I'll show some code below, for clarity.
VB code running Python script with image path as an argument:
Dim Processtask As New System.Diagnostics.Process()
Processtask.StartInfo.FileName = "cmd.exe"
Processtask.StartInfo.Arguments = "/c python " + path.ToString + " " + ImageURL.ToString
Processtask.StartInfo.UseShellExecute = False
Processtask.StartInfo.RedirectStandardOutput = True
Processtask.StartInfo.RedirectStandardError = True
Processtask.StartInfo.CreateNoWindow = True
Processtask.Start()
Processtask.WaitForExit()
output = Processtask.StandardOutput.ReadToEnd()
Python code snippet receiving image path:
import sys
import cv2
if __name__ == "__main__":
im = str(sys.argv[1])
print(im)
I have run out of possible ideas as to what could cause this problem. Any advice would be greatly appreciated.
EDIT
I managed to find the full error message which reads as follows:
System.Exception: System.IO.StreamReader
System.InvalidOperationException: Process has exited, so the requested
information is not available.
at System.Diagnostics.Process.EnsureState(State state) at
System.Diagnostics.Process.get_ProcessName()
at System.Diagnostics.Process.ToString()

Got the solution eventually, I'll post it here in case anyone else ever runs into this problem:
The dll files of opencv installed onto the server which hosted the web app had different access rights. The files were denied access when being called from the web application, whereas the rest of the modules called had no issue.
I used sysinternals process monitor to trace which files were being denied access and was able to change the rights by hand. Not very elegant but it worked out.

Related

running imported module functions through sockets in Maya (Python)

I have a problem and I am not sure what is going on, I have created a 'userSetup.py' file and placed it in the script folder (C:\Users*user*\Documents\maya\2022\scripts)
This is my userSetup.py file:
def importPy():
### import modules and open a command port ###
exec("import my_module", globals())
exec("cmds.commandPort(name=':1234', sourceType = 'python')")
exec("print('FINISHED')")
def tryImport():
"""
execute importPy when Maya is idle
"""
from maya.utils import executeDeferred
executeDeferred("importPy()")
tryImport()
now I have created a file 'my_module.py' and placed it in the same script folder
this is the my_module.py file:
print("my_module loaded")
def function_print(statement: str):
print(statement)
I know this is working on startup as the console in Maya reads:
my_module loaded
FINISHED
I have a successfully sent over simple commands like:
cmds.polyCube()
it works fine even returns fine which I found odd since I am not echoing the output, so the socket server is working as intended. But if I send:
my_module.function_print("please print this")
it doesn't work, but it will work if I write that exact same line in the python command line within Maya.
This doesn't really make sense to me, I am fairly new to python so I may be missing something obvious here. But all I can think is that the socket commands somehow don't have access to the global scope.
If anyone knows what's up with this, it would be much appreciated.
Thanks,
Brendan
P.S. the names to my modules and functions have been made up for this example. If that wasn't obvious.

"/Library" directory permission denied on Mac - Python3

I'm trying to create a program that copies a directory in the library directory on mac (path : "/Library"). I use shutil which works very well in other directories but not in the Library directory...
I want to be able to compile my program, so I can't run it as root.
Here is my code :
import shutil
def copy(src_path, dir_path):
try:
shutil.copytree(src_path, dir_path)
print("Success!")
except:
print("Impossible to copy the folder...")
print("Failed!")
copy("/Users/marinnagy/Desktop/Test", "Library/Test")
I think it's because the library directory is protected and requires authentication to make changes.
Do I have to make an authentication request to the user ? Or do I need to use another method than shutil ?
Thanks for your help !
After a good deal of research and many attempts, I finally managed to copy a folder into my Library directory.
On macOS, the process of writing to a protected directory like the Library directory is blocked for python program. Once compiled (I use pyinstaller), it seems to be impossible for a python application to access this kind of folder, even if you give the app Full Disk Access in the System Preferences.
So I used some AppleScript to manage this specific copy/paste task :
on run {scr_path, dir_path} # Run with arguments
# Translate standard paths to their quoted form
set formated_scr_path to quoted form of scr_path
set formated_dir_path to quoted form of dir_path
# Run a simple shell script to copy the repertory in the other
do shell script "cp -R " & formated_scr_path & space & formated_dir_path ¬
with administrator privileges # Ask for administrator privileges
end run
Then, in my python program, I call the AppleScript program when I want to copy/past to a protected repertory like the Library repertory :
import subprocess
def copy(scr_path, dir_path):
# Use the osascript process to call the AppleScript
# Give the paths in arguments
process = subprocess.call(['osascript', "path/to/applescript",
scr_path, dir_path])
return process
copy("path/to/folder 1", "path/to/folder 2")
This method worked for me on protected repertories. The AppleScript run in the background and an authentication window pop in, asking the user to identify himself as an admin :
result screenshot

Run Python script when opened via VBA or .bat

I am trying to open a py script via VBA Excel.
The script is to interact with engineering software which undertakes finite elements analysis. The script can run directly from the py editor.
They prepared a Python library I have to import at the beginning of the script which also requires some password and log in credentials for the script to interact with that specific software.
I can open simple py scripts (such as the classic Hello World) via the Shell in VBA.
The script that I have prepared is more complex. When opening my script via VBA using the shell it flashes the cmd window and nothing happens.
Below is the subroutine I have coded in VBA to open the Python interpreter and Python script, for illustration: it returns error message 2.
Sub RunPythonScript()
Dim wsh As Object
Dim PythonExe, PythoScript As String
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Dim errorCode As Long
Dim pth As String
PythonExe = """C:\ProgramData\Bentley\Geotechnical\PLAXIS 2D CONNECT Edition V20\python\python.exe"""
PythoScript = """C:\Users\ukjfv001\Desktop\MyPython\MyAnalysis.py"""
pth = PythonExe & PythoScript
Set wsh = VBA.CreateObject("WScript.Shell")
errorCode = wsh.Run(pth, windowStyle, waitOnReturn)
If errorCode = 0 Then
MsgBox "Done! No error to report."
Else
MsgBox "Program exited with error code " & errorCode & "."
End If
End Sub
There is a lot of information online on how to run Python scripts.
In this forum: How to call python script on excel vba?. I have also created a bat file which I could open via VBA but, got the following error message:
C:\Users\ukjfv001\Desktop\MyPython>"C:\Users\ukjfv001\Anaconda3\python.exe" ""C:\Users\ukjfv001\Desktop\MyPython\MyAnalysis.py""
start
Traceback (most recent call last):
File "C:\Users\ukjfv001\Desktop\MyPython\MyAnalysis.py", line 16, in
from plxscripting.easy import * #call Plaxis scritping library
ModuleNotFoundError: No module named 'plxscripting'
Below is a bit of the Python code which I have to place at the top of the script in the SciTE editor (which comes with the engineering software).
From what I can see in the error message (above) and the bit of code below from plxscripting.easy import there is something I am not doing.
I am new to Python so usually I need practical examples to understand what is to be done.
from plxscripting.easy import * #callS engineering scritping library
inputport = 8888888
plaxispw = some_password
plaxis_path = C:\Users\ukjfv001\... #to here the software is intalled
plaxis_input = Plaxis.exe #software executable
if not process_exists(plaxis_input): #checkS if software is alreayd running
# first launch software
args = [os.path.join(plaxis_path, plaxis_input),"--AppServerPort={}".format(inputport),"--AppServerPassWord={}".format(plaxispw)]
inputprocess = subprocess.Popen(args)
# Initialize new_server with waiting time
s_i, g_i = new_server('localhost', inputport, password=plaxispw, timeout=10.0)
s_i.new()#starts a new Project
#after this point is where I have my Python script...```
I had a similar problem where I got an error running a python script from a scheduler (via running a file) even though it ran in my IDE. I also had to run it from a batch file to see the error, otherwise nothing happened. The issue was that python could not find the path to my custom libraries (which may be your issue, since the error is a library import). I think this can happen if you set your Python Path to custom libraries in your IDE and the environmental variables/ path are not also set (that is what you need to synchronize).
In Spyder, you just go to Tools: Python Path Manager in the menu and hit synchronize. I don't know what IDE you are using, but probably it also has a Python Path Manager if it isn't Spyder.

Calling Python script in excel as executable

I am currently developing a tool for a client that interfaces with both python 2.7 and excel 2013 and as a result running into a problem.
As background, I have a python code I want to run as a executable. The client doesn't have python on their computers so it's vital that the exe runs without .py. I've converted the script from a .py to a .exe with py2exe. Then I am trying to call that .exe with VBA. When the macro runs it looks like it pulls up the command prompt for a second but it doesn't run the .exe. When I go into the directory and double click the .exe however, it runs fine and outputs what I want it to.
Below is my code in VBA:
Dim folderPath As String
folderPath = Application.ActiveWorkbook.Path
ChDir folderPath
Dim stAppName As String
stAppName = folderPath & "\dist\MAT.exe"
Call Shell(stAppName, 1)
Not sure if my Shell needs any other inputs
Any help would be appreciated!
this is an indirect answer more to help you figure out what might be wrong
in your main file put your program in a main function (you dont have to call it main... you can call it whatever)
def main():
#do whatever
then when you run it if its main do this
if __name__ == "__main__":
try:
main()
finally:
raw_input("Hit enter To Close...")
this will guarantee your window to stay open even if there is an uncaught error

Qualcomm's QPST Automation Server in Python 2.7 using win32com module

Python newbie here. So, please excuse if this has been asked before in a different format.
I am trying to replicate the following perl snippet in Python using the win32com module. This snippet is provided by Qualcomm for easier automation of their tools.
use Win32::OLE;
use Win32::OLE::Variant;
$prod_id = "QPSTAtmnServer.Application"; # AppId for the Automation server.
eval{ $qpst = Win32::OLE->GetActiveObject($prod_id)}; # Attempt to use a running instance.
die "$prod_id not installed" if $#;
unless (defined $qpst) { $qpst = Win32::OLE->new($prod_id, sub {$_[0]->Quit;}) or die "Cannot start $prod_id";} # Start a new instance. Call Quit when $qpst set to undef or script exits.
if (defined $qpst)
{
$port = $qpst->GetPort("COM30001");
}
The block of python code I have till now is as follows:
import win32com.client
import time
import os
cmd = 'cls'
os.system(cmd)
cmd = 'start C:\\LAB\\exe\\pskill.exe QPSTConfig'
os.system(cmd)
cmd = 'start C:\\LAB\\exe\\pskill.exe QPSTServer'
os.system(cmd)
cmd = 'start C:\\LAB\\exe\\pskill.exe AtmnServer'
os.system(cmd)
time.sleep(2)
_path = os.getcwd()
qpst = win32com.client.Dispatch('QPSTAtmnServer.Application')
time.sleep(5)
if (qpst is None):
print('Darn!')
else:
port = qpst.GetPort('30001')
print(port)
and it throws the following error:
Traceback (most recent call last):
File "xxxx.py", line 20, in module
port = qpst.GetPort('30001')
TypeError: 'NoneType' object is not callable
After reading a couple of posts it seems like the method (GetPort) is not registering as a method after all.
Is that correct analysis?
If yes, how do I make Python interpret it as a method?
If not, what is going on here with the error?
Thanks in advance for the help!
It looks like I had to do couple of things to solve the issue.
Use the makepy command on the "AtmnServer" OLE TypeLibrary file to create a *.py file in:
...\Python27\Lib\site-packages\win32com\gen_py\
Add an extra line to actually interpret the required Method as a method (instead of as a property/attribute or something) :
qpst._FlagAsMethod("GetPort")
before the line:
port = qpst.GetPort("COM30001")
Thanks again for offering to help!
Correct, it is saying that GetPort does not exist. Have you checked that the Perl version works? If you don't have Perl, you could try through Excel's VBA (open its VBA console -- you may have to enable it by following the steps here). If you can dispath the QPST from Excel VBA and do the GetPort, then something is very odd.
It could be that QPST COM interface changed since this script was written. You could try
qpst = win32com.client.gencache.EnsureDispatch(
'QPSTAtmnServer.Application')
which will attempt to create the type library for QPST. Sometimes it finds extra objects, but if not at very least you can then browse the QPST COM from python using combrowse.py (which is part of pywin32) and try to find where that function is. Combrowse is a basic COM browser, just run \Lib\site-packages\win32com\client\combrowse.py, if need more powerful the one from visual studio is probably better.

Categories