QProcess问题,流程输出

use*_*297 5 qt qt4

我想弄清楚 QProcess 的使用。我看着Qt doc没有运气。
http://doc.qt.io/qt-4.8/qprocess.html

问题示例。

示例 1:下面的代码有效。

    #include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QProcess>    

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream qout(stdout);    

    QProcess cmd;
    
    cmd.start("cmd");
    if (!cmd.waitForStarted())  {
        return false;
    }

    cmd.waitForReadyRead();
    QByteArray result = cmd.readAll();
    //qout << result.data() << endl;   //console junk captured, doesn't show. 

    //My test command
    cmd.write("echo hello");
    cmd.write("\n");

    //Capture my result
    cmd.waitForReadyRead();
    //This is my command shown by cmd, I don't show it, capture & discard it.
    result = cmd.readLine();
    //Read result of my command ("hello") and the rest of output like cur dir.   
    result = cmd.readAll();    
    qout << result.data();

    qout << "\n\n---End, bye----" << endl;
    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

上面代码的输出

你好

F:\Dev_Qt\expControllingExtConsoleApps-build-desktop>

---End, bye----
Run Code Online (Sandbox Code Playgroud)

问题是,如果我尝试通过 Qprocess 和 cmd 控制台以这种方式使用 ipconfig 或 7zip,我将看不到 ipconfig 或 7zip 的任何输出。我什至不知道有没有做任何事情,如果做了什么,那为什么我看不到输出?下面的代码说明了。

示例 2: 不起作用。不能使用ipconfig。

#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QString>
#include <QProcess>    

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QTextStream qout(stdout);
   
   QProcess cmd2;
    cmd2.setWorkingDirectory("C:/Program Files/7-Zip");   //not needed in this example.
    cmd2.setReadChannel(QProcess::StandardOutput);
    cmd2.setProcessChannelMode(QProcess::MergedChannels);

    cmd2.start("cmd");
    if (!cmd2.waitForStarted())
    {
        qout << "Error: Could not start!" << endl;
        return false;
    }

    cmd2.waitForReadyRead();
    QByteArray result = cmd2.readAll();
    qout << result.data() << endl;      //Console version info, etc.

    //My command
    cmd2.write("ipconfig");
    cmd2.write("\n");

    //Capture output of ipconfig command
    //DOES NOT WORK!!
    cmd2.waitForReadyRead();
    while (! cmd2.atEnd())
    {
        result = cmd2.readLine();
        qout << result;
        result.clear();
    }
    qout << endl;

    qout << "\n\n---end----" << endl;
    return a.exec();

}
Run Code Online (Sandbox Code Playgroud)

输出如下,缺少 ipconfig 连接信息结果。根本没有捕获 ipconfig 的输出。

Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp。

C:\Program Files\7-Zip> ipconfig

- -结尾 - -

应该更像这样(使用 ipconfig 结果)。

Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp。

C:\Documents and Settings\noname>ipconfig

Windows IP 配置

以太网适配器本地连接:

    Connection-specific DNS Suffix  . :
    IP Address. . . . . . . . . . . . : 192.172.148.135
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 192.172.148.177
Run Code Online (Sandbox Code Playgroud)

C:\Documents and Settings\noname>

显然,输出应该比上面的略有不同,但是应该已经捕获了作为“ipconfig”输出的连接信息。同样,如果我尝试通过 cmd 控制台使用 7zip ......我看不到/捕获 7zip 的任何输出。所以我的问题是如何通过 QProcess 和 cmd 控制台使用 ipconfig 和 7zip 等命令行应用程序并查看这些应用程序的输出结果?

示例 3: 7zip 不起作用

#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QProcess>    

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QTextStream qout(stdout);

    QProcess cmd2;
    cmd2.setWorkingDirectory("C:/Program Files/7-Zip");
    cmd2.setReadChannel(QProcess::StandardOutput);
    cmd2.setProcessChannelMode(QProcess::MergedChannels);

    cmd2.start("cmd");
    if (!cmd2.waitForStarted()) {
        return false;
    }

    //My Command
    cmd2.write("7z.exe");
    cmd2.write("\n");

    //Capture output of ipconfig command
    cmd2.waitForReadyRead();
    QByteArray result;

    while (! cmd2.atEnd()) {
        result = cmd2.readLine();
        qout << result;
        result.clear();
    }
    qout << endl;

    qout << "\n\n---end----" << endl;
    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

