Qt can't kill process - qt

In my Qt app i run a process under a push-button click.The process run gnome-terminal.My problem is when i kill qt process that run but push-button click from another button by pid,its shows error."kill: sending signal to 19771 failed: No such process" but still terminal running.And if i kill my app,but still terminal running.
QProcess *p = new QProcess(this);
if (p)
{
p->setEnvironment( QProcess::systemEnvironment() );
p->setProcessChannelMode( QProcess::MergedChannels );
QString program = "gnome-terminal";
QStringList arguments;
arguments << "-x" << "bash" << "--rcfile" << "./auto.sh";
p->start(program, arguments);
pid= p->pid();
}
Button2 cod is:
QProcess::startDetached("kill -9 "+QString(pid));
how can kill process and also terminal by click another push-button?

Related

arp command with grep argument in QProcess [duplicate]

I'm using Qt and bash over it, need to execute something like:
bash: cat file | grep string
in Qt:
QString cmd = "cat file | grep string";
QProcess *process = new QProcess;
process->start(cmd);
process->waitForBytesWritten();
process->waitForFinished();
qDebug() << process->readAll();
The problem is in pipe ("|"), and process returs nothing. If there is no ("|"), like
"cat file"
everything is ok.
I tried smth. like
"cat file \\| grep string",
"cat file \| grep string"
but result is the same. If I copy the command and run it in bash everything is ok.
QString::toAscii().data()
and other transforms also have bad result.
The problem is you cannot run a system command with QProcess, but only a single process. So the workaround will be to pass your command as an argument to bash:
process.start("bash", QStringList() << "-c" << "cat file | grep string");
The quick and dirty hack would be this:
QString cmd = "/bin/sh -c \"cat file | grep string\"";
You could also avoid the escaping in there with C++11's R"", but the point is that do not use bash in there because that will make it only work with bash. It will not work on embedded with busybox without bash, just ash, or any other common desktop shell.
/bin/sh is usually a symlink to the shell interpreter used, so that will eventually work.
BUT!
I think you are thinking a bit too low-level when using a high-level C++/OOP framework such as Qt. I would not recommend to invoke the commands in the low-level way when you run it from bash. There is some dedicated high-level convenience API for this use case.
Based on the official documentation, QProcess is supposed to work for pipe'd commands:
void QProcess::setStandardOutputProcess(QProcess * destination)
Pipes the standard output stream of this process to the destination process' standard input.
In other words, the command1 | command2 shell command command can be achieved in the following way:
QProcess process1;
QProcess process2;
process1.setStandardOutputProcess(&process2);
process1.start("cat file");
process2.start("grep string");
process2.setProcessChannelMode(QProcess::ForwardedChannels);
// Wait for it to start
if(!process1.waitForStarted())
return 0;
bool retval = false;
QByteArray buffer;
while ((retval = process2.waitForFinished()));
buffer.append(process2.readAll());
if (!retval) {
qDebug() << "Process 2 error:" << process2.errorString();
return 1;
}
qDebug() << "Buffer data" << buffer;
This is not the main point, but a useful suggestion: do not use QString::toAscii(). That API has been deprecated in Qt 5.
The problem is that when you call process->start(cmd), the commands following the the call to cat are all interpreted as arguments to cat, so the pipe is not doing what you're expecting. If you start with a call to bash with a parameter of a string, you should get what you want: -
QString cmd = "bash -c \"cat file | grep string\"";
Alternatively, you could just call "cat file" and do the search on the returned QString when you read the output from the QProcess
how about this :
QString program = "program";
QStringList arguments;
download = new QProcess(this);
download->start(program, arguments);
If Google brought you here and you are using PyQt5 or PySide2
process1 = QProcess()
process2 = QProcess()
process1.setStandardOutputProcess(process2)
process1.start(cat, [file])
process2.start(grep, [string])

How to check for 30sec if file in folder exist?

