Jump to content
Tuts 4 You
Sign in to follow this  
LCF-AT

How to read errors or success from same handle?

Recommended Posts

LCF-AT

Hi guys,

I have a small question about commandline handles and reading from stdout and how to differ whether I got a error info or success.

Example: I have created a GUI app and a CLI app.Now I wanna run my CLI app from the GUI app and reading the results from pipe.My question now is how to know whether the CLI app did made success or whether it made a error?How to differ that in my GUI app?

Example about it.If I just run the CMD window and enter any command into like ipconfig then it does return the results of it = success.Now if I enter the same command wrong like ipkonfig then it does return a error info like "command  not found or valid etc" you know = Error.Now if I run the CMD with ipconfig or ipkonfig from a GUI app using CreateProcess / CreatePipe etc then I do read from stdout what I got = I get the ipconfig results on success or I get the error info.The main question for me is now how to know whether it was successfully or a error without any manually error string checkings etc?

Is there a way to check that anyhow?I thought it can be done if I just send error messages seperated into hStdError handle and success results into hStdOutput handle.So I hope you guys know what I mean.

CLI app calcthis.exe

calcthis.exe -c 10+10

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Now in my CLI app I do calc this values if paramter -c is present and a value content too...

on success I do
invoke GetStdHandle,STD_OUTPUT_HANDLE
invoke WriteFile,....

on any failed operation I do same...
invoke GetStdHandle,STD_OUTPUT_HANDLE
invoke WriteFile,.... // print error "Failed because of xy reason"

So my  main question is whether its correct to send success results and error messages into same STD_OUTPUT_HANDLE or not?If yes,how to handle it them from a GUI app to find out whether it was successfully or failed?Or is that usually not possible and I always need to check the error text messages itself?Sounds anyhow pretty bad to do that.Does anyone maybe know how to deal with that?

greetz

Share this post


Link to post
Progman

Probably you want to send the error messages into the STD_ERROR_HANDLE and despite that stdout and stderr are typically both bound the console output, they typically wont interleave in display if simultaneously written because of buffering features that wait for a new line or a flush command.  But they are separate handles and devices which can be monitored.  From command line there is 

calcthis.exe -c 10+10 < inputfile > outputfile 2> errorfile
calcthis.exe -c 10+10 < inputfile > outputfile 2>&1

The latter command binds stderr to stdout (in fact > outputfile and 2> outputfile would cause undesirable interleaving).

 

As mentioned above, the process exit code of negative typically indicates an error while 0 or positive is some type of success.  Doing both is the usual technique but its more efficient to merely check the exit code rather than textual messages on stdout and stderr which are the detailed information.

Edited by Progman (see edit history)
  • Like 1

Share this post


Link to post
LCF-AT

Hi,

hmmm not sure about that.

So I see I have to send error messages into hStdError handle seperated and success traffic into hStdOutput handle but here I have a problem.In my other pipe example codes I made before and examples I found on internet are piped both to same (write & error).

I am using CreatePipe function where I can only get read & write handles back and these I fill into STARTUPINFO struct.The write handle into hStdOutput & hStdError.Output and errors using same handle now.I think somehow I need to create another pipe just for the hStdError but how to do that?

Only way at the moment I could use is just not fliling the hStdError with the write handle = I only get success traffic or nothing (if I send error messages to STD_ERROR_HANDLE in my CLI app).But also in this case I only know that my CLI app did fail but I dont know the reason why it did fail.

Example about CMD.exe: As I told above about ipconfig command.If I execute it right then I can read the results from STD_OUTPUT_HANDLE = OK.If I enter the command wrong then CMD does send the error into STD_ERROR_HANDLE.But if I enter this command ipconfig /allll then it does send the error and example syntax into STD_OUTPUT_HANDLE.

PS: I think I got it now.Just creating another pipe and putting the write handle of it into hStdError of STARTUPINFO struct.If I now get nothing back from hStdOutput then I read from hStdError. :) Now I can read all seperated for success traffic or errors.

greetz

Share this post


Link to post
LCF-AT

Hi again,

sorry Progman,I didnt seen your post before.Yes the problem is that I bound both output / error to same location what makes it not possible to check for success or error.So in my case I just run the CLI app from outside location / application via CreateProcess cmd /c mode what does close the CLI app by itself.Reading the text / erros etc in CMD window is not needed for my task just getting the ouput traffic or error traffic (if something fail).If I get nothing on output traffic pipe then I know that something  was going wrong and then I can read the error pipi to get the xy error message.

invoke CreatePipe,addr hRead,addr hWrite,addr SecuAttr,NULL 
invoke CreatePipe,addr hReadError,addr hWriteError,addr SecuAttr,NULL

        mov StartInfo.cb,sizeof StartInfo
        invoke GetStartupInfo,addr StartInfo
        xor eax,eax
        mov StartInfo.lpReserved,eax     
       
        mov eax,hWrite
        mov StartInfo.hStdOutput,eax ; <--- 1. pipe write handle
        mov eax, hWriteError         ; <--- 2. pipe write handle
        mov StartInfo.hStdError,eax  ; <--- to hStdError
        mov eax, hRead 
        mov StartInfo.hStdInput,eax  ; <--- 1. pipe read handle

	    mov StartInfo.dwFlags, STARTF_USESTDHANDLES
        mov StartInfo.wShowWindow,SW_SHOW


Later on reading I wrote this...

invoke PeekNamedPipe,hRead,addr PIPEBUFFER,.... ; read from 1. pipe
.if eax != FALSE
     ; normal reading from first pipe / loop = success
.else
    invoke PeekNamedPipe,hReadError,addr PIPEBUFFER,.... ; read from 2. pipe error 
    ....
    invoke MessageBox,hWnd,addr PIPEBUFFER,chr$("ERROR Happens!"),MB_ICONINFORMATION
    ....
.endif

So this seems to work.Just important for me to know that how to deal with this for my own CLI apps later.Now I know to send error messages only into error pipe and not into same output pipe.

greetz

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×
×
  • Create New...