Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Reading console output from external executable (fxc)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 07:58 AM

Not sure if you are familiar with the fxc.exe file. It's basically a command line based application to compile shader files.

Anyway what I want to do is call this at a specific point in my actual application (win32) and output the log inside of my console GUI which accepts a string. So I need to catch the console output of this application that I call and write it in a buffer.

 

I've been trying to find a solution to this for a bit but haven't gotten far.

I've only managed to find out that I need to somehow direct the output of that application using pipes to my application or something...

But I'm clueless on how to do so.

 

Does anyone know how to do that or has already done that before ?



Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9673

Like
3Likes
Like

Posted 19 March 2013 - 08:14 AM

This MSDN article shows the necessary API functions necessary to redirect the standard input and output handles of a child process.

#3 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 08:22 AM

So there's no simpler way to do that ? (keep in mind I just want to read not write to the application, plus I have no control over this child application's code)

 

I've tried something like:

	char buffer[BUFFER_SIZE];

	FILE* test = _popen("fxc.exe", "r");
	if(test)
	{
		char* line_p = fgets(buffer, sizeof(buffer), test);
		_pclose(test);
	}

 

but it always reads nothing. Works when using "dir" as command.



#4 Cosmic314   Members   -  Reputation: 1261

Like
1Likes
Like

Posted 19 March 2013 - 08:29 AM

Does fxc.exe buffer its output?  Use the function fflush(test) to empty the buffer to the OS.

 

Edit:  You'll also need to provide input to fxc.exe.  Your _popen should be something like FILE *test = _popen("fxc.exe <shader_input_file>","r");


Edited by Cosmic314, 19 March 2013 - 08:38 AM.


#5 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 08:38 AM

Just tried doing that before reading. Still nothing. When running it the console window pops up and closes right after.

 

edit: There's something written about how to read the error's and output here (bottom of the page) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509710(v=vs.85).aspx but they state nowhere what "hReadOutPipe" or "hReadErrorPipe" is or how it was created.

 

@Cosmic314 I know but it still outputs an error that states that which is the reason why I want to read its output in the first place.


Edited by lipsryme, 19 March 2013 - 08:47 AM.


#6 Cosmic314   Members   -  Reputation: 1261

Like
1Likes
Like

Posted 19 March 2013 - 08:47 AM

Do you specify the full path to the input file?  Maybe your program is running in a different directory than your input source?



#7 Cosmic314   Members   -  Reputation: 1261

Like
2Likes
Like

Posted 19 March 2013 - 08:55 AM

@Cosmic314 I know but it still outputs an error that states that which is the reason why I want to read its output in the first place.

 

_popen only opens the process' standard output.  If you need to read stderr redirect it to stdout via:  FILE *test = _popen("fxc.exe <your_options> 2>&1","r");  

 

'stderr' is represented by the 2 file descriptor hence the "2>&1".

 

Edit:  Sorry, forgot to add "2>&1".


Edited by Cosmic314, 19 March 2013 - 08:57 AM.


#8 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 08:59 AM

Hmm it's odd I just tried it with another console application, where it works. Running fxc.exe does not give me any output though...

@Cosmic314 So the text that it outputs in the cmd.exe is not the standard output ?

 

UPDATE: That worked! Thanks a lot :D


Edited by lipsryme, 19 March 2013 - 09:02 AM.


#9 Cosmic314   Members   -  Reputation: 1261

Like
1Likes
Like

Posted 19 March 2013 - 09:04 AM

Hmm it's odd I just tried it with another console application, where it works. Running fxc.exe does not give me any output though...

@Cosmic314 So the text that it outputs in the cmd.exe is not the standard output ?

It all depends on how fxc.exe writes its messages.  It sounds like it opens both STDOUT and STDERR which is typical in console applications (I'm in Linux land and that's standard fare).  I'm guessing fxc.exe does just this and when it encounters errors it spits it out to STDERR.

 

The reason for this is to easily separate errors from expected output.  Instead of using 2>&1 you could instead do 2> file.txt and the STDERR stream would go to a file instead.



#10 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 09:08 AM

So what 2>&1 does is redirect the output of stderr (being 2) to the stdout (being 1) ?

Is there also a way to check when it is done compiling before I execute the _pclose() function ?

I guess I could check the buffer whenever it contains the success message but I suppose that wouldn't be the most elegant way of doing it.


Edited by lipsryme, 19 March 2013 - 09:10 AM.


#11 Cosmic314   Members   -  Reputation: 1261

Like
2Likes
Like

Posted 19 March 2013 - 09:09 AM

So what 2>&1 does is redirect the output of stderr (being 2) to the stdout (being 1) ?

Is there also a way to check when it is done compiling before I execute the _pclose() function ?

 

Yes.

 

Sorry, just saw the second part.

 

Check your file pointer against feof(test) before using it.  Something like:

 

while( !feof(test) )
{
   ...
}

Edited by Cosmic314, 19 March 2013 - 09:13 AM.


#12 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 09:19 AM

Great. Thanks a lot.



#13 NightCreature83   Crossbones+   -  Reputation: 3034

Like
0Likes
Like

Posted 19 March 2013 - 05:15 PM

Just tried doing that before reading. Still nothing. When running it the console window pops up and closes right after.
 
edit: There's something written about how to read the error's and output here (bottom of the page) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509710(v=vs.85).aspx but they state nowhere what "hReadOutPipe" or "hReadErrorPipe" is or how it was created.
 
@Cosmic314 I know but it still outputs an error that states that which is the reason why I want to read its output in the first place.

You realise that MS code heftly relies upon hungarian code standard so the lowercase h in front of the vars should be a hint to you that these are Handles. The handles come from the call to CreateProcess and actually are returned to you through the STARTUPINFO structure that comes out of the CreateProcess call.

Reading documentation is also a skill and the MS ones are not easy but once you do get used to them the actually do tell you everything you need to know. All I did to figure out where the handles where coming from was to go to the CreateProcess documentation page and from there to the STARTUPINFO documentation. That together with the names of the handles made me realise they should map to HANDLE hStdOutput; HANDLE hStdError; that are in the startup info.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#14 lipsryme   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 19 March 2013 - 05:39 PM

I do realize that they were handles to the standard outputs, it's just that I had no idea how they work or how I create "NamedPipes"...I guess I did not check up on the STARTUPINFO documentation. But I guess you have to realize that some people with less experience than you can't figure that out in a matter of seconds.
And I did not feel like wasting an hour figuring out how this system works.
Anyway I've got it working now using the previous solution.

Edited by lipsryme, 19 March 2013 - 05:40 PM.


#15 NightCreature83   Crossbones+   -  Reputation: 3034

Like
1Likes
Like

Posted 20 March 2013 - 02:31 AM

Yeah the post might have read hostile after rereading I didn't mean it that way though. All I meant is that reading MS docs is a skill and you will have to learn how to do this, they contain a lot of information and not always in the clearest manner. I found the most important bits to read on those are always the remarks as they most likely explain why something isn't working, and other then that it is an exercise in reading and understanding what you read.


Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS