Obtenha a saída de uma string Java do VBA

Nov 25 2020

Preciso obter a string de saída de uma função java em meu projeto VBA. Como um exemplo rápido, estou tentando obter a saída da versão java instalada, mas no aplicativo real serão outras funções privadas.

Primeira tentativa:

' 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

Segunda tentativa:

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

Nenhum deles funcionou para mim.

Eu gostaria de evitar o uso de arquivos temporários como em meu exemplo de segunda tentativa. No uso final, vou chamar essa função centenas de milhares de vezes, e prefiro não criar essa quantidade de arquivos ou editar esse arquivo tantas vezes ...

Respostas

Joracosu Nov 26 2020 at 07:41

Encontrei a solução para as duas tentativas e basicamente é o mesmo problema: a saída de uma função java exibida no shell de comando é tratada como um erro, portanto, não é uma saída. A dúvida foi resolvida aqui

No caso de enviar a saída java para um arquivo, resolve-se usando em 2>vez de apenas >como é dito aqui . De qualquer forma, existem muitas variantes diferentes dependendo do que você precisa, conforme relatado neste outro link . Um pequeno problema deste método é que a criação do arquivo de saída precisa de um tempo para ser feita, portanto a variável final do Runcomando deve ser ajustada paraTrue

E o código é o seguinte:

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

No caso de levar diretamente a saída java para uma variável, isso é resolvido usando em StdErrvez de StdOut. Eu tenho a iluminação lendo este link . O WshExecobjecto tem três elementos principais: StdErr, StdIne StdOut. Se a string de saída java for tratada como um erro, ela deve estar interna StdErr.

E o código é o seguinte:

' 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