kihlh 发表于 2023-5-12 21:47

修改窗口句柄的图标 一个支持其他进程的方式

我自己写了一个node模块 专门用于处理窗口和进程和一些系统常用api处理 , 有天因为需求编写了窗口图标修改的功能,但是发现居然只能修改标题处的图标

就是这里
!(https://cos.kiic.top/assets/anc/Snipaste_2023-05-12_21-09-50.png)
真该死呀,我的node连接WebView2 的方案看样子要扼杀在摇篮里了
然后今天 编写自己的窗口的图标修改时候发现,进程对着自己的进程居然可以修改,而且大图标也是正常修改的,然后灵机一动,是不是直接调用系统dll就可以越过这个权限限制

### 说干就干 发现其实可行

#### 从可执行文件中获取并设置窗口图标
```cpp
        void SetWindowIconForExtractUs32(HWND hwnd, string iconStr, int index)
{
    HICON hIcon;
    hIcon = (HICON)ExtractIconA(NULL, iconStr.c_str(), index);
    HINSTANCE hIn = NULL;
    hIn = LoadLibraryA("user32.dll");
    if (hIn)
    {
      LRESULT(WINAPI * SendMessageA)
      (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
      SendMessageA = (LRESULT(WINAPI *)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam))GetProcAddress(hIn, "SendMessageA");
      if (SendMessageA)
      {
            SendMessageA(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
            SendMessageA(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
      }
      else
      {
      }
    }
    else
    {
    }
}

void SetWindowIconForExtract(HWND hwnd, string iconStr, int index)
{
    HICON hIcon;
    hIcon = (HICON)ExtractIconA(NULL, iconStr.c_str(), index);

    SendMessageA(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
    SendMessageA(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
}


// 设置第一个是句柄第二个是 可执行文件名称 第三个是 索引(指的是文件中的第N个图标)
HWND handle = 123;
        SetWindowIconForExtract(handle,"F:\\1.exe",0);
        SetWindowIconForExtractUs32(handle,"F:\\1.exe",0);
       // 刷新窗口
    UpdateWindow(handle);
       
// - 为啥要执行两次 因为直接调用系统的dll不一定会成功 这个也无法查询 所以索性设置两次
```


### 直接将ico文件设置为窗口图标
```cpp
void SetWindowTitleIcon(HWND handle, string iconStr)
{
    HICON hWindowIcon = NULL;
    HICON hWindowIconBig = NULL;
    if (hWindowIcon != NULL)
      DestroyIcon(hWindowIcon);
    if (hWindowIconBig != NULL)
      DestroyIcon(hWindowIconBig);
    hWindowIcon = (HICON)LoadImageA(GetModuleHandle(NULL), iconStr.c_str(), IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
    hWindowIconBig = (HICON)LoadImageA(GetModuleHandle(NULL), iconStr.c_str(), IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
    SendMessage(handle, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon);
    SendMessage(handle, WM_SETICON, ICON_BIG, (LPARAM)hWindowIconBig);
}
void SetWindowTitleIconUs32(HWND handle, string iconStr)
{
    HICON hWindowIcon = NULL;
    HICON hWindowIconBig = NULL;
    if (hWindowIcon != NULL)
      DestroyIcon(hWindowIcon);
    if (hWindowIconBig != NULL)
      DestroyIcon(hWindowIconBig);
    hWindowIcon = (HICON)LoadImageA(GetModuleHandle(NULL), iconStr.c_str(), IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
    hWindowIconBig = (HICON)LoadImageA(GetModuleHandle(NULL), iconStr.c_str(), IMAGE_ICON, 32, 32, LR_LOADFROMFILE);

    HINSTANCE hIn = NULL;
    hIn = LoadLibraryA("user32.dll");
    if (hIn)
    {
      LRESULT(WINAPI * SendMessageA)
      (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
      SendMessageA = (LRESULT(WINAPI *)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam))GetProcAddress(hIn, "SendMessageA");
      if (SendMessageA)
      {

            SendMessageA(handle, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon);
            SendMessageA(handle, WM_SETICON, ICON_BIG, (LPARAM)hWindowIconBig);
      }
      else
      {
      }
    }
    else
    {
    }
}

HWND handle = 123;
        SetWindowTitleIcon(handle,"F:\\1.exe");
        SetWindowTitleIconUs32(handle,"F:\\1.exe");
       // 刷新窗口
    UpdateWindow(handle);
```

### 既然轮子已经实现那我们将其应用在node中

```cpp

static napi_value setWindowTitleIcon(napi_env env, napi_callback_info info)
{
    napi_status status;
    size_t argc = 2;
    napi_value args;
    status = $napi_get_cb_info(argc, args);
    int64_t Handle;
    status = napi_get_value_int64(env, args, &Handle);
    HWND handle = (HWND)Handle;
    string iconStr = call_String_NAPI_WINAPI_A(env, args);

    SetWindowTitleIcon(handle, iconStr);
    UpdateWindow(handle);
    return NULL;
}

static napi_value setWindowIconForExtract(napi_env env, napi_callback_info info)
{
    napi_status status;
    size_t argc = 3;
    napi_value args;
    status = $napi_get_cb_info(argc, args);
    int64_t Handle;
    status = napi_get_value_int64(env, args, &Handle);
    HWND handle = (HWND)Handle;
    string iconStr = call_String_NAPI_WINAPI_A(env, args);
    int index;
    status = napi_get_value_int32(env, args, &index);
    SetWindowIconForExtract(handle, iconStr, index);
    SetWindowIconForExtractUs32(handle, iconStr, index);
    UpdateWindow(handle);
    return NULL;
}

```

在node中测试是否成功 使用 hmc-win32 模块 (我写的)
将WebView2 窗口的图标设置为新的图标
```javaScript
const hmc = require ('hmc-win32');

hmc.setWindowIconForExtract(138324,"F:\\Root\\APortable\\XMind\\XMind.exe",0);

// 试试直接ico文件

hmc.native.setWindowTitleIcon(138324,"C:\\Users\\kiic\\AppData\\Local\\Temp\\14ff7e14-ea35-4928-ac1c-3935f6c21766.tmp.ico");


```

查询窗口句柄
!(https://cos.kiic.top/assets/anc/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230512214312.png)
修改前
!(https://cos.kiic.top/assets/anc/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230512214252.png)

修改后(二进制)
!(https://cos.kiic.top/assets/anc/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230512214304.png)

修改后(icon)
!(https://cos.kiic.top/assets/anc/Snipaste_2023-05-12_21-46-20.png)

丶懒喵喵 发表于 2023-5-12 23:17

这个是永久保存(关闭再打开也在)
还是运行时才有效果捏

haokucn 发表于 2023-5-12 23:46

应该是运行时有效。

忧郁之子 发表于 2023-5-13 01:23

这个API找不到详细说明,不过还是支持一下

kihlh 发表于 2023-5-13 02:02

丶懒喵喵 发表于 2023-5-12 23:17
这个是永久保存(关闭再打开也在)
还是运行时才有效果捏

修改的是当前进程窗口的图标 如果要彻底修改一个程序的图标 要么从源码入手要么每次启动时候修改

吾爱支持 发表于 2023-5-13 06:51

kihlh 发表于 2023-5-13 02:02
修改的是当前进程窗口的图标 如果要彻底修改一个程序的图标 要么从源码入手要么每次启动时候修改

这个有用处,就是墨鱼时,最小化反图标换成安全的。

kihlh 发表于 2023-5-13 17:34

吾爱支持 发表于 2023-5-13 06:51
这个有用处,就是墨鱼时,最小化反图标换成安全的。

巧了 我就是打算写一个上班时候保护自己电脑的,已经在编写了
1:鼠标移开指定微信对话框 例如名称带有 * 透明度直接变成0
2:鼠标移入指定微信对话框 例如名称带有 * 透明度直接变成50 旁边看不到 自己看得到
3:当指定的usb设备被拔出或者消息发送锁定时候禁用鼠标设备,指定窗口透明度变0和图标变掉
https://cos.kiic.top//202305131734183.png?imageMogr2/quality/90/format/webp

吾爱支持 发表于 2023-5-14 22:15

kihlh 发表于 2023-5-13 17:34
巧了 我就是打算写一个上班时候保护自己电脑的,已经在编写了
1:鼠标移开指定微信对话框 例如名称带有...
加油。。等成品就放心摸了

kihlh 发表于 2023-5-15 04:17

吾爱支持 发表于 2023-5-14 22:15
加油。。等成品就放心摸了

欢迎来提意见 和催更
https://www.52pojie.cn/thread-1785464-1-1.html

吾爱支持 发表于 2023-5-15 07:54

估计论谈不让发类似。私信吧。。
页: [1]
查看完整版本: 修改窗口句柄的图标 一个支持其他进程的方式