如何在启动 Mozilla Firefox 时获取进程 ID?
How to get the process ID when starting Mozilla Firefox?
获取我正在启动的进程的 PID 的任务,CreateProcess()
ProcessInformation.dwProcessId
在这方面做得很好,但就我而言,我启动的进程打开了子进程处理然后关闭,我需要获取创建我正在打开的进程的所有 PID。
我找到这段代码,它接收子 PID,但它们与最终的 Firefox 不匹配 window,我做错了什么
来源:
更新 1
在 Drake Wu - MSFT 评论之后,我使用了以下代码
int test(const wchar_t* programPath) {
HANDLE Job = CreateJobObject(nullptr, nullptr);
if (!Job) {
std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
return 0;
}
HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (!IOPort) {
std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
return 0;
}
JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;
if (!SetInformationJobObject(Job,
JobObjectAssociateCompletionPortInformation,
&Port, sizeof(Port))) {
std::cout << "SetInformation, error " << GetLastError() << std::endl;
return 0;
}
PROCESS_INFORMATION ProcessInformation;
STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
LPWSTR szCmdline = const_cast<LPWSTR>(programPath);
if (!CreateProcessW(
programPath,
nullptr,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&StartupInfo,
&ProcessInformation))
{
std::cout << "CreateProcess, error " << GetLastError() << std::endl;
return 0;
}
std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
std::cout << "Assign, error " << GetLastError() << std::endl;
return 0;
}
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;
while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
{
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
std::cout << "New PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_EXIT_PROCESS:
std::cout << "Exit PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
break;
default:
break;
}
if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
break;
}
std::cout << "All done" << std::endl;
}
我得到了以下结果:
standart Firefox
test(L"C:\Program Files\Mozilla Firefox\firefox.exe");
portable edition Firefox
test(L"D:\FirefoxPortable\FirefoxPortable.exe");
和以前一样,PID 返回错误。在便携版的情况下,进程挂在while循环上,在firefox标准版的情况下,GetQueuedCompletionStatus()
returnsJOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO
。为什么我得到错误的结果?
更新 2
我 运行 Visual Studio 作为管理员,但是在标准启动时一切都显示正确
我测试过Firefox的进程不是新建的,是按顺序退出的(CreateProcess
获取到的pid会退出),如果有新的进程创建,你的代码不会接收到新的Firefox进程稍后。
您可以使用 swtich-case
语句,以下示例适用于我:
int openProgram(const wchar_t* programPath) {
HANDLE Job = CreateJobObject(nullptr, nullptr);
if (!Job) {
std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
return 0;
}
HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (!IOPort) {
std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
return 0;
}
JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;
if (!SetInformationJobObject(Job,
JobObjectAssociateCompletionPortInformation,
&Port, sizeof(Port))) {
std::cout << "SetInformation, error " << GetLastError() << std::endl;
return 0;
}
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
LPTSTR szCmdline = _tcsdup(programPath);
if (!CreateProcessW(
nullptr,
szCmdline,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&StartupInfo,
&ProcessInformation))
{
std::cout << "CreateProcess, error " << GetLastError() << std::endl;
return 0;
}
std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
std::cout << "Assign, error " << GetLastError() << std::endl;
return 0;
}
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;
while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
{
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
std::cout << "New PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_EXIT_PROCESS:
std::cout << "Exit PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
break;
default:
break;
}
if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
break;
}
std::cout << "All done" << std::endl;
}
结果:
获取我正在启动的进程的 PID 的任务,CreateProcess()
ProcessInformation.dwProcessId
在这方面做得很好,但就我而言,我启动的进程打开了子进程处理然后关闭,我需要获取创建我正在打开的进程的所有 PID。
我找到这段代码,它接收子 PID,但它们与最终的 Firefox 不匹配 window,我做错了什么
来源:
更新 1 在 Drake Wu - MSFT 评论之后,我使用了以下代码
int test(const wchar_t* programPath) {
HANDLE Job = CreateJobObject(nullptr, nullptr);
if (!Job) {
std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
return 0;
}
HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (!IOPort) {
std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
return 0;
}
JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;
if (!SetInformationJobObject(Job,
JobObjectAssociateCompletionPortInformation,
&Port, sizeof(Port))) {
std::cout << "SetInformation, error " << GetLastError() << std::endl;
return 0;
}
PROCESS_INFORMATION ProcessInformation;
STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
LPWSTR szCmdline = const_cast<LPWSTR>(programPath);
if (!CreateProcessW(
programPath,
nullptr,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&StartupInfo,
&ProcessInformation))
{
std::cout << "CreateProcess, error " << GetLastError() << std::endl;
return 0;
}
std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
std::cout << "Assign, error " << GetLastError() << std::endl;
return 0;
}
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;
while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
{
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
std::cout << "New PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_EXIT_PROCESS:
std::cout << "Exit PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
break;
default:
break;
}
if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
break;
}
std::cout << "All done" << std::endl;
}
我得到了以下结果:
standart Firefox
test(L"C:\Program Files\Mozilla Firefox\firefox.exe");
portable edition Firefox
test(L"D:\FirefoxPortable\FirefoxPortable.exe");
和以前一样,PID 返回错误。在便携版的情况下,进程挂在while循环上,在firefox标准版的情况下,GetQueuedCompletionStatus()
returnsJOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO
。为什么我得到错误的结果?
更新 2
我 运行 Visual Studio 作为管理员,但是在标准启动时一切都显示正确
我测试过Firefox的进程不是新建的,是按顺序退出的(CreateProcess
获取到的pid会退出),如果有新的进程创建,你的代码不会接收到新的Firefox进程稍后。
您可以使用 swtich-case
语句,以下示例适用于我:
int openProgram(const wchar_t* programPath) {
HANDLE Job = CreateJobObject(nullptr, nullptr);
if (!Job) {
std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
return 0;
}
HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (!IOPort) {
std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
return 0;
}
JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;
if (!SetInformationJobObject(Job,
JobObjectAssociateCompletionPortInformation,
&Port, sizeof(Port))) {
std::cout << "SetInformation, error " << GetLastError() << std::endl;
return 0;
}
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
LPTSTR szCmdline = _tcsdup(programPath);
if (!CreateProcessW(
nullptr,
szCmdline,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&StartupInfo,
&ProcessInformation))
{
std::cout << "CreateProcess, error " << GetLastError() << std::endl;
return 0;
}
std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
std::cout << "Assign, error " << GetLastError() << std::endl;
return 0;
}
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;
while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
{
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
std::cout << "New PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_EXIT_PROCESS:
std::cout << "Exit PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
break;
default:
break;
}
if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
break;
}
std::cout << "All done" << std::endl;
}
结果: