捕获外部进程的工作目录[Qt / WinAPI]

时间:2015-07-23 23:50:08

标签: c++ qt winapi

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

3 个答案:

答案 0 :(得分:1)

我之前做过类似的事情,这是相关的部分。只是为了说明它是如何运作的。

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

如果您使用此代码段并启动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;
}

答案 1 :(得分:0)

您可以使用Qprocess ..

以编程方式运行vbs / batch(.bat)文件

答案 2 :(得分:0)

好的,这是我最终如何解决它的问题:

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

}