0

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:

  1. call python from vbs and return final python output to vbs

  2. not wscript.sleep as vbs is running with nonstandard host and .sleep is not a recognised property or method of my Wscript object

  3. not .run as i need to retrieve output from the python program - i think i must use .exec?

  4. does not devote an entire cpu core to a wait loop

suggested solutions at linked 'duplicate' are:

  1. Wscript.sleep -> my script is not run by Windows Scripting Host, and .Sleep is not a recognised property or method of my Wscript object

  2. cpu-hog loops -> no thanks

  3. shell.run -> doesn't provide access to stdout for return values

  4. 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

  5. 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
prosody
  • 557
  • 1
  • 3
  • 11

0 Answers0