Discussion:
Calling a console app and pausing before exit?
(too old to reply)
Harry Potter
2018-10-15 23:14:05 UTC
Permalink
I have a Win32 C program that calls a console app before exiting, and I want to be able to read the console app's output before exit and need to get it to pause. How do I do that?
JJ
2018-10-16 10:10:59 UTC
Permalink
Post by Harry Potter
I have a Win32 C program that calls a console app before exiting,
Just execute the app just like normal, except in this case, at the end of
the C program flow.
Post by Harry Potter
and I want to be able to read the console app's output before exit
Use pipes.
Post by Harry Potter
and need to get it to pause. How do I do that?
If the C program is not a console based program, create the console window
before executing the child program. Once the child program ends, you can
prompt an input before closing the console window.
Harry Potter
2018-10-16 12:08:26 UTC
Permalink
Post by JJ
Post by Harry Potter
and I want to be able to read the console app's output before exit
Use pipes.
Post by Harry Potter
and need to get it to pause. How do I do that?
If the C program is not a console based program, create the console window
before executing the child program. Once the child program ends, you can
prompt an input before closing the console window.
It is. I'm using CreateProcess() to start the console application. It starts the app normally but doesn't pause before exit. I looked the function up on MSDN but didn't find the necessary information. How do I get the app to pause without using a batch file?
R.Wieser
2018-10-16 12:39:29 UTC
Permalink
Harry,
Post by Harry Potter
I'm using CreateProcess() to start the console application.
In that case, take a look at WaitForSingleObject.

Also don't forget to take care of the handles returned by CreateProcess.
IIRC there are two, and you must close them both (or have the process stay
alive as a ghost - just taking up resources)

Regards,
Rudy Wieser
Harry Potter
2018-10-16 13:25:46 UTC
Permalink
Post by R.Wieser
In that case, take a look at WaitForSingleObject.
Thanks! :)
Post by R.Wieser
Also don't forget to take care of the handles returned by CreateProcess.
IIRC there are two, and you must close them both (or have the process stay
alive as a ghost - just taking up resources)
I do.
R.Wieser
2018-10-16 14:10:51 UTC
Permalink
Harry,
Post by Harry Potter
Post by R.Wieser
In that case, take a look at WaitForSingleObject.
Thanks! :)
You're welcome. :-)
Post by Harry Potter
Post by R.Wieser
Also don't forget to take care of the handles returned by CreateProcess.
I do.
The first few times I used CreateProcess I forgot :-\

And another function you might like : GetExitCodeProces

With just a bit of luck your console-based program returns a status you can
use (instead of needing to parse the what it (normally) displays on the
console).

