我自己写了一个node模块 专门用于处理窗口和进程和一些系统常用api处理 , 有天因为需求编写了窗口图标修改的功能,但是发现居然只能修改标题处的图标
就是这里
真该死呀,我的node连接WebView2 的方案看样子要扼杀在摇篮里了
然后今天 编写自己的窗口的图标修改时候发现,进程对着自己的进程居然可以修改,而且大图标也是正常修改的,然后灵机一动,是不是直接调用系统dll就可以越过这个权限限制
说干就干 发现其实可行
从可执行文件中获取并设置窗口图标
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文件设置为窗口图标
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中
static napi_value setWindowTitleIcon(napi_env env, napi_callback_info info)
{
napi_status status;
size_t argc = 2;
napi_value args[2];
status = $napi_get_cb_info(argc, args);
int64_t Handle;
status = napi_get_value_int64(env, args[0], &Handle);
HWND handle = (HWND)Handle;
string iconStr = call_String_NAPI_WINAPI_A(env, args[1]);
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[3];
status = $napi_get_cb_info(argc, args);
int64_t Handle;
status = napi_get_value_int64(env, args[0], &Handle);
HWND handle = (HWND)Handle;
string iconStr = call_String_NAPI_WINAPI_A(env, args[1]);
int index;
status = napi_get_value_int32(env, args[2], &index);
SetWindowIconForExtract(handle, iconStr, index);
SetWindowIconForExtractUs32(handle, iconStr, index);
UpdateWindow(handle);
return NULL;
}
在node中测试是否成功 使用 hmc-win32 模块 (我写的)
将WebView2 窗口的图标设置为新的图标
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");
查询窗口句柄
修改前
修改后(二进制)
修改后(icon)