[SOLVED] Problem with cmd process
-
First of all, sorry for my bad english.
I have a .exe called "rtosim_ik_from_file" which want 3 arguments (model, tracing and taskset) and i run this from the cmd.exe with this command "rtosim_ik_from_file --model OpenSim_Example_3/arm8mark32scaled.osim --trc OpenSim_Example_3/irio/os_irio_11042019.trc --task-set OpenSim_Example_3/irio/ik_taskset.xml -v". Then, it shows a 3d simulation of inverse kinematics.Now, i'm building a script which shows a windows with 4 lines: general directory, model's directory, tracing's directory and taskset's directory. By clicking a button, the script has to run the .exe:
void MainWindow::on_submitpath_clicked()
{
QString directory = ui->linepath->text() ;
QString model = ui->linemodel->text();
QString tracing = ui->linetracing->text();
QString taskset = ui->linetaskset->text();
QString sndstring="rtosim_ik_from_file --model ";
sndstring.append(model);
sndstring.append(" --trc ");
sndstring.append(tracing);
sndstring.append(" --task-set ");
sndstring.append(taskset);
sndstring.append(" -v");
QStringList params = QStringList() << "/k"<< sndstring;
qDebug()<<params;
QString command = "C:/Windows/System32/cmd.exe";
QProcess process;
process.setWorkingDirectory(directory);
process.start(command, params);
process.waitForFinished(-1);
}But the window freezes and it doesn't work. Any suggestions?
Thank you in advance. -
Right.
Usually, i run cmd.exe, i set another directory ("cd C:\OpenSimLib\rtosim_install\bin") and i write that command "rtosim_ik_from_file --model OpenSim_Example_3/arm8mark32scaled.osim --trc OpenSim_Example_3/irio/os_irio_11042019.trc --task-set OpenSim_Example_3/irio/ik_taskset.xml -v". And it works.Now i want to do this thing with a qt process. How?
-
@Cimmy On Windows .cmd files are run by the system using command line. I'd suggest creating temporary file (.bat, .cmd, whatever works for you really) and starting that directly.
On a separate note: have you tried to run that .exe directly? It's been a while since I used command line on Windows, but don't it recognize the .exe format and runs it in cmd as it is? -
@Cimmy said in Problem with cmd process:
process.waitForFinished(-1);
Why do you wait for it to finish? This is why your app freezes.
Simply add QProcess member to your class and use it to execute the process without waiting. -
First try: use cmd, use rtosim_ik_from_file.exe as parameters. Message "destroyed while process is still running" and nothing happen
Second try: run directly rtosim_ik_from_file.exe with parameters (model, trc ect) but nothing happen. NO "destroyed while [...]" message.
Any other suggestions?
Don't know how to create a batch file. I will try... -
Hi
-Don't know how to create a batch file. I will try...
Its just a text file and then you rename it to filename.bat and then its a bat file.Regarding the code.
You are using the parameters in an odd way since you add to a string and then add to that string to the param list.
Normally you would do likeQString program = "./path/to/Qt/examples/widgets/analogclock"; QStringList arguments; arguments << "-style" << "fusion";
so each param and value are differnt indexs in the list.
In your sample, it seems to be one big string -
void MainWindow::on_submitpath_clicked()
{
QString directory = ui->linepath->text() ;
QString model = ui->linemodel->text();
QString tracing = ui->linetracing->text();
QString taskset = ui->linetaskset->text();
QString sndstring="rtosim_ik_from_file --model ";
sndstring.append(model);
sndstring.append(" --trc ");
sndstring.append(tracing);
sndstring.append(" --task-set ");
sndstring.append(taskset);
sndstring.append(" -v");
QString filenew = directory;
filenew.append("/Filenew.bat");
QFile file(filenew);
if ( file.open(QIODevice::ReadWrite) )
{
QTextStream stream(&file);
stream << sndstring <<endl;
}
QStringList arguments;
arguments << "/c" << "Filenew.bat";
QProcess *exec = new QProcess();
exec->setWorkingDirectory(directory);
exec->start("cmd.exe", arguments);
}SOLVED!! Thanks to all!!
-
@Cimmy said in Problem with cmd process:
SOLVED!! Thanks to all!!
Not really - you leak memory (exec is never deleted). As I wrote already add exec to your class as member, or pointer to QProcess to be able to delete it when you're done.
-
@Cimmy said in Problem with cmd process:
right?
wrong. Then you will again have same issue: QProcess going out of scope and deleted.
I write it now for the third time: "I wrote before: "Simply add QProcess member to your class"." (as @JonB suggested also). -
@Cimmy
If you are interested (as I am!) as to why you have things this way. Here is what @jsulm has been telling you:The issue is the
QProcess
destructor:Destructs the QProcess object, i.e., killing the process.
Note that this function will not return until the process is terminated.
So if a
QProcess
gets destructed it will kill the process if it's still running. The problem is your code is only going tostart()
the sub-process running. It can/will continue running for a while. If your code were waiting for it to finish (e.g.QProcess::execute()
orQProcess::waitForFinished()
), there wouldn't be a problem, after that you could allow theQProcess
to get destroyed.If your
QProcess
is a local variable on the stack in a function like you propose, as soon as the function exits (variable goes "out of scope") the destructor would get called. So you can either:-
Move
QProcess exec
variable to a member of your class, not destructed till class instance destructed; or -
Use
QProcess *exec = new QProcess()
, allocated on the heap. Not destructed tilldelete exec
. But then you need somewhere to save that pointer so that you can later delete it, no use as a local variable, so equally needs moving to class scope.
@jsulm
I have musing over this. If you want simple to start a sub-process and "forget" about it (yes, I know about "zombie" processes), this~QProcess()
behaviour is a bit problematic. I don't thinkstartDetached()
in itself would help here, it doesn't say that the destructor will not kill the process in this case:If the calling process exits, the detached process will continue to run unaffected.
Yes, but if
~QProcess()
called on exit it will still kill it, unless the docs are a bit vague here. Perhaps actually it does not? I wonder ifQProcess()
could do with asetNoKillOrWaitOnDestruct()
flag, ifstartDetached()
does not do that?So.... I guess in this case the only safe thing to do would be to go
new QProcess
and deliberately notdelete
on exit? C++ doesn't go through everything you'venew
ed anddelete
prior to exit, does it?! So accept that your program "leaks" prior to exit (e.g. a memory checker) and put up with it? -
-
@JonB "If the calling process exits, the detached process will continue to run unaffected." - https://doc.qt.io/qt-5/qprocess.html#startDetached
So, the QProcess destructor will not terminate the detached process as it is detached.
"this ~QProcess() behaviour is a bit problematic" - in what way? If you use startDetached() then the destructor doesn't matter. If you use exec() then I don't see why ~QProcess() terminating process is a problem? At the end it's your job as developer to select the right approach. -
"If the calling process exits, the detached process will continue to run unaffected."
That describes what happens if the calling process exits. It does not state it countermands what I quoted from
~QProcess()
, which states it kills & waits. The question (my question) is what happens, which "wins", if you do not usenew
but have a "global" scopedQProcess globProc
variable (not*globProc
), initiateglocProc.startDetached()
, and then exit your program. To me the docs are unclear....Can I try this myself? No, because I'm stinky Python, and there are no variables, only heap pointers....