edit: the suggested duplicate does not contain a solution to my issue.
i'm fairly new to coding, and totally new to vbs - trying to work around this 'nonstandard script host' is totally baffling me as most online help assumes can use .sleep
... add to this my need to return values from python - which excludes using .run
- and i'm struggling... i could really do with some input...
to summarise my requirements:
call python from vbs and return final python output to vbs
not
wscript.sleep
as vbs is running with nonstandard host and.sleep
is not a recognised property or method of my Wscript objectnot
.run
as i need to retrieve output from the python program - i think i must use.exec
?does not devote an entire cpu core to a wait loop
suggested solutions at linked 'duplicate' are:
Wscript.sleep -> my script is not run by Windows Scripting Host, and .Sleep is not a recognised property or method of my Wscript object
cpu-hog loops -> no thanks
shell.run -> doesn't provide access to stdout for return values
window.settimeout -> looks a little promising, but the link to explanation is dead and i don't understand how to refactor for the purpose of waiting for the called python program to complete
application.wait -> i don't understand, what is my application to call
.wait
on? i tried with most of the objects in my script but 'no property or method'
original post:
edit: i don't think my vbs is being hosted by the normal Windows Scripting Host which is why wscript.sleep isn't working... i see a solution for arbitrary wait times here but i can't work out how to use it to wait for python to finish before retrieving .stdout
i'm running a python module in a shell from a vbs script, and want to return a value to vbs.
in brief, the vbs script resides in a database program, it exports some data to an xml, then launches python via shell.run
passing xml file location. python then uses the data along with prompted user input to book shipping and print labels etc... it all works fine
but now i want to capture tracking numbers and return them from python to the database software and have learned that .run is not appropriate, so i'm using .exec.
at the moment the python script stalls, i close the shell, then vbs shows msgbox with everything python would print to screen up until the first user-input
how do i let python finish then get the final return value?
(some of) my code: note, app.shipment.trackingNumbers does indeed contain the data i want when that line is run
vbs:
Sub ShipHire(xmlfile)
' AmDesp'
Dim python_exe, python_script, commence_wrapper, oShellExec, currentCommand, WshShell, WshShellExec, WshFinished, WshFailed, strOutput
python_exe = "C:\AmDesp\python\bin\python.exe"
python_script = "C:\AmDesp\AmDespMain.py"
ExportItemDetailForm(xmlfile)
currentCommand = "cmd /k " & python_exe & " " & python_script & " " & xmlfile & Chr(34)
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(currentCommand)
Select Case WshShellExec.Status
Case WshFinished
strOutput = WshShellExec.StdOut.ReadAll
Case WshFailed
strOutput = WshShellExec.StdErr.ReadAll
End Select
MsgBox strOutput 'write results in a message box
End Sub
python:
def shipper(ship_mode):
app = ShippingApp(ship_mode)
app.xml_to_shipment()
if app.queue_shipment():
if app.book_collection():
print("success")
app.log_json()
return app.shipment.trackingNumbers
if __name__ == '__main__':
shipper()
original vbs with no return
Sub ShipHire(xmlfile)
' AmDesp'
Dim python_exe, python_script, commence_wrapper
python_exe = "C:\AmDesp\python\bin\python.exe"
python_script = "C:\AmDesp\AmDespMain.py"
commence_wrapper = "C:\Program Files\Vovin\Vovin.CmcLibNet\Vovin.CmcLibNet.dll"
ExportItemDetailForm(xmlfile)
Dim oShell, currentCommand, my_command
Set oShell = CreateObject("Wscript.Shell")
' my_command = python_exe & " -noexit " & python_script & " " & JsonPath ''## (for multi-shiment via json)
' currentCommand = "cmd /k " & python_exe & " " & python_script & Chr(34) ' & " " & xmlfile'
currentCommand = "cmd /k " & python_exe & " " & python_script & " " & xmlfile & Chr(34)
oShell.run currentCommand,1,true
set oShell = nothing
End Sub
edit: i tried this way, but i get 'object doesn't suppor tthis property or method' where object is wscript
sub anothertry(xmlfile)
dim python_exe, python_script, currentCommand
python_exe = "C:\AmDesp\python\bin\python.exe"
python_script = "C:\AmDesp\AmDespMain.py"
ExportItemDetailForm(xmlfile)
currentCommand = "cmd /k " & python_exe & " " & python_script & " " & xmlfile & Chr(34)
Const WshRunning = 0
Const WshFinished = 1
Const WshFailed = 2
Dim shell : Set shell = CreateObject("WScript.Shell")
Dim exec : Set exec = shell.Exec(currentCommand)
While exec.Status = WshRunning
WScript.Sleep 50
Wend
Dim output
If exec.Status = WshFailed Then
output = exec.StdErr.ReadAll
Else
output = exec.StdOut.ReadAll
End If
MsgBox output
End Sub