LCF-AT Posted February 3, 2019 Share Posted February 3, 2019 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 Link to comment Share on other sites More sharing options...
Viloresi Posted February 3, 2019 Share Posted February 3, 2019 for the errors handling in the cmd there is just the errorlevel I guess : https://ss64.com/nt/errorlevel.html 1 Link to comment Share on other sites More sharing options...
Progman Posted February 3, 2019 Share Posted February 3, 2019 (edited) 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 February 3, 2019 by Progman 1 Link to comment Share on other sites More sharing options...
LCF-AT Posted February 3, 2019 Author Share Posted February 3, 2019 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 Link to comment Share on other sites More sharing options...
LCF-AT Posted February 4, 2019 Author Share Posted February 4, 2019 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 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now