如何从Qt / Windows代码中等待 - 然后 - 捕获外部进程(可能还没有运行)的工作目录?
答案 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() //#
{
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);
}
}