Regards,
Rudy Wieser
Harry Potter
2018-10-20 20:23:30 UTC
Permalink
Post by R.Wieser
In that case, take a look at WaitForSingleObject.
I just looked up WaitForSingleObject() on MSDN. It doesn't do what I need to do. :(
R.Wieser
2018-10-20 21:00:43 UTC
Permalink
Harry,
Post by Harry Potter
I just looked up WaitForSingleObject() on MSDN. It doesn't
do what I need to do. :(
Explain please. What does(n't) it do ?

I've been using it myself, and it does for me. One difference though: I've
been running GUI programs, not console. But I''l test it tomorrow to make
sure it works (too late on the day now).

And also take a look at ShellExecuteEx. It will allow you to "start" even
textfiles or (JS, VBS) scripts.

Regards,
Rudy Wieser
Harry Potter
2018-10-20 21:20:58 UTC
Permalink
Post by R.Wieser
Harry,
Post by Harry Potter
I just looked up WaitForSingleObject() on MSDN. It doesn't
do what I need to do. :(
Explain please. What does(n't) it do ?
I want to wait for a key press, not for a particular period of time.
R.Wieser
2018-10-21 07:17:31 UTC
Permalink
Harry,
Post by Harry Potter
Post by R.Wieser
Explain please. What does(n't) it do ?
I want to wait for a key press, not for a particular period of time.
Its not ment to just wait (you could use Sleep for that), the provided time
is there just as a fail-safe. The idea is that you can close the command
console (by its X), and than continue your program.

But ... I was mistaken. The console window will just close, and
WaitForSingleObject will just wait until it sees that happen. Which is not
what you where looking for. :-(


The actual answer is rather simple though: Let CreateProcess run CMD.EXE
(use full path), and provide the program you want to start, pre- and
postfixed with "/c " and " & pause", as the argument. So, "/c {your
program} & pause"

The "/c" causes the command interpreter to run {your program}, and the "&"
will than follow that up with the "pause" command.

If you want {your program} to run but the console window to stay open
afterwards (use "quit" or the "X" to close) use "/k {your program}" instead

Actually, you can use everyting as you can find under "cmd /?" :-)

Hope that helps.

Regards,
Rudy Wieser
Harry Potter
2018-10-21 10:33:55 UTC
Permalink
R.Wieser: Thanks! :)
R.Wieser
2018-10-21 11:11:48 UTC
Permalink
Harry,
Post by Harry Potter
R.Wieser: Thanks! :)
You're welcome. :-)

By the way, if you do *not* use WaitForSingleObject you are allowing your
program (the one executing CreateProcess) to continue parallel with the
console (and its program). Which could mean that if you than execute
another CreateProcess the programs appear ontop of, instead of after each
other.

In other words, WaitForSingleObject does certainly have its use.

Regards,
Rudy Wieser
Harry Potter
2018-10-21 13:06:37 UTC
Permalink
R.Wieser: By "specify full path," do you mean for cmd.exe or the console program? If the latter, that should be easy, as I'm already specifying the full path of the latter.
R.Wieser
2018-10-21 13:52:52 UTC
Permalink
Harry,
Post by Harry Potter
R.Wieser: By "specify full path," do you mean for cmd.exe or
the console program?
The former. CreateProcess does not search for the program its told to
execute.

And a suggestion: Expand the %COMSPEC% environment variable and use that.
That way your program will be able to run on anyones machine, regardless of
on which drive their OS resides or which command-interpreter they normally
use (might be different than "cmd.exe").

In other words: Do not use a hard-coded path.

Regards,
Rudy Wieser
Harry Potter
2018-10-21 14:17:20 UTC
Permalink
Uhh...I have another problem: which parameter of CreateProcess() is the program to execute, and which is the command line? I couldn't find the function on MSDN.
R.Wieser
2018-10-21 17:35:00 UTC
Permalink
Harry,
Post by Harry Potter
which parameter of CreateProcess() is the program to execute
Which one did you use when the commandbox didn't want to stay around ?
*Thats* the program to execute (cmd.exe is just another program. Its just
*us* who think its special :-) )

Also, the argument is called "ApplicationName". And "application" is just a
fancy name for "program".
Post by Harry Potter
and which is the command line? I couldn't find the function on MSDN.
Really ? What is the name of the second argument of the CreateProcess
function ? And what where you looking for ? The difference is just a
space and uppercasing of two letters ... How come you missed it ?


And an even better question: How come you did not google it ? I thew a
"CreateProcess command line" (without those doublequotes) into it - which is
*exactly* the words you where using - , and the third result was named "How
to pass command line arguments when using CreateProcess ...". Its someone
with the same problem as you (from way-back-when in 2002), and the answer
(with full code!) is in there.

So, a warning. I like to help you, but if I (again) get the feeling that
you rather ask me than to try to find (google) it yourself first than I will
(again) stop trying to help you. Its upto you.

Regards,
Rudy Wieser
Harry Potter
2018-10-21 17:52:25 UTC
Permalink
I thank you, and I'm sorry about the last issue. I didn't think to look on Google, just MSDN. :(
Harry Potter
2018-10-21 18:37:49 UTC
Permalink
It works, but one more issue: if I quote the console app. name, the console window displays an error message quoting the whole command line after the initial quote as an invalid program file. :(
R.Wieser
2018-10-21 20:58:50 UTC
Permalink
Harry,
Post by Harry Potter
I thank you, and I'm sorry about the last issue.
I didn't think to look on Google, just MSDN. :(
True, MSDN offers good reference material. But I'm afraid that if you
really want to know how to *use* functions that MSDN describes you most
alway need to look elsewhere.
Post by Harry Potter
It works, but one more issue: if I quote the console app.
name, the console window displays an error message
quoting the whole command line after the initial quote as
an invalid program file. :(
I said it before, and I repeat it here:

1) Post the full error message.

2) Post the involved code.

Without it is *very* hard to even get an idea of what might be going on. :-(

But my guess ? You are using quotes within a quoted string (the
commandline argument). Quotes *within* strings need special consideration.
Like escaping them.

Possibly something like this: "one \"two\" three". If printed that would
show as
one "two" three

Regards,
Rudy Wieser
Harry Potter
2018-10-21 21:08:34 UTC
Permalink
The error message is:

'C:\Emulators\C64\exomizer-2.0.10\win32\exomizer.exe" sfx basic -t64 -x1 -o "com
press64.prg" "compress64.prg' is not recognized as an internal or external comma
nd,
operable program or batch file.
Harry Potter
2018-10-21 21:19:26 UTC
Permalink
The command line is:

/c "C:\Emulators\C64\exomizer-2.0.10\win32\exomizer.exe" sfx basic -t64 -x1 -o "compress64.prg" "compress64.prg"&pause
R.Wieser
2018-10-21 21:48:24 UTC
Permalink
Harry,
The error message is: [snip]
*That* points to a program that isn't found (duh!), not a quoting problem.

And thats exactly why you should ALWAYS post the error message.
/c "C:\Emulators\C64\exomizer-2.0.10\win32\exomizer.exe" sfx
basic -t64 -x1 -o "compress64.prg" "compress64.prg"&pause
Have you already checked if that
"C:\Emulators\C64\exomizer-2.0.10\win32\exomizer.exe" will run the program
if that string(without the surrounding quotes) is put in the "run" box (in
the start menu) ?

Also, do not post snips-and-snaps, post the whole involved function. Just
copy-and-paste it from your code.

And try to post the involved info in a *single* message.

Regards,
Rudy Wieser
Harry Potter
2018-10-21 22:17:59 UTC
Permalink
Post by R.Wieser
Harry,
The error message is: [snip]
*That* points to a program that isn't found (duh!), not a quoting problem.
It *does* exist. The string without quotes works.
Post by R.Wieser
And thats exactly why you should ALWAYS post the error message.
/c "C:\Emulators\C64\exomizer-2.0.10\win32\exomizer.exe" sfx
basic -t64 -x1 -o "compress64.prg" "compress64.prg"&pause
Have you already checked if that
"C:\Emulators\C64\exomizer-2.0.10\win32\exomizer.exe" will run the program
if that string(without the surrounding quotes) is put in the "run" box (in
the start menu) ?
I don't have a Run... command on my Start menu. I have Win10/64. But it runs on the Command Prompt.
Post by R.Wieser
Also, do not post snips-and-snaps, post the whole involved function. Just
copy-and-paste it from your code.
I think I revealed enough to help me with this issue.
Post by R.Wieser
And try to post the involved info in a *single* message.
I'm sorry. The second post was an afterthought. :(
R.Wieser
2018-10-22 06:54:14 UTC
Permalink
Harry,
Post by Harry Potter
I'm sorry. The second post was an afterthought. :(
Maybe you should read the "how to post a question" FAQ again.
Post by Harry Potter
It *does* exist. The string without quotes works.
And THAT is why I asked you to post *the whole function call*. Not all of
the code, just one frigging function.
Post by Harry Potter
I think I revealed enough to help me with this issue.
OK., But in that case I can't help you.

The problems for me ?

1) You post absolutily vague "it doesn't work!" blurbs

2) You do not even post the involved error message

3) From the above I have to GUESS to what the problem might be, and by it
now having wasted my time *twice*.

