Problem with process!
-
I want to close computer when i close the mainwindow,but i failed ,below is my code:
void MainWindow::closeEvent(QCloseEvent *event) { // writefile(); p=new QProcess; connect(p,SIGNAL(errorOccurred(QProcess::ProcessError)),this,SLOT(showerr(QProcess::ProcessError))); connect(p,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(showexit(int,QProcess::ExitStatus))); connect(p, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadyReadStandardOutput())); connect(p,SIGNAL(started()),this,SLOT(onStarted())); begin(); // qDebug() <<p->state(); if (p->waitForStarted()) { // qDebug() <<p->state(); p->waitForFinished(); qDebug() <<p->readAllStandardError(); } else qDebug() << "Failed to start"; event->accept(); } void MainWindow::begin() { qDebug()<<"current applicationDirPath: "<<QCoreApplication::applicationDirPath(); p->start("cmd.exe", QStringList() <<QCoreApplication::applicationDirPath()+"/shutdown.bat"); } void MainWindow::onStarted() { qDebug()<<"started!"; } void MainWindow::onReadyReadStandardOutput() { // qDebug() << p->readAllStandardOutput(); } void MainWindow::showerr(QProcess::ProcessError error) { qDebug()<<"error"<<error; } void MainWindow::showexit(int exitCode, QProcess::ExitStatus) { qDebug()<<"exitCode"<<exitCode; emit completed(); }
this is my shutdown.bat:
shutdown -s -t 60
below is my debug information:
current applicationDirPath: "D:/myQt/prcsnew/release"
started!
exitCode 1
"'elease' \xB2\xBB\xCA\xC7\xC4\xDA\xB2\xBF\xBB\xF2\xCD\xE2\xB2\xBF\xC3\xFC\xC1\xEE\xA3\xAC\xD2\xB2\xB2\xBB\xCA\xC7\xBF\xC9\xD4\xCB\xD0\xD0\xB5\xC4\xB3\xCC\xD0\xF2\r\n\xBB\xF2\xC5\xFA\xB4\xA6\xC0\xED\xCE\xC4\xBC\xFE\xA1\xA3\r\n"
I want to know why the process exit 1. -
@JNBarchan Thanks a lot!If I right-click on the .bat file in Explorer and select Run as administrator,it does work!I can sure that .bat only contains a single line of shutdown -s -t 60.
Thank you again.I fix the problem as you say.I change my .bat file
to shutdown.exe -s -t 60,it does work! I find that the name of file doesn't influence the result.I want to know why the code cmd.exe shutdown -s -t 60 doesn't work and how do you find it. -
Hi
Have you tried system command? -
p->start("cmd.exe", QStringList() <<QCoreApplication::applicationDirPath()+"/shutdown.bat");
That would run
cmd.exe .../shutdown.bat
. But that's not the right command: you probably want eithercmd.exe /c .../shutdown.bat
or just plain.../shutdown.bat
. (Unless you really intendcmd.exe shutdown.bat
, which is probably the root of your current error, in which case as @VRonin says you'll need anexit
[or maybe anexit /b %errorlevel%
] at the end of yourshutdown.bat
.)Furthermore, you should be careful here about using
\
rather than/
. In other places Qt translates/
to\
where it knows a OS path is involved. However, it cannot know that in command-line arguments toQProcess
. I think you should use either one of the following:p->start("cmd.exe", QStringList() <<"/c"<<QDir::toNativeSeparators(QCoreApplication::applicationDirPath()+"/shutdown.bat)"); p->start(QCoreApplication::applicationDirPath()+"/shutdown.bat");
In my code I run
.bat
files just as per the second case, without bothering withcmd
, andQProcess::start()
gets it right.If you have no interest in the output from the process, there's no need to use
QProcess
if Qt/C++ provides asystem(<string>)
command (I don't know if it does, my Python provides a native one).If you do want to view the output, it arrives from
p->readAllStandardError()
as aQByteArray
(i.e. binary). To view it as text you need to convert it toQString()
. Something like (I'm not C++)QString::QString(const QByteArray &ba)
. (UnlessqDebug()
does that implicitly for you.)Finally:
I want to know why the process exit 1.
Well, I don't see where the exit codes of
shutdown
are stated, so I don't know what exit code number you expect. You'll need to find out what it exits with under what circumstances if you want to act on the exit code. -
@JNBarchan At first,thank you.
I tried to fix this problem in this code before:
p->start("cmd.exe", QStringList()<<"/c"<<QCoreApplication::applicationDirPath()+"/shutdown.bat");
but it didn't work,it froze my windows application.
Just now,i try the methods that you give me.
①p->start(QCoreApplication::applicationDirPath()+"/shutdown.bat");
②p->start("cmd.exe", QStringList() <<"/c"<<QDir::toNativeSeparators(QCoreApplication::applicationDirPath()+"/shutdown.bat"));
both of ① and ② freeze my windows application.
Qt/C++ provides a system(<string>) command.I try to shutdown use this code:
system("shutdown -s -t 60");
but it doesn,t work or freeze my windows application.I try this code in another simple application,it does work!I guess that which my partial code blocks the GUI thread.
I run my application in original code:
p->start("cmd.exe", QStringList()<<QCoreApplication::applicationDirPath()+"/shutdown.bat");
i convert p->readAllStandardError() to QString(),below is the information:
"'elease' ??????????????\uE8EC?????????е????\r\n?????????????\r\n"
but i don't know what it means. -
@Tirupathi-Korla At first,thank you,that you mean run the shutdown.bat in cmd.exe like this:
it does work. -
i convert p->readAllStandardError() to QString(),below is the information:
"'elease' ??????????????\uE8EC?????????е????\r\n?????????????\r\n"
but i don't know what it means.It means your output is not in UTF-8, hence the
?
characters. Which is hardly surprising now that your screenshot shows you are in an Asian language... So you need to use the rightQByteArray()
toQString()
converter. And/or, just possibly, wherever you are viewing this does not display Asian characters (e.g. are you in Qt Creator debug window? does that output Asian chars properly?) -
@lusijie
Try moving the code to another block. There is a signal qApp aboutToQuit() which will be called before quitting the application. Handle this signal and write the system("D:/myQt/prcsnew/release/shutdown.bat") in that slot.QObject :: connect( qApp, SIGNAL(aboutToQuit()),&mainwindow,SLOT(shutdown()));
void shutdown (){system("shutdown.bat")}
-
@lusijie
You are saying that:-
You have a
.bat
which only contains a single line ofshutdown -s -t 60
, nothing else, exactly that, let's be 100% clear, right? -
If you run it from that Command Prompt it works?
-
If you double-click the
.bat
from Windows Explorer, however, it does not behave the same?
Strange. Is your Command Prompt elevated? What if you right-click on the
.bat
file in Explorer and selectRun as administrator
instead?BTW, this "freezing": although it shouldn't work like that, it sounds a bit like the
shutdown.bat
'sshutdown
statement is invokingshutdown.bat
again, instead of the Windows commandshutdown.exe
. Try either renaming yourshutdown.bat
tomyshutdown.bat
, or edit itsshutdown -s -t 60
line to readshutdown.exe -s -t 60
. (I'm 99% sure this is your "freezing" problem.) -
-
@JNBarchan Thanks a lot!If I right-click on the .bat file in Explorer and select Run as administrator,it does work!I can sure that .bat only contains a single line of shutdown -s -t 60.
Thank you again.I fix the problem as you say.I change my .bat file
to shutdown.exe -s -t 60,it does work! I find that the name of file doesn't influence the result.I want to know why the code cmd.exe shutdown -s -t 60 doesn't work and how do you find it. -
@Tirupathi-Korla Thank you a lot.As you say ,I change code like this:
QObject :: connect( qApp, SIGNAL(aboutToQuit()),&mainwindow,SLOT(shutdown())); void shutdown (){system("shutdown -s -t 60")}
It works!Thank you!
-
So, in your environment, either you have to run
shutdown
as an Administrator, or there is some confusion over your use of the wordshutdown
when you don't specify eithershutdown.bat
orshutdown.exe
, to do with which found on thePATH
, at a guess. Make all your calls have either the explicit.bat
or.exe
as appropriate.If when you do run
shutdown.exe
successfully there is some kind of dialog thrown up asking for confirmation, maybe it's possible that it doesn't work right when run from inside an app with redirection as opposed to from a terminal/Explorer, I don't know. I doubt anyone else here will either. You'll need to do your own investigations. -
@Tirupathi-Korla It need to change like this:
void shutdown (){system("shutdown.exe -s -t 60")}
The application run normally like this.
-
void shutdown (){system("shutdown.exe -s -t 60")}
That's fine if you don't need to use your
shutdown.bat
to do something else/additional. I presumed that since you had chosen to write a.bat
file instead, you had a reason for that.... But if you're happy I'm happy :) -
@JNBarchan Thank you very much! I am a chinese.If you take a holiday in China Wuhan in the future,I hope to take you see the Yellow Crane Tower and The Yangtze River.I hope you have a chance to visit in China.Best wishes to you!This is my email:863872260@qq.com.