Search code examples
command-lineopenedgeprogress-4gl

How to catch OS-COMMAND results in Progress-4GL?


I'm using the logging facilities, as described in this other post:

OUTPUT TO VALUE("C:\Temp_Folder\logfile.txt").
...
PUT UNFORMATTED "Start : Check-zones" SKIP.
...
OUTPUT CLOSE.

This is working fine.

Now I would like to add the results of an OS-COMMAND in the output file.
I've already tried the following: (putting the results in a newly to be created file)

OS-COMMAND NO-WAIT VALUE("WMIC printer get name, deviceID >> C:\Temp_Folder\Printers.txt").

This is working fine.
So, I know the command is working fine. However, the following is not working:

OS-COMMAND NO-WAIT VALUE("WMIC printer get name, deviceID >> C:\Temp_Folder\LogFile.txt").

This is obvious, because C:\Temp_Folder\Logfile.txt is locked for writing by the progress application, so the shell, opened by OS-COMMAND can't write to that file.

In order to overcome this, I would like to catch the results of the OS-COMMAND's results.

How can I do this?


Solution

  • Unfortunately back in the dark ages when os-command was designed, it was considered useful to suppress all errors.

    You can either start a batch file and let that do some “guaranteed” output error handling, see https://knowledgebase.progress.com/articles/Article/21039

    Or (since you are on Windows) you can use the .Net system diagnostics process class (which you will want to wrap in your own method or function to simplify use):

    DEFINE VARIABLE oProcess   AS System.Diagnostics.Process NO-UNDO.
    DEFINE VARIABLE lcstderr   AS LONGCHAR    NO-UNDO.
    DEFINE VARIABLE lcstdout   AS LONGCHAR    NO-UNDO.
    
    oProcess = NEW System.Diagnostics.Process().
    
    oProcess:StartInfo:FileName = "wmic.exe".
    oProcess:StartInfo:Arguments = "printer get name, deviceID".
    oProcess:StartInfo:CreateNoWindow         =  TRUE.
    oProcess:StartInfo:UseShellExecute        =  FALSE.
    oProcess:StartInfo:RedirectStandardError  =  TRUE.
    oProcess:StartInfo:RedirectStandardOutput =  TRUE.
    oProcess:Start().
    
    lcstdout = oProcess:StandardOutput:ReadToEnd().
    lcstderr = oProcess:StandardError:ReadToEnd().
    
    oProcess:WaitForExit().
    
    lcstdout = lcstdout + oProcess:StandardOutput:ReadToEnd().
    lcstderr  = lcstderr + oProcess:StandardError:ReadToEnd().