4) I have to pull each - and - ever - bit - of - information outof you, and
than you either ignore it or just post something less than usefull.

5) None of what you have posted - even after me having asked for it several
times - touches the actual problem.

I'm sorry kid, but this isn't going to work. I really would like to help
you, but having to fight you all of the way isn't my cup of tea. And I'm
not willing to just post full working snippets of what your code *should*
look like, as you can google those for yourself.

Good luck with your program. Goodbye. Again.

Regards,
Rudy Wieser
Harry Potter
2018-10-22 16:07:18 UTC
Permalink
I'm sorry again. :( The actual code follows:
-----------------------------------
CreateProcess (
comspec,
cmd,
0,
0,
0,
CREATE_NEW_CONSOLE,
0,
lpath,
&start,
&inf);
WaitForSingleObject (inf.hProcess, INFINITE);
CloseHandle (inf.hProcess);
CloseHandle (inf.hThread);
------------------------------
The following code produces the comspec variable to get the cmd.exe path:
------------------------------
ExpandEnvironmentStrings ("%comspec%", &comspec, 256);
------------------------------
The following code builds the string for the program to run:
------------------------------
static void writecmd (void)
{
strcpy (cmd, "/c \"");
strcat (cmd, exomdir);
strcat (cmd, "\\exomizer.exe\" sfx basic -t");
//itoa (systxt, flags.sys, 10); strcat (cmd, systxt);
sprintf (systxt, "%d", flags.sys); strcat (cmd, systxt);
strcat (cmd, " -x1 -o ");
strcat (cmd, file);
strcat (cmd, " ");
strcat (cmd, file);
strcat (cmd, "&pause");
}
file is the file to feed to exomizer.exe. lpath is the folder that contains the file fed to exomizer.exe.

