Ottieni l'output di una stringa Java da VBA

Nov 25 2020

Ho bisogno di ottenere la stringa di output di una funzione java nel mio progetto VBA. Come esempio veloce, sto cercando di ottenere l'output della versione java installata ma nell'applicazione reale ci saranno altre funzioni private.

Primo tentativo:

' Needs a reference to Windows Script Host Object Model
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub get_java_output()
    Dim cmd_windows    As New WshShell
    Dim execution_cmd  As WshExec
    Dim command_str    As String
    command_str = "java -version"
    Set execution_cmd = cmd_windows.exec("cmd.exe /c " & command_str)
    Do While execution_cmd.Status = WshRunning
        Sleep 20
    Loop
    final_string = execution_cmd.StdOut.ReadAll
    Debug.Print final_string
End Sub

Secondo tentativo:

Sub get_java_output_2()
    Dim windows_shell As Object
    
    Set windows_shell = CreateObject("WScript.Shell")
    command_str = "java -version"
    shell_output = windows_shell.Run("cmd /c " & command_str & " > c:\temp\output.txt", 0, False)
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set File = fso.OpenTextFile("c:\temp\output.txt", 1)
    final_string = File.ReadAll
    File.Close
    Debug.Print final_string
End Sub

Nessuno di loro ha funzionato per me.

Vorrei evitare l'uso di file temporanei come nel mio secondo esempio di tentativo. Nell'uso finale, chiamerò questa funzione centinaia di migliaia di volte e preferisco non creare quella quantità di file o modificare quel file così tante volte ...

Risposte

Joracosu Nov 26 2020 at 07:41

Ho trovato la soluzione per entrambi i tentativi e fondamentalmente è lo stesso problema: l'output di una funzione java visualizzato sulla shell dei comandi viene trattato come un errore, quindi non è un output. Il dubbio è stato risolto qui

Nel caso di invio dell'output java a un file, viene risolto utilizzando 2>invece di >come è detto qui . Ad ogni modo, ci sono molte varianti diverse a seconda di ciò di cui hai bisogno, come riportato in questo altro link . Un problema minore di questo metodo è che la creazione del file di output richiede un tempo per essere eseguita, quindi la variabile finale del Runcomando deve essere impostata suTrue

E il codice è il seguente:

Sub get_java_output_2()
    Dim windows_shell As Object
    
    Set windows_shell = CreateObject("WScript.Shell")
    command_str = "java -version"
    shell_output = windows_shell.Run("cmd /c " & command_str & " 2> c:\temp\output.txt", 0, True)
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set File = fso.OpenTextFile("c:\temp\output.txt", 1)
    final_string = File.ReadAll
    File.Close
    Debug.Print final_string
End Sub

Nel caso di portare direttamente l'output java a una variabile, viene risolto usando StdErrinvece di StdOut. Ho avuto l'illuminazione leggendo questo link . L' WshExecoggetto ha tre elementi principali: StdErr, StdIne StdOut. Se la stringa di output java viene considerata come un errore, dovrebbe essere StdErrinvece all'interno .

E il codice è il seguente:

' Needs a reference to Windows Script Host Object Model
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub get_java_output()
    Dim cmd_windows    As New WshShell
    Dim execution_cmd  As WshExec
    Dim command_str    As String
    command_str = "java -version"
    Set execution_cmd = cmd_windows.exec(command_str)
    Do While execution_cmd.Status = WshRunning
        Sleep 20
    Loop
    final_string = execution_cmd.StdErr.ReadAll
    Debug.Print final_string
End Sub