I want to check if in a Folder are a json-File called "test.json" for 30 sec.
I have in Qt a Button, which execute a python skript --> this skript create the test.json.
When I clicked the Button now i get the file successfully.
How can I checked if a file is in a Folder for 30 sec?
Any Idea?
you can use a QTimer
with singleshot = true and interval to 30 000
t = new QTimer(this);
t->setSingleShot(true);
t->setInterval(30 * 1000);
connect(t, &QTimer::timeout, [](){
qDebug() << "is the file already there: " << QFile::exists("/home/pw/file.txt");});
t->start();

Qt copy file with sudo right

I handle the normal copying of files with Qt like this:
QFile::copy("/path/file", "/path/copy-of-file");
How can I now copy a file for which Sudo rights are required.
You can use QProcess and pkexec to execute a command as another user
pkexec allows an authorized user to execute PROGRAM as another user. If username is not specified, then the program will be executed as the administrative super user, root.
https://www.freedesktop.org/software/polkit/docs/0.105/pkexec.1.html
QProcess *proc = new QProcess(this);
proc->waitForFinished();
QString cmd = "pkexec /bin/cp /path/file /path/copy-of-file";
proc->start(cmd);
if(!proc->waitForStarted()) //default wait time 30 sec
{
qDebug() << "Cannot execute:" << cmd;
}
proc->waitForFinished();
proc->setProcessChannelMode(QProcess::MergedChannels);
if(proc->exitStatus() == QProcess::NormalExit
&& proc->exitCode() == QProcess::NormalExit){
qDebug() << "Success";
} else {
qDebug() << "Cannot copy file" << cmd;
}
run shell command, like this
sudo cp /path/file /path/copy-of-file
Set a password if necessary.:
$echo <password> | sudo -S <command>

Qt - Wait for Qprocess to finish

I'm using CMD by QProcess but I have a problem.
My code:
QProcess process;
process.start("cmd.exe");
process.write ("del f:\\b.txt\n\r");
process.waitForFinished();
process.close();
When I don't pass an argument for waitForFinished() it waits for 30 secs. I want to terminate QProcess after CMD command is executed! Not much and not less!
You need to terminate the cmd.exe by sending exit command, otherwise it will wait for commands
Here is my suggestion:
QProcess process;
process.start("cmd.exe");
process.write ("del f:\\b.txt\n\r");
process.write ("exit\n\r");
process.waitForFinished();
process.close();
The process you're starting is cmd.exe which, by itself will, not terminate. If you call cmd with arguments, you should achieve what you want: -
QProcess process;
process.start("cmd.exe \"del f:\\b.txt"\"");
process.waitForFinished();
process.close();
Note that the arguments are escaped in quotes.
Alternatively, you could call the del process, without cmd: -
QProcess process;
process.start("del \"f:\\b.txt"\"");
process.waitForFinished();
process.close();
Finally, if you just want to delete a file, you could use the QFile::remove function.
QFile file("f:\\b.txt");
if(file.remove())
qDebug() << "File removed successfully";

QProcess and shell : Destroyed while process is still running

I want to launch a shell script with Qt.
QProcess process;
process.start(commandLine, QStringList() << confFile);
process.waitForFinished();
if(process.exitCode()!=0)
{
qDebug () << " Error " << process.exitCode() << process.readAllStrandardError();
}
else
{
qDebug () << " Ok " << process.readAllStrandardOutput() << process.readAllStrandardError();
}
The result is :
Ok : Result.... " "" QProcess : Destroyed while process is still
running.
This message does not appear every time.
What is the problem?
process.waitForFinished(); is hitting the default 30 seconds timeout. Use process.waitForFinished(-1); instead. This will make sure you wait for however long it takes for the process to finish, without any timeout.
Note you create QProcess into the local scope. This means that the object will be deleted when you exit the scope. In the destructor QProcess process terminates. The message "Destroyed" while "the process is still running" when the process terminates in the destructor.
For solving this problem, you should call QProcess destructor when process is already terminated.
If will be QProcess::waitForFinished(-1) into your example, it will occur, but this will block you application.

Resources