Does this help?

Uwe Kotyczka
2018-10-18 20:57:35 UTC
Permalink
Post by JJ
Post by Harry Potter
I have a Win32 C program that calls a console app before exiting,
Just execute the app just like normal, except in this case, at the end of
the C program flow.
Post by Harry Potter
and I want to be able to read the console app's output before exit
Use pipes.
You may check out my demo "ShellWin32" to see how to
redirect stdin/stdout/stderr using pipes:
http://kotyczka.byethost24.com/samples_en.html
Post by JJ
Post by Harry Potter
and need to get it to pause. How do I do that?
If the C program is not a console based program, create the console window
before executing the child program. Once the child program ends, you can
prompt an input before closing the console window.
HTH
Harry Potter
2018-10-18 23:14:47 UTC
Permalink
Post by Uwe Kotyczka
Post by JJ
Use pipes.
You may check out my demo "ShellWin32" to see how to
http://kotyczka.byethost24.com/samples_en.html
I don't want to redirect output. I simply want to pause the program just before exit so the user can read the program's output.
JJ
2018-10-19 21:39:48 UTC
Permalink
Post by Harry Potter
Post by Uwe Kotyczka
Post by JJ
Use pipes.
You may check out my demo "ShellWin32" to see how to
http://kotyczka.byethost24.com/samples_en.html
I don't want to redirect output. I simply want to pause the program just
before exit so the user can read the program's output.
I don't think you know what you're dealing with. Without any redirection,
reading the console text of other process requires reading that process'
memory space - which is much more complicated than you think.
Harry Potter
2018-10-20 20:19:25 UTC
Permalink
Post by JJ
I don't think you know what you're dealing with. Without any redirection,
reading the console text of other process requires reading that process'
memory space - which is much more complicated than you think.
I am *not* redirecting the program's output nor do I want to. I merely want to *pause* the console program before exit so the user can see the program's output.
Harry Potter
2018-10-20 21:19:15 UTC
Permalink
Post by Harry Potter
I have a Win32 C program that calls a console app before exiting, and I want to be able to read the console app's output before exit and need to get it to pause. How do I do that?
Let me try again. I am creating a Win32 C program that uses CreateProcess() to start another program. The other program is a console application. When using a batch file to run a program, I can add the PAUSE command to pause the file and request the user to press a key. I want to do the same, but without a batch file, rather, just before the console app exits. I am not an expert Win32 API programmer, as you can probably tell, so I'm using the following code to call the app:
----------------------------
CreateProcess (
0,
cmd,
0,
0,
0,
CREATE_NEW_CONSOLE,
0,
lpath,
&start,
&inf);
WaitForSingleObject (inf.hProcess, INFINITE);
CloseHandle (inf.hProcess);
CloseHandle (inf.hThread);
---------------------------------------
BTW, in this case, I don't need to wait for console program to finish before exiting my code, as the console execution is the last thing my program does. BTW, the console program is *not* mine, just the calling code.

I just looked on MSDN for the CreateProcess() function, and the closest I found was the CreateProcessA() function, and it had references but no link to CreateProcess(). Where can I find info directly on CreateProcess()?
JJ
2018-10-21 10:00:06 UTC
Permalink
Post by Harry Potter
BTW, in this case, I don't need to wait for console program to finish
before exiting my code, as the console execution is the last thing my
program does. BTW, the console program is *not* mine, just the calling
code.
Do not use CREATE_NEW_CONSOLE. If you use CREATE_NEW_CONSOLE, you will not
have any control over the new console window because it belong to the child
process rather than yours.

So, before executing the child process, create your own new console window
using AllocConsole(). Attach self to the new console. Then execute the child
process *without* CREATE_NEW_CONSOLE.

And don't remove the WaitForSingleObject().
Loading...