Hello,
I'm calling a foreign DLL/dylib (Win + Mac) which outputs errors to stdErr. Sadly, I dont know how to get the output.
ReadProgramError() only works with a program parameter which I do not have (because it is my own running process).
Any idea how to get the stdErr of the DLL in my own process?
Thank you,
Kukulkan
How to get my own stdErr output?
Re: How to get my own stdErr output?
It is possible to redirect it to a file. The following code works on Windows:
Note that you should do the replacing of the handle before you load your dll, because it may be possible that the dll reads and stores the handle somewhere in a variable in which case changing the standard handle after that will have no effect. For example in PB, after OpenConsole() is called, changing the handle has no effect anymore because the console lib stores the handle in its own variable.
A similar thing should be possible on OSX by importing the "stderr" variable and changing it. Note that I did not try the code below as I don't have OSX available right now. The variable could also be named "_stderr" or similar on OSX. You may have to do a bit trial & error there:
It is also possible to redirect to a pipe so no file is needed, but this is more complex because you have to read from the pipe at the same time that the dll writes to it (or the program will lock up) which would require using threads. If redirecting to a file is enough then this is definitely the simpler solution.
Code: Select all
; Create file for redirection
CreateFile(0, "test.txt")
; Replace the standard error handle with the created file
oldHandle = GetStdHandle_(#STD_ERROR_HANDLE)
SetStdHandle_(#STD_ERROR_HANDLE, FileID(0))
; do some output
OpenConsole()
For i = 1 To 10
ConsoleError("StdErr Message" + i)
Next i
CloseConsole()
; restore original handle
SetStdHandle_(#STD_ERROR_HANDLE, oldHandle)
; close file
CloseFile(0)A similar thing should be possible on OSX by importing the "stderr" variable and changing it. Note that I did not try the code below as I don't have OSX available right now. The variable could also be named "_stderr" or similar on OSX. You may have to do a bit trial & error there:
Code: Select all
ImportC ""
stderr.i
EndImport
; Create file for redirection
CreateFile(0, "test.txt")
; Replace the standard error handle with the created file
oldStdErr = stderr
stderr = FileID(0)
; do some output
OpenConsole()
For i = 1 To 10
ConsoleError("StdErr Message" + i)
Next i
CloseConsole()
; restore original handle
stderr = oldStrErr
; close file
CloseFile(0)quidquid Latine dictum sit altum videtur
Re: How to get my own stdErr output?
Hello freak,
thank you very much! Indeed, this seems a solution.
Do you think it is possible to use something "in memory" instead of using a file? Maybe some "memory writer" output?
Kukulkan
thank you very much! Indeed, this seems a solution.
Do you think it is possible to use something "in memory" instead of using a file? Maybe some "memory writer" output?
Kukulkan
Re: How to get my own stdErr output?
Yes, but its more complex. You need threads to prevent a deadlock between the writing and reading of the stream then.
quidquid Latine dictum sit altum videtur
Re: How to get my own stdErr output?
I will try the file thing then...
Thank you!
Kukulkan
Thank you!
Kukulkan
Re: How to get my own stdErr output?
I thought to post here since freak's suggested code sounds like a fit?
I use fossil.exe in a cmd prompt as my SCM and for a failed commit it outputs an error to the console.
If I try to pipe that message to a file so I can read it in code it creates an empty file and spits the error out as before.
If I try freak's code above, I also get nothing.
My point for all this is to automate some repetitive steps and handle errors. However, I cannot get the error returned from this command?
Indirectly I can prevent this error by asking fossil if there is anything to commit. But, this inability to read the output worries me for future commands.
I use fossil.exe in a cmd prompt as my SCM and for a failed commit it outputs an error to the console.
Code: Select all
c:\tryfossil>fossil commit --user me -M commit.txt
nothing has changed; use --allow-empty to override
Code: Select all
c:\tryfossil>fossil commit --user me -M commit.txt > fossilout.txt
nothing has changed; use --allow-empty to override
My point for all this is to automate some repetitive steps and handle errors. However, I cannot get the error returned from this command?
Code: Select all
rp = RunProgram("fossil.exe", "commit --user me -M c:\tryfossil\commit.txt", "c:\tryfossil\", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: How to get my own stdErr output?
Never mind, another case of RTFM! Didn't see ReadProgramError()
Code: Select all
rp = RunProgram("cmd.exe", "/c fossil.exe commit --no-warnings --user me -M " + *r\Path$ + #fos_commit$, *r\Path$, #PB_Program_Open | #PB_Program_Read | #PB_Program_Error | #PB_Program_Hide)
If rp
*r\e$ = #NULL$
*r\e$ = ReadProgramError(rp)
EndIf
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum

