Query with QProcess - c++

I'm supposed to check whether the service is RUNNING. I've a problem with QProcess query execution, when it comes to executing the following query: SC QUERY "service name" | findstr RUNNING, though this works fine when executed directly in command line in Windows. The code snipet here as follows:
QProcess process;
process.setProcessChannelMode(QProcess::ForwardedChannels);
process.start("SC QUERY \"Service_name\" | findstr RUNNING", QIODevice::ReadWrite);
// Wait for it to start
if(!process.waitForStarted())
return 0;
QByteArray buffer;
while(process.waitForFinished())
buffer.append(process.readAll());
qDebug() << buffer.data();
Output is:
Can you help me?

It is because using these three lines will not give you the expected results:
QProcess process;
process.setProcessChannelMode(QProcess::ForwardedChannels);
process.start("SC QUERY \"Service_name\" | findstr RUNNING", QIODevice::ReadWrite);
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("SC QUERY \"Service_name\"");
process2.start("findstr RUNNING");
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;

Related

I need to check if the process is running using pid in QT

I want to check if the process is running with process id (pid).
My project is developed using QT and can be executed on both Windows and Linux.
So my code need to be able to run on both OS.
I have searched full through stackoverflow but I couldn't find expected result.
I already tried to execute cmd command -
tasklist, kill. But I still can't get result.
I think there is a way to use QProcess to get access of specified process with pid.
Here are my code I used.
#ifdef Q_OS_WIN32
QVariant variant(this->pid);
QString cmd = "tasklist /nh /fi \"pid eq " + variant.toString() + "\"";
QProcess process;
process.start(cmd);
process.waitForReadyRead();
QString result = process.readAll();
process.terminate();
if (result.indexOf(variant.toString()) >= 0)
{
return true;
}
else {
return false;
}
#else
QVariant variant(this->pid);
QString cmd = "kill -0 " + variant.toString();
QProcess process;
process.start(cmd);
process.waitForReadyRead();
QString result = process.readAll();
process.terminate();
if (result.indexOf("No") >= 0)
{
return false;
}
else {
return true;
}
#endif
I want to get help.

Executing the shell command in QProcess.Piping the input

I am trying to pipe the commands and execute it, but I am not able to figure how to pipe it.
I am trying to copy multiple files at once using the shell command
for %I in (source) do copy %I (destination)
QString files = "for %I in (source) do copy %I (destination)"
QProcess copy ;
copy.start(files);
I have to implement the piping to do that.
for Eg.
QProcess sh;
sh.start("sh", QStringList() << "-c" << "ifconfig | grep inet");
sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();
How can I implement piping for my copy process?
Try this example:
QProcess sh;
sh.start( "sh", { "-c", "ifconfig | grep inet" } );
if ( !sh.waitForFinished( -1 ) )
{
qDebug() << "Error:" << sh.readAllStandardError();
return -1;
}
const auto output = sh.readAllStandardOutput();
// ...
waitForFinished() should be called in blocking mode and it must be checked if it was successful or not.

Issue Commands to QProcess once its started

