【问题标题】:capture working directory of external process [Qt/WinAPI]捕获外部进程的工作目录 [Qt/WinAPI]
【发布时间】:2015-07-23 23:50:07
【问题描述】:

如何从 Qt/Windows 代码中等待然后捕获外部进程的工作目录(可能尚未运行)

【问题讨论】:

标签: c++ qt winapi


【解决方案1】:

我以前做过类似的事情,这里是相关部分。只是为了展示它是如何工作的。

WaitForProcess 类将每刷新毫秒搜索 exe,作为参数传递给start

如果你使用这个sn-p,并启动notepad.exe,它将在控制台中显示它的路径。一旦你有了这些信息,你就可以发出一个信号或任何你喜欢的东西。

main.cpp

#include <QApplication>
#include "waitforprocess.h"


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    WaitForProcess wfp;
    wfp.start("notepad.exe", 1000);


    return a.exec();
}

waitforprocess.h

#ifndef WAITFORPROCESS_H
#define WAITFORPROCESS_H

#include <QObject>
#include <QString>
#include <QTimer>

class WaitForProcess : public QObject
{
    Q_OBJECT
public:
    explicit WaitForProcess(QObject *parent = 0);
    ~WaitForProcess();

signals:

public slots:

    void start(const QString& processName, int refresh);

private slots:

    void onTimeout();

private:

    QString _processName;
    QTimer* _timer;

    bool FindWin32Process();
};

#endif // WAITFORPROCESS_H

waitforprocess.cpp

#include "waitforprocess.h"

#include <Windows.h>
#include <TlHelp32.h>
#include <QFileInfo>
#include <QDebug>

WaitForProcess::WaitForProcess(QObject *parent) : QObject(parent)
{
    _timer = new QTimer(this);
    connect(_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}

WaitForProcess::~WaitForProcess()
{

}

void WaitForProcess::onTimeout()
{
    if(FindWin32Process()) {
        _timer->stop();
    }
}

void WaitForProcess::start(const QString& processName, int refresh)
{
    _processName = processName;
    _timer->start(refresh);
}

std::string utf8_encode(const std::wstring &wstr)
{
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo( size_needed, 0 );
    WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}

bool WaitForProcess::FindWin32Process()
{
    QString otherProcess;

    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        return false;
    }

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (!Process32First(hProcessSnap, &pe32))
    {
        // clean the snapshot object
        CloseHandle(hProcessSnap);
        return false;
    }

    // loop through all running processes looking for process
    do
    {
        otherProcess = QString(utf8_encode(std::wstring(pe32.szExeFile)).c_str());
        if (_processName.compare(otherProcess)==0)
        {
            // Find Path
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);

            wchar_t lpExeName[1024];
            DWORD lpdwSize = 1024;

            if(hProcess != NULL)
            {
                QueryFullProcessImageName(hProcess, 0, lpExeName, &lpdwSize);
                QString fullPath = QString(utf8_encode(std::wstring(lpExeName)).c_str());

                // HERE I'VE FOUND THE PATH OF THE EXE

                QFileInfo info(fullPath);
                QString path = info.path();
                QString name = info.fileName();

                qDebug() << "Found: " << name;
                qDebug() << "PATH: " << path;
            }

            // clean the snapshot object
            CloseHandle(hProcess);
            CloseHandle(hProcessSnap);

            return true;
        }
    } while(Process32Next(hProcessSnap, &pe32));

    // clean the snapshot object
    CloseHandle(hProcessSnap);

    return false;
}

【讨论】:

    【解决方案2】:

    您可以使用 Qpr​​ocess 以编程方式运行 vbs/batch (.bat) 文件..

    【讨论】:

      【解决方案3】:

      好的,我最后解决的方法如下:

      void Widget::waitForExe() //#
      

      {

      ifdef Q_OS_WIN32

           HWND hWnd;
           do{
            hWnd = ::FindWindow(NULL, L"TARGETWINDOW!");
           }while(!hWnd);                                                   
       // will loop a goto FindWindow() till hWnd captured (window opened/found)
       // better use above in another thread as it will freeze the GUI otherwise.
      
        qDebug() << "target window found in waitForExe()";
        DWORD pid = 0x0;
        GetWindowThreadProcessId( hWnd, &PID );
        qDebug() << "PID: " << pid;
      
        HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,       FALSE,pid);
      
        if(handle == 0)
            qDebug()<<"no handle after openProcess() :(";
        else{
            wchar_t exe_path[2048] = {};
      
            if (GetModuleFileNameEx(handle, 0, exe_path, sizeof(exe_path)-1))
              qDebug() << "exe_path" << QString::fromWCharArray(exe_path);
      
            else
              qDebug() << "GetModuleFileNameEx() failed: " << GetLastError();
      
            CloseHandle(handle);
        }
      

      endif

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 2011-03-23
        • 1970-01-01
        • 2013-08-19
        • 1970-01-01
        • 2017-12-02
        • 1970-01-01
        相关资源
        最近更新 更多