You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过进程名称获取窗口HWND?窗口名称随重启随机变化

通过进程名称获取窗口HWND的方案

当然可以搞定!当窗口标题每次重启都随机变化时,通过进程名称定位HWND确实是更可靠的方案。核心思路就是遍历系统里的所有窗口,把窗口和它所属的进程ID关联起来,先找到目标进程的PID,再匹配到对应的窗口句柄。

核心步骤拆解

  • 第一步:根据进程名称找到对应的进程ID(PID)
  • 第二步:遍历系统中所有顶层窗口,获取每个窗口所属的PID
  • 第三步:匹配PID,筛选出目标窗口的HWND(如果一个进程有多个窗口,还可以进一步过滤)

C++ 实现示例

下面是用Windows原生API实现的代码,适合原生开发场景:

#include <windows.h>
#include <tlhelp32.h>
#include <vector>
#include <string>

// 全局变量存储目标PID和找到的HWND(也可以用结构体传递,这里为了简化用全局)
DWORD g_targetPID = 0;
HWND g_targetHWND = NULL;

// 窗口枚举回调函数,逐个检查窗口所属进程
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
    DWORD pid;
    GetWindowThreadProcessId(hwnd, &pid);
    // 匹配PID+过滤可见顶层窗口,不需要的话可以去掉IsWindowVisible判断
    if (pid == g_targetPID && IsWindowVisible(hwnd)) {
        g_targetHWND = hwnd;
        return FALSE; // 找到第一个匹配窗口后停止枚举
    }
    return TRUE;
}

// 根据进程名称获取PID
DWORD GetPIDByName(const std::wstring& processName) {
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    // 创建进程快照
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return 0;

    if (Process32First(hSnapshot, &pe32)) {
        do {
            // 不区分大小写匹配进程名
            if (_wcsicmp(pe32.szExeFile, processName.c_str()) == 0) {
                CloseHandle(hSnapshot);
                return pe32.th32ProcessID;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }
    CloseHandle(hSnapshot);
    return 0;
}

// 测试用主函数
int main() {
    std::wstring targetProcess = L"notepad.exe";
    g_targetPID = GetPIDByName(targetProcess);
    if (g_targetPID == 0) {
        MessageBox(NULL, L"没找到目标进程", L"提示", MB_OK);
        return 1;
    }

    // 开始枚举窗口
    EnumWindows(EnumWindowsProc, 0);
    if (g_targetHWND != NULL) {
        // 拿到HWND后的操作,比如激活窗口
        SetForegroundWindow(g_targetHWND);
    } else {
        MessageBox(NULL, L"没找到目标窗口", L"提示", MB_OK);
    }
    return 0;
}

C# 实现示例

如果是.NET开发场景,用C#实现会更简洁:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections.Generic;

class HWNDFromProcessName
{
    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport("user32.dll")]
    private static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    private static List<IntPtr> _matchedWindows = new List<IntPtr>();
    private static uint _targetPID;

    static void Main(string[] args)
    {
        string processName = "notepad"; // 不需要带.exe后缀
        Process[] targetProcesses = Process.GetProcessesByName(processName);
        
        if (targetProcesses.Length == 0)
        {
            Console.WriteLine("未找到目标进程");
            return;
        }
        _targetPID = (uint)targetProcesses[0].Id;

        // 枚举所有窗口收集匹配项
        EnumWindows(WindowEnumCallback, IntPtr.Zero);

        if (_matchedWindows.Count > 0)
        {
            Console.WriteLine($"找到 {_matchedWindows.Count} 个属于目标进程的窗口");
            // 对第一个窗口进行操作,比如激活
            SetForegroundWindow(_matchedWindows[0]);
        }
        else
        {
            Console.WriteLine("未找到目标窗口");
        }
    }

    private static bool WindowEnumCallback(IntPtr hWnd, IntPtr lParam)
    {
        GetWindowThreadProcessId(hWnd, out uint pid);
        if (pid == _targetPID && IsWindowVisible(hWnd))
        {
            _matchedWindows.Add(hWnd);
        }
        return true; // 返回true继续枚举所有窗口,收集全部匹配项
    }
}

注意事项

  • 一个进程可能对应多个窗口,如果需要全部收集,不要在回调里提前终止枚举(比如C++示例里返回FALSE会停止,改成TRUE就能收集所有匹配窗口)
  • IsWindowVisible用于过滤不可见窗口,如果需要包括后台窗口,可以去掉这个判断
  • 进程名称匹配尽量用不区分大小写的方式,避免因为大小写问题找不到进程

内容的提问来源于stack exchange,提问作者rck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:38:34