下面输出。不显示 7zip 中的任何内容。

Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp。

C:\Program Files\7-Zip>7z.exe

- -结尾 - -

预计输出将沿着......

Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp。

C:\Documents and Settings\noname>cd C:\Program Files\7-Zip

C:\Program Files\7-Zip>7z.exe

7-Zip 9.15 beta 版权所有 (c) 1999-2010 Igor Pavlov 2010-06-20

用法:7z [...] <archive_name> [<file_names>...] [<@listfiles...>]

a:将文件添加到存档
b:基准 d:从存档中删除文件 e:从存档中提取文件(不使用目录名称) l:列出存档的内容
t:测试存档的完整性 u:更新文件到存档 x:提取文件完整路径
-ai[r[-|0]]{@listfile|!wildcard}:包括档案
-ax[r[-|0]]{@listfile|!wildcard}:排除档案 -bd:禁用百分比指示器
-i [r[-|0]]{@listfile|!wildcard}:包含文件名 -m{Parameters}:设置压缩方法
-o{Directory}:设置输出目录 -p{Password}:设置密码 -r[-|0]:递归子目录 -scs{UTF-8 | 赢| DOS}:为列表文件设置字符集 -sfx[{name}]:创建 SFX 存档 -si[{name}]:从标准输入读取数据 -slt:显示 l(列表)命令的技术信息 -so:将数据写入标准输出-ssc[-]:设置区分大小写模式 -ssw:压缩共享文件
-t{Type}:设置存档类型 -u[-][p#][q#][r#][x#][y#] [z#][!newArchiveName]:更新选项 -v{Size}[b|k|m|g]:创建卷 -w[{path}]:分配工作目录。空路径表示临时目录
-x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames -y: 假设所有查询都是 Yes

C:\Program Files\7-Zip>

Dar*_*sig 4

e我看到一个大问题。在 Windows 下,您可以按 Enter 键发出命令。写作

cmd.write("command");
cmd.write("\n");
Run Code Online (Sandbox Code Playgroud)


这还不够,你还得写

cmd.write("command");
cmd.write("\n\r");
Run Code Online (Sandbox Code Playgroud)

注意结尾的 \r。试试这个,它应该工作得更好,我所说的更好是指 7zip。我不知道你能否让 ipconfig 正常工作。

祝你好运并致以最诚挚的问候
D

编辑这是一个可行的解决方案:


#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QString>
#include <QtCore/QTextStream>

// Not clean, but fast
QProcess *g_process = NULL;

// Needed as a signal catcher
class ProcOut : public QObject
{
  Q_OBJECT
public:
  ProcOut (QObject *parent = NULL);
  virtual ~ProcOut() {};

public slots:
  void readyRead();
  void finished();
};

ProcOut::ProcOut (QObject *parent /* = NULL */):
QObject(parent)
{}

void
ProcOut::readyRead()
{
  if (!g_process)
    return;

  QTextStream out(stdout);
  out << g_process->readAllStandardOutput() << endl;
}

void
ProcOut::finished()
{
  QCoreApplication::exit (0);
}

int main (int argc, char **argv)
{
  QCoreApplication *app = new QCoreApplication (argc, argv);

  ProcOut *procOut = new ProcOut();
  g_process        = new QProcess();

  QObject::connect (g_process, SIGNAL(readyReadStandardOutput()),
    procOut, SLOT(readyRead()));
  QObject::connect (g_process, SIGNAL(finished (int, QProcess::ExitStatus)),
    procOut, SLOT(finished()));

  g_process->start (QLatin1String ("cmd"));
  g_process->waitForStarted();

  g_process->write ("ipconfig\n\r");

  // Or cmd won't quit
  g_process->write ("exit\n\r");

  int result = app->exec();

  // Allright, process finished.
  delete procOut;
  procOut = NULL;

  delete g_process;
  g_process = NULL;

  delete app;
  app = NULL;

  // Lets us see the results
  system ("pause");

  return result;
}

#include "main.moc"
Run Code Online (Sandbox Code Playgroud)

希望有帮助。它每次都在我的机器上工作。