So in the code I have now below it loads up gphoto2 with no problem and adds the ---shell switch to it. How can I add one more line to issue a command to that shell the command i want to issue to the shell is "start-preview-stream" Thanks again!
QProcess gphoto2;
gphoto2.start("gphoto2", QStringList() << "--shell");
if (!gphoto2.waitForStarted()){
qDebug("gPhoto2 didn't start properly");
return 1;
}
qDebug("gPhoto2 Started Successfully");
Debug Shows
gPhoto2 Started Successfully
I have also tried the following with no luck
QProcess gphoto2;
gphoto2.start("gphoto2", QStringList() << "--shell" << "start-preview-stream");
if (!gphoto2.waitForStarted()){
qDebug("gPhoto2 didn't start properly");
return 1;
}
qDebug("gPhoto2 Started Successfully");
If you just need to send that string to the process's standard input stream, you need to write() to the QProcess:
QProcess gphoto2;
gphoto2.start("gphoto2", QStringList() << "--shell");
if (!gphoto2.waitForStarted()){
qDebug("gPhoto2 didn't start properly");
return 1;
}
qDebug("gPhoto2 Started Successfully");
gphoto2.write("start-preview-stream\n");
(obviously, you'll need to add some appropriate checking of the return value etc.)

Qt: Failed to find out application pid when run from binary using script

I have an aim to obtain the PID of application, when the latter runs.
I wrote a simple function calls pgrep command:
QString Scriptlauncher::getAppProcessId() {
QProcess p;
QString programme("pgrep");
QStringList args = QStringList() << "app_name";
p.start(programme, args);
p.waitForReadyRead();
QByteArray rdata = p.readAllStandardOutput();
qDebug() << "------------- script output rawdata is:" << rdata;
if (!rdata.isEmpty()) {
QString pid(rdata);
pid = pid.left(pid.length() -1); // cut '\n' symbol
qWarning() << "APPLICATION pid is" << pid;
return pid;
}
qWarning() << "failed to find out PID";
return ("-1");
}
When I run the program directly from Qt or using a simple script (call it execute.sh; it exports all needed shared libs and then run app binary, - to run the app from terminal), the codeblock from above returns correct value:
user#host:/standalone_package/ execute.sh
------------- script output rawdata is: "21094\n"
APPLICATION pid is "21094"
But when I run execute.sh from the valgrind heap profiler command, the function returns:
user#host:/standalone_package/ valgrind --tool=massif --trace-children=yes ./execute.sh
------------- script output rawdata is: ""
failed to find out PID
Thanks to Hayt for links! I've found a solution!
The second link offered requires the instance of QProcess object. I have no idea about how to get it.
But using first link, I get the code working both directly from app and under valgrind:
QString Scriptlauncher::getAppProcessId() {
long pid = (long)getpid();
qDebug ("------------- pid is %d", pid);
QString pidstr = QString::number(pid);
return pidstr;
}

Qt: How to get live output of a running QProcess

I have to get the output of a QProcess while it is running. Therefore I have written the following Code:
CommandExecutor_C::CommandExecutor_C():
mProcessStatus(AI_UNKNOWN),
mOnTdiActiveCallback(),
mTdiProcess(new QProcess)
{
connect(mTdiProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(CheckOutput()));
connect(mTdiProcess, SIGNAL(readyReadStandardError()), this, SLOT(CheckOutput()));
}
void CommandExecutor_C::ExecuteCommand(QString &aCommand)
{
mTdiProcess->start(aCommand, QProcess::Unbuffered | QProcess::ReadWrite);
LOGINFO(FB_TDI,"Launch command: " + aCommand.toStdString());
}
void CommandExecutor_C::CheckOutput()
{
QString StdOut = QString(mTdiProcess->readAllStandardOutput());
QString StdErr = QString(mTdiProcess->readAllStandardError());
mProcessStatus = CheckTdiAutomationInterface(StdOut.toStdString(), StdErr.toStdString());
if(mProcessStatus != AI_UNKNOWN)
{
OnTdiActive(mProcessStatus);
}
}
This works fine if QProcess gets finished but in my case the Process starts an automation interface which should run in background permanently. Therefore I have used "readyReadStandardOutput" and connect it to the slot CheckOutput(). CheckOutput() is getting called just if the process has been finished. Otherwise I am waiting endless.
I have googled a lot about the problem but nothing worked. I am very sure that the output is getting buffered and does just return if the Process has finished. Therefore I have started the Process in Unbuffered-Mode. I have also tried to forward the channels of mTdiProcess. Here the Code:
void CommandExecutor_C::ExecuteCommand(QString &aCommand)
{
mTdiProcess->setProcessChannelMode(QProcess::ForwardedChannels);
mTdiProcess->start(aCommand, QProcess::Unbuffered | QProcess::ReadWrite);
LOGINFO(FB_TDI,"Launch command: " + aCommand.toStdString());
}
But nothing worked. I hope you can help me.
I am using Qt 5.4.2 if that's important.
I usually check the output in regular intervals like this:
bool returnBool = false;
while (returnBool == false)
{
/*! Wait one second if the process finishes. Then read all output to
* stdout and stderr and redo. */
returnBool = process.waitForFinished(1000);
QString outputStdOut = process.readAllStandardOutput();
QString outputStdErr = process.readAllStandardError();
}