如何在session 0运行的程序中判断进程是否属于当前活跃用户会话
问题解决方法
1. 修复核心语法错误
你观察到的ProcessIdToSessionId返回值错误是代码语法问题直接导致的:在判断进程会话ID是否匹配当前用户会话ID的代码行,你误用了赋值运算符=而非比较运算符==,直接覆盖了API返回的真实进程会话ID:
// 错误写法:把当前用户会话ID赋值给process_session_id,覆盖了API返回值 if (process_session_id = current_user_session_id) process_running = true;
修改为比较运算符即可解决值被覆盖的问题:
// 正确写法:比较两个ID是否相等 if (process_session_id == current_user_session_id) process_running = true;
2. 补充API调用错误校验
ProcessIdToSessionId调用成功时返回非0值,失败返回0,你当前没有做返回值校验,权限不足等场景会导致拿到无效的会话ID,建议补充校验逻辑:
DWORD process_session_id = 0; // 调用失败直接跳过当前pid if (!ProcessIdToSessionId(pid, &process_session_id)) { continue; }
如果仍偶发取值错误,可以替换为更稳定的WTS接口获取进程所属会话ID:
DWORD process_session_id = 0; DWORD bytes_returned = 0; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pid, WTSSessionId, (LPTSTR*)&process_session_id, &bytes_returned)) { WTSFreeMemory(&process_session_id); }
3. 优化主逻辑流程
process_running变量需要在每次循环遍历进程前重置为false,否则上一轮循环的状态会残留,导致该启动新进程时不触发启动逻辑GetCurrentUserSessionId_RemoteDesktop不需要在遍历每个进程时都调用,在每次循环开始、获取进程列表前调用一次即可,减少不必要的系统开销Sleep(10)间隔过短会无意义占用CPU,建议调整为1000~5000毫秒
4. 调整后主循环参考代码
while (true) { // 每次循环先重置状态 bool process_running = false; // 提前获取当前活跃会话ID DWORD current_user_session_id = GetCurrentUserSessionId_RemoteDesktop(); // 获取所有foo.exe的pid std::vector<int> processes_id = _GetAllProcessId(L"foo.exe"); for (size_t i = 0; i < processes_id.size(); i++) { DWORD pid = processes_id[i]; DWORD process_session_id = 0; // 补充调用成功校验 if (!ProcessIdToSessionId(pid, &process_session_id)) { continue; } // 关闭session 0下的异常进程 if (process_session_id == 0) { const auto explorer = OpenProcess(PROCESS_TERMINATE, false, pid); if (explorer) { TerminateProcess(explorer, 1); CloseHandle(explorer); } continue; } // 匹配当前活跃会话ID if (process_session_id == current_user_session_id) { process_running = true; } } // 未找到对应进程则启动 if (!process_running) { // 调用ExecAs库启动foo.exe到当前会话 } // 降低轮询频率 Sleep(3000); }
内容的提问来源于stack exchange,提问作者user14451870
相关产品推荐
相关产品推荐

