【问题标题】:How to start an executable from console and read the output with Qt如何从控制台启动可执行文件并使用 Qt 读取输出
【发布时间】:2019-11-25 22:34:45
【问题描述】:

我想在 cmd 上从 Qt 启动一个可执行文件,然后读取它的输出。

我必须为此使用 WinAPI 吗?比如CreateProcess()?

我使用了 QProcess,它在 Windows 10 上运行良好,但它不适用于 Windows CE。这是适用于桌面的示例代码;

    QProcess p;
    p.start(path, arg);
    p.waitForFinished();
    std::string output = p.readAll();

【问题讨论】:

    标签: c++ qt winapi windows-ce qprocess


    【解决方案1】:

    试试这个类(省略了一些错误检查)

    #pragma once
    #include <windows.h>
    #include <thread>
    #include <iostream>
    #include <sstream>
    #define BUFSIZE 4096
    class m_Process
    {
    public:
        m_Process();
        ~m_Process();
        BOOL start(char* path, char* cmd);
        void waitForFinished();
        std::string readAll();
    
    private:
        HANDLE hProcess;
        HANDLE hRead;
        HANDLE hWrite;
        std::ostringstream stream;
        friend void ReadFromPipe(m_Process* Process);
    };
    
    void ReadFromPipe(m_Process* Process)
    {
        DWORD dwRead;
        CHAR chBuf[BUFSIZE];
        BOOL bSuccess = FALSE;
        Process->stream.clear();
        for (;;)
        {
            bSuccess = ReadFile(Process->hRead, chBuf, BUFSIZE-1, &dwRead, NULL);
            if (!bSuccess || dwRead == 0) break;
            chBuf[dwRead] = 0;
            Process->stream << chBuf;
        }
    }
    
    m_Process::m_Process()
    {
        hProcess = NULL;
        SECURITY_ATTRIBUTES saAttr;
        saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
        saAttr.bInheritHandle = TRUE;
        saAttr.lpSecurityDescriptor = NULL;
        CreatePipe(&hRead, &hWrite, &saAttr, 0);
        SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0);
    }
    
    
    m_Process::~m_Process()
    {
        if(hRead)
            CloseHandle(hRead);
        if (hWrite)
            CloseHandle(hWrite);
        CloseHandle(hProcess);
        stream.clear();
    }
    
    BOOL m_Process::start(char * path, char * cmd)
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        si.dwFlags = STARTF_USESTDHANDLES;
        si.wShowWindow = TRUE;
        si.hStdOutput = hWrite;
        si.hStdError = hWrite;
        BOOL ret = CreateProcess(path, cmd, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi);
        CloseHandle(hWrite);
        hWrite = NULL;
        std::thread t(&ReadFromPipe,this);
        t.join();
        if (ret)
            hProcess = pi.hProcess;
        return ret;
    }
    
    void m_Process::waitForFinished()
    {
        if (hProcess)
            WaitForSingleObject(hProcess, INFINITE);
    }
    
    std::string m_Process::readAll()
    {
        return stream.str();
    }
    

    用法:

    m_Process p;
    p.start(path, arg);
    p.waitForFinished();
    std::string output = p.readAll();
    

    【讨论】:

      【解决方案2】:

      QT 4.8 documentation 状态

      Note: On Windows CE and Symbian, reading and writing to a process is not supported.
      

      【讨论】:

      • 您知道是否可以使用 WinAPI 完成此操作吗?
      • QT 5.13 文档中也不存在此注释。
      • 不了解WinAPI,值得自己尝试。我确实在 Qt 文档中看到值得检查每个调用 API 的返回值,并且值得使用 waitForStarted()
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多