方法一:

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/

标签: none

添加新评论