Run .bat file
-
Hi,
my .bat file on Windows pauses itself (pause; waiting for user input). I launch this bat file with:QStringList param; param << "/c" << "a.bat"; QProcess process; process.start("cmd.exe", param); process.waitForStarted(-1); process.waitForFinished(-1);
The problem is that my program doesn't open any window for this process so I'm unable to unpause my bat file. My program is therefore stuck forever on waitForFinished line.
How to launch bat file with window?
-
Hi,
my .bat file on Windows pauses itself (pause; waiting for user input). I launch this bat file with:QStringList param; param << "/c" << "a.bat"; QProcess process; process.start("cmd.exe", param); process.waitForStarted(-1); process.waitForFinished(-1);
The problem is that my program doesn't open any window for this process so I'm unable to unpause my bat file. My program is therefore stuck forever on waitForFinished line.
How to launch bat file with window?
-
You are right, thank you. However, it seems that waitForFinished doesn't work with startDetached as I need. I need to sequentially execute several bat files, waiting for finish of the previous one to launch next one. How is that achievable?
@MartinD
Yep, that is problematic if you have to usestartDetached
to get a console window....!While I'm thinking about it, have a read of https://stackoverflow.com/a/31724745/489865 ... Also https://stackoverflow.com/a/42292619/489865 for more bad news...
EDIT1 https://forum.qt.io/topic/40962/qprocess-start-doesn-t-display-a-console-window-for-console-programs-windows discusses this. If I read right, it says that the non-Qt
system()
function does just what you want. (Yep, https://stackoverflow.com/a/45595224/489865 confirms this.) Would that be acceptable?Otherwise you may have to get into calling the Windows
AllocConsole
as per https://stackoverflow.com/a/48867208/489865 ....) Or, possibly, take the pid returned fromstartDetached()
and do your own Window calls to wait on it. Which is whysystem()
would be much easier :) -
The system call almost suits my needs, but I also need to set working dir of the process. Not sure if it is possible with system().
EDIT: This might be the solution:
system("cd /D C:\mypath && a.bat");
@MartinD
Sigh, you don't ask for much! :)The current directory stuff was in one of the links I gave you, from https://forum.qt.io/topic/40962/qprocess-start-doesn-t-display-a-console-window-for-console-programs-windows/11 downward. You can do it a variety of ways, https://forum.qt.io/topic/40962/qprocess-start-doesn-t-display-a-console-window-for-console-programs-windows/13 probably being the definitive explanation/suggestion.
pushd
does the same sort of thing ascd /d
, one possible benefit being that it handles connecting to & disconnecting from network paths a bit better. Though not quite sure why the Qt program's current directory isn't suitable for your bat file (system()
inherits parent's current directory, parent could chdir somewhere and then chdir back on completion)), or specify a full path to the bat file, or have the bat file do thecd
, but whatever.P.S.
As a by-the-by to all this: you said you were happy writing Windows specific code, ultimately all these solutions will call Windows::CreateProcess()
you could use that yourself directly to give yourself full control over everything such as detaching & creating a new console if you really find you need to/prefer that. Just a heads-up. -
@MartinD
Sigh, you don't ask for much! :)The current directory stuff was in one of the links I gave you, from https://forum.qt.io/topic/40962/qprocess-start-doesn-t-display-a-console-window-for-console-programs-windows/11 downward. You can do it a variety of ways, https://forum.qt.io/topic/40962/qprocess-start-doesn-t-display-a-console-window-for-console-programs-windows/13 probably being the definitive explanation/suggestion.
pushd
does the same sort of thing ascd /d
, one possible benefit being that it handles connecting to & disconnecting from network paths a bit better. Though not quite sure why the Qt program's current directory isn't suitable for your bat file (system()
inherits parent's current directory, parent could chdir somewhere and then chdir back on completion)), or specify a full path to the bat file, or have the bat file do thecd
, but whatever.P.S.
As a by-the-by to all this: you said you were happy writing Windows specific code, ultimately all these solutions will call Windows::CreateProcess()
you could use that yourself directly to give yourself full control over everything such as detaching & creating a new console if you really find you need to/prefer that. Just a heads-up. -
@JonB Thanks for your replies. Thats all I need :)
There are also other than .bat commands I want to run - they need to be launched in specific directory, different from Qt app's current directory.
@MartinD
Just so you know: personally (I'm just a Qt user, not a Qt person) I agree that it's a bit of a mess that, say,startDetached()
opens a console but cannot be waited, whilestart()
can be waited but cannot open a console. Ifstart()
could have an option to create a console (andstartDetached()
have an option not to create one!) your reasonable question would never have been such a problem.... -
I spent an hour debugging why this:
system("C:/a.bat");
launches console but displays nothing from a.bat in the console (no output to console)
and this:
system("cmd.exe /c C:/a.bat");
launches console and displays all output from a.bat in the console.
I noticed that the first command's output goes to Application output window in Qt Creator. Just for curiosity, why?
-
I spent an hour debugging why this:
system("C:/a.bat");
launches console but displays nothing from a.bat in the console (no output to console)
and this:
system("cmd.exe /c C:/a.bat");
launches console and displays all output from a.bat in the console.
I noticed that the first command's output goes to Application output window in Qt Creator. Just for curiosity, why?
@MartinD
I don't know what the documentation/implementation ofsystem()
says under Windows. To run a.bat
file under Windows you do have to run it viacmd.exe
(or similar). Your second code obeys this. Your first one does not. Unlesssystem()
tries to runC:/a.bat
by prefacing it withcmd /c
for you, I think the command should fail. I don't think youra.bat
will get executed, so no output. Have you checked the return result from eachsystem()
call? -
Directly "calling" bat file using system() doesn't fail. System() returns return code from the bat file. The only problem seems to be the output redirection. Now I noticed in some cases I don't see the output in launched console nor in Application output of Qt Creator.
So, the question now is what is the proper way to call system (particulary to launch bat files) to get process's output in its console window. I don't want my Qt app to steal the output... Launching bat files through cmd /c seems to solve this problem, but can I be sure? :)
-
Directly "calling" bat file using system() doesn't fail. System() returns return code from the bat file. The only problem seems to be the output redirection. Now I noticed in some cases I don't see the output in launched console nor in Application output of Qt Creator.
So, the question now is what is the proper way to call system (particulary to launch bat files) to get process's output in its console window. I don't want my Qt app to steal the output... Launching bat files through cmd /c seems to solve this problem, but can I be sure? :)
-
Yes, launching .bat via cmd /c behaves as I need (its output goes to its console). I'm just asking why direct call of bat file redirects its output to my Qt app. Just in case you or somebody else know.
EDIT: Hmm, probably because individual commands of bat file are executed inside the process which called system().