ubuntu22编译winehq9.0 解决阴影框问题
方法一:
1,第一步下载winehq9.0源码:
https://www.winehq.org/
1,编译wine 32位和64位共存
(这一步很重要,如果你想装64位微信就得有64位wine容器,但只编译64位版本因为缺少system32里面文件也会安装不起来)
- 创建两文件夹wine32 wine64 将源码解压2份放入两个文件夹
修改两文件夹源码dlls/user32/win.c文件
cs.lpszClass = className; cs.dwExStyle = exStyle; //-------如下是增加的 if (exStyle == 0x080800a0) // WeChat/WxWork shadow hwnd { FIXME("hack %x\n", cs.dwExStyle); return NULL; } if (exStyle == 0x000800a0) // Netease Cloudmusic shadow wnd { FIXME("hack %x\n", cs.dwExStyle); return NULL; } //-------上面是增加的 return wow_handlers.create_window( &cs, className, instance, TRUE ); }
sudo dpkg --add-architecture i386 sudo apt -y install build-essential && sudo apt -y install libc6-dev:i386 && sudo apt-get -y install gcc-multilib sudo apt-get install flex bison libx11-dev:i386 sudo apt-get install libfreetype-dev:i386 sudo apt-get install libx11-dev sudo apt-get install libfreetype-dev export C_INCLUDE_PATH=/usr/include/freetype2 export CPLUS_INCLUDE_PATH=/usr/include/freetype2 cd wine64 ./configure --enable-win64 make -j 8 cd ../wine32 ./configure --with-wine64=../wine64 (编译32位wine时通过--with-wine64参数指定了已编译完成的wine64位的目录,这样编译32位wine时,程序会注入64位版本处理32位程序所需的库。) make -j 8 sudo make DESTDIR=/opt/wine install cd ../wine64 sudo make DESTDIR=/opt/wine install
如上一定注意编译和安装顺便,编译要先编译64位,再编译32位,安装的话先安装32位再安装64位
3,配置安装
cd /opt/wine/usr/local/bin
(可以wine安装完找不到路径就执行这句,可有可无)
export WINEARCH=win64
(指定架构,好像老版本才用,可有可无)
export WINEPREFIX=~/.wine
(配置容器路径)
winecfg
(初始化,改缩放192)
sudo apt install winetricks
(安装wine搭档)
winetricks
(界面选择安装riched20 riched32)
winecfg
(函数库 riched20 riched32都是原装先于内建,wechatocr.exe停用)
env WINEPREFIX=~/.wine /opt/wine/usr/local/bin/wine64 ~/Downloads/WeChatSetup.exe
方法二:
X api
第一种同样是隐藏窗体,但是在X的层面进行的操作. 然而网上使用的方法大多是错误的, 要么是漏杀, 要么是错杀. 我写了一个正确的程序, 可以正确的隐藏阴影框, 同时不影响各个菜单.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_event.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xproto.h>
static xcb_connection_t *conn;
static xcb_screen_t *scr;
static xcb_atom_t atom;
void init_atom() {
// Get `_NET_WM_NAME` atom
const char *atom_name = "_NET_WM_NAME";
xcb_intern_atom_cookie_t atom_cookie =
xcb_intern_atom(conn, true, strlen(atom_name), atom_name);
xcb_intern_atom_reply_t *atom_reply =
xcb_intern_atom_reply(conn, atom_cookie, NULL);
if (!atom_reply) {
fprintf(stderr, "_NET_WM_NAME atom not found, WTF?\n");
return;
}
atom = atom_reply->atom;
free(atom_reply);
}
void handle_wechat(xcb_window_t window) {
// Get value of `_NET_WM_NAME`
xcb_icccm_get_text_property_reply_t prop;
if (!xcb_icccm_get_text_property_reply(
conn, xcb_icccm_get_text_property(conn, window, atom), &prop, NULL)) {
fprintf(stderr, "Can't get _NET_WM_NAME property\n");
return;
}
if (prop.name_len) {
printf("Normal window with name: %.*s\n", prop.name_len, prop.name);
return;
}
// If `_NET_WM_NAME` is empty, check if this windows accept input
xcb_icccm_wm_hints_t hints;
if (!xcb_icccm_get_wm_hints_reply(conn, xcb_icccm_get_wm_hints(conn, window),
&hints, NULL)) {
fprintf(stderr, "Can't get WM_HINTS property\n");
return;
}
if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && hints.input) {
printf("Normal dialog without name\n");
return;
}
printf("Black shadow window, unmap it!\n");
xcb_unmap_window(conn, window);
return;
}
bool is_wechat(xcb_window_t window) {
xcb_get_property_cookie_t cookie = xcb_get_property(
conn, 0, window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0, 32);
xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie, NULL);
if (!reply) {
return false;
}
int len = xcb_get_property_value_length(reply);
if (!len) {
free(reply);
return false;
}
char *property = (char *)xcb_get_property_value(reply);
printf("0x%0x8: WM_CLASS= %.*s\n", window, len, property);
bool result = false;
if (!strcmp(property, "wechat.exe")) {
printf("Wechat found!\n");
result = true;
}
free(reply);
return result;
}
int main(int argc, char **argv) {
conn = xcb_connect(NULL, NULL);
if (xcb_connection_has_error(conn)) {
fprintf(stderr, "Failed to connect to the X server\n");
exit(1);
}
scr = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
if (!scr) {
fprintf(stderr, "Failed to get X screen\n");
exit(2);
}
uint32_t val[] = {XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY};
xcb_change_window_attributes(conn, scr->root, XCB_CW_EVENT_MASK, val);
init_atom();
while (1) {
xcb_aux_sync(conn);
xcb_generic_event_t *e = xcb_wait_for_event(conn);
if (XCB_EVENT_RESPONSE_TYPE(e) == XCB_MAP_NOTIFY) {
xcb_map_notify_event_t *map = (xcb_map_notify_event_t *)e;
if (is_wechat(map->window)) {
handle_wechat(map->window);
}
}
free(e);
}
if (conn) {
xcb_disconnect(conn);
}
return 0;
}
编译方法:
gcc xwechathide.c -lxcb -lxcb-util -lxcb-icccm -o xwechathide
转至https://12101111.github.io/block-wine-wechat-black-window/