OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 150

Wine:兼容层与前缀

从 Windows API 兼容理解 Wine 的 DLL、前缀、配置与运行边界。

所在专题Wine 与应用环境 ↗
约 20 分钟阅读开始阅读

"Wine Is Not an Emulator" — 不是模拟器,而是在 Linux 上重新实现 Windows API 的兼容层。本文介绍 API 兼容、前缀管理,以及 NTSYNC、WoW64、Wayland 的验证条件;具体支持范围取决于所用版本、构建和发行版。


Wine 的核心原理与架构#

API 翻译,而非 CPU 模拟

Wine 将 Windows PE (Portable Executable) 加载到 Linux 用户空间,实时把 Windows API 调用翻译为 POSIX/Linux 系统调用。与虚拟机不同,Wine 不模拟 CPU 指令——在兼容的 CPU 架构上,Windows 程序通常直接执行对应机器指令,Wine 负责加载及 API/系统行为兼容。跨 CPU 架构则可能另外依赖指令翻译工具,不能把 Wine 本身当作 CPU 模拟器:

graph LR
    subgraph "Windows .exe"
        APP["应用程序"]
    end
    subgraph "Wine"
        NTDLL["ntdll.dll — NT 内核模拟"]
        KERNEL["kernel32.dll — 进程/线程/文件"]
        USER["user32.dll / gdi32.dll — 窗口与绘制"]
    end
    subgraph "Linux Kernel"
        SYSCALL["syscall"]
        DRIVER["GPU / FS / Net"]
    end
    APP --> NTDLL
    APP --> KERNEL
    APP --> USER
    NTDLL --> SYSCALL
    KERNEL --> SYSCALL
    USER --> DRIVER

性能由应用、API 路径、驱动、同步实现和图形转换共同决定,可能下降也可能接近原生或更快;没有基准、版本与硬件条件时,不给出固定损耗百分比。

DLL 双轨制:Builtin vs Native

Wine 的 DLL 加载可在内建实现与外部 DLL 之间选择;不是每个 Windows DLL 都存在完整可用的两种实现:

类型 来源 特点
Builtin Wine 自行实现 开源替代品,功能可能不完整
Native 真实 Windows / Microsoft 分发包 来源和兼容性需核对,可能依赖其他 Windows 组件;还需遵守分发许可证

通过 winecfg 的 Libraries 面板为特定 DLL 指定优先级。常见用例:用原生 riched20.dll 解决富文本编辑器中文输入问题。

图形后端:多层转译管线

Windows App (D3D9/10/11)
    ↓
WineD3D (Wine 内置 D3D→OpenGL)
    ↓ 可替换为 DXVK (D3D→Vulkan)
OpenGL 或 Vulkan
    ↓
X11 / Wayland

DXVK 的 Vulkan 路径可以减少某些工作负载的转换开销,但收益取决于游戏、DXVK 与驱动版本;WineD3D 回退适合诊断或不具备所需 Vulkan 支持的环境,不能承诺固定帧率提升。


Wine Prefix:虚拟 Windows 环境#

Prefix 目录结构

Prefix 是 Wine 最核心的概念——一个独立目录,包含完整的虚拟 Windows 环境:

~/.wine/                    # 默认 Prefix
├── drive_c/                # 虚拟 C:\
│   ├── windows/
│   │   ├── system32/       # Windows 目录布局;DLL/PE 与宿主库形式随 Wine 构建变化
│   │   └── ...
│   ├── Program Files/
│   └── users/
├── dosdevices/             # 驱动器映射 (c: -> drive_c)
├── system.reg              # 注册表 HKLM
├── user.reg                # 注册表 HKCU
└── .update-timestamp

关键特性

  • 配置分离:不同程序使用不同 Prefix,分离 DLL、注册表和应用文件,减少配置冲突;它们仍可共享宿主用户权限、文件与网络,不是安全隔离
  • 架构控制:创建时按所选 Wine 构建指定架构;传统构建与新 WoW64 构建的支持选项不同,不能统一宣称 win32 已弃用或所有版本接受 wow64
  • 可备份与重建:Prefix 是普通目录,但可能包含存档、授权信息和配置。关闭相关进程、确认备份范围后先重命名保留原目录,再建立新前缀测试;不要直接删除唯一副本

Prefix 创建操作

# 创建 64 位 Prefix(推荐)
WINEARCH=win64 WINEPREFIX=~/Games/MyApp winecfg

# 新 WoW64 构建可减少对 32 位 Unix 库的依赖;先核对发行包说明。
# WINEARCH 的可用值随 Wine 版本与构建不同,不在这里强制 wow64。

# 为特定 Prefix 安装依赖
WINEPREFIX=~/Games/MyApp winetricks vcrun2022 dotnet48

实战:从零到运行一个 Windows 程序#

完整工作流

下面是独立普通 Wine 前缀的示例,/home/user 是需替换的通用用户路径。Arch 与 NixOS 安装方式分别使用;依赖按应用要求选择,不是预装越多越好。

# 第一步:安装 Wine(以 Arch/NixOS 为例)
# Arch
sudo pacman -Syu wine wine-mono wine-gecko winetricks
# NixOS — 在 configuration.nix 中声明(见 05_NixOS_Management)

# 第二步:创建独立 Prefix
WINEPREFIX="$HOME/Games/MyTool" winecfg
# 首次运行会弹出 winecfg 窗口,同时创建 Prefix 骨架

# 第三步:安装 Windows 运行时依赖
WINEPREFIX=~/Games/MyTool winetricks -q vcrun2022 dotnet48 allfonts

# 第四步:运行安装程序
WINEPREFIX=~/Games/MyTool wine ~/Downloads/Setup_MyTool.exe
# 安装完成后,程序默认安装在 Prefix 内的 C:\Program Files\

# 第五步:运行已安装的程序
cd ~/Games/MyTool/drive_c/Program\ Files/MyTool
WINEPREFIX=~/Games/MyTool wine MyTool.exe

# 第六步(可选):创建桌面快捷方式
cat > ~/.local/share/applications/mytool.desktop <<'EOF'
[Desktop Entry]
Name=MyTool
Exec=env WINEPREFIX=/home/user/Games/MyTool wine "/home/user/Games/MyTool/drive_c/Program Files/MyTool/MyTool.exe"
Type=Application
Icon=wine
EOF

日常操作速查

# 为某个 Prefix 打开 winecfg 面板
WINEPREFIX=~/Games/MyTool winecfg

# 直接运行 .exe(不安装)
WINEPREFIX=~/Games/MyTool wine ./portable-app.exe

# 打开虚拟 C 盘的文件管理器
WINEPREFIX=~/Games/MyTool winefile

# 打开注册表编辑器
WINEPREFIX=~/Games/MyTool regedit

# 打开 Windows 命令行(cmd.exe)
WINEPREFIX=~/Games/MyTool wine cmd

# 卸载程序(通过 Windows 添加/删除程序)
WINEPREFIX=~/Games/MyTool wine uninstaller

# 查看当前 Prefix 的 Windows 进程与窗口
WINEPREFIX=~/Games/MyTool wine taskmgr
# wineserver -d 用于服务器调试输出,不是进程列表命令。

winecfg 配置面板详解#

运行 WINEPREFIX=... winecfg 后可见以下标签页:

Applications — 按应用设置 Windows 版本

设置 作用
Windows Version 报告给程序的 Windows 版本号。默认值随版本与前缀状态变化;部分老旧程序需要特定版本报告
Per-application override 为特定 .exe 设置不同的 Windows 版本

常见应用:某些安装程序检测到 Win10/Win11 后拒绝运行,设 Win7 可绕过。

Libraries — DLL 覆盖(最常用的面板)

对每个 DLL 可设置覆盖优先级:

覆盖模式 含义
Builtin then Native (b,n) 先尝试 Wine 自带,失败再用原生(加载顺序,不是安全策略)
Native then Builtin (n,b) 先尝试原生 DLL,失败再用 Wine 自带(覆盖安装的组件优先)
Builtin only (b) 强制用 Wine 自带
Native only (n) 强制用原生(如从 Windows 复制的 DLL)
Disable 禁用此 DLL

常用覆盖场景:

d3d9, d3d10core, d3d11, dxgi   → (n,b)  启用 DXVK
nvapi64, nvapi                  → Disable  禁用 NVAPI(防崩溃)
riched20                        → (n,b)  修复中文输入
mscoree, mscorsvw               → Disable  禁用 .NET(用 Wine Mono 代替)

Graphics — 图形设置

设置 建议
Automatically capture the mouse 全屏游戏开启
Emulate a virtual desktop 若程序窗口无法正确显示,填入分辨率如 1920×1080
DPI 高 DPI 屏幕可设 144 或 192

Drives — 驱动器映射

默认 C: → Prefix 内 drive_c/,Z: → Linux 根目录 /。可添加映射如 D: → /mnt/games 方便访问外部文件。移除 Z: 只能减少一个便利的文件入口,不形成文件系统或网络安全边界。不可信程序需要独立评估宿主权限、挂载、网络和显示服务;可使用适当配置的沙箱或虚拟机。

Audio / Staging 面板

  • Audio:选择音频驱动(winepulse.drv / winealsa.drv)
  • Staging:只有相应构建和版本提供时才出现。历史 CSMT 等选项不能概括所有当前构建,是否有效应查对应版本说明并实际测量

winetricks 依赖管理实战#

基本用法

# GUI 模式(首次推荐,可浏览所有可安装组件)
WINEPREFIX=~/Games/MyTool winetricks

# 命令行静默安装(-q 参数)
WINEPREFIX=~/Games/MyTool winetricks -q <组件名>

# 列出所有可用组件
winetricks list-all

场景配方

按应用文档或已核对的兼容报告选择依赖,先在独立前缀中测试。安装 .NET、VC 运行时和字体不能保证某个 Office 或 Photoshop 版本兼容;许可、安装器、在线服务与未实现 API 都可能成为限制。

现代 Windows 应用的候选依赖:

# Visual C++、.NET 与字体分别按应用要求选取;不是每个程序都需要全部安装。
WINEPREFIX="$HOME/Games/MyTool" winetricks -q \
  vcrun2022 dotnet48 corefonts

老游戏的候选依赖:

# DirectX 辅助库、VC 2015 与 XACT 按日志缺项选择。
WINEPREFIX="$HOME/Games/OldGame" winetricks -q \
  vcrun2015 d3dx9 d3dx10 xact

中文字体:

WINEPREFIX="$HOME/Games/MyTool" winetricks -q cjkfonts

allfonts、directx9、fakechinese 等名称是否可用,应先通过当前 winetricks 的列表查询;不要把 locale、编码与字体缺失视为同一问题,也不要无差别安装所有组件。

Media Foundation / 过场动画:先看 Proton 或所选 runner 对目标游戏的媒体修复,再诊断解码器和 GStreamer。mf-install 是曾被教程引用的外部方案,不能未经核对就当作当前 winetricks 内建 verb;lavfilters 的可用性和作用范围也需按当前列表、程序和许可证检查。

winetricks list-all
WINEPREFIX="$HOME/Games/MyGame" winetricks list-installed

Shell 续行反斜杠必须是行尾最后一个字符,不能在 \ 后追加空格或注释。把组件说明放到命令前的独立注释行,避免原本一条命令被意外拆断。

同步、架构与显示驱动的版本边界#

1. NTSYNC:内核同步原语

NTSYNC 为 Windows NT 风格的同步对象提供 Linux 内核接口,用于等待、事件、互斥与信号量等操作。它与 runner 曾采用的 esync/fsync 是不同实现路径;后者也涉及内核设施,不能笼统描述成全部在用户空间完成。

要判断能否使用 NTSYNC,应分别检查内核配置、驱动/设备、权限、runner 的实现与当前进程实际选择。内核版本号大于某个数、出现 /dev/ntsync 或看到一条日志,都不是完整的运行证据。内核文档定义接口,Wine/Proton 的版本说明定义用户空间支持。未经复核的游戏帧率表不保留为性能承诺。

# 仅检查设备节点是否存在及其权限,不证明当前游戏正在使用。
ls -l /dev/ntsync

# 对支持该日志通道的 runner 收集线索,再结合进程/版本信息判断。
WINEPREFIX="$HOME/Games/MyApp" WINEDEBUG=+ntsync \
  wine myapp.exe 2>&1 | grep -i ntsync

性能评估至少固定同一游戏场景、runner、驱动、同步模式和硬件,记录帧时间与重复测量;不能把其他机器或开发者的极端测试数值当作通用收益。

2. 新 WoW64 与旧前缀

新 WoW64 路径旨在让 32 位 Windows 代码使用 64 位 Unix 侧运行环境,减少对 32 位 Unix 库的依赖。这不表示所有 32 位应用、Unix 插件、OpenGL 路径或所有发行包已经兼容。

  • WINEARCH 在创建前缀时影响架构,但接受的值、默认值与已有前缀兼容性取决于 Wine 版本和构建。
  • 传统 win32、win64 与新 WoW64 不是可任意切换的标签。遇到架构不匹配,先检查包的构建说明和已有前缀,不强制升级原目录。
  • 需要迁移时保留关闭状态的完整备份,在新目录中验证应用、依赖和存档;不能承诺设置一个变量就无损转换。
  • 是否还有独立 wine64 命令、是否需要 multilib,应以实际安装包为准。

3. Wayland 图形驱动

winewayland.drv 提供直接面向 Wayland 的驱动路径,区别于通过 XWayland 使用 X11 驱动。可用性取决于 Wine/Proton 构建、compositor、协议与具体应用。

功能 验证条件
窗口与全屏 确认实际加载的驱动,测试窗口切换与全屏恢复
剪贴板与拖放 双向测试应用与宿主之间的文本、文件和格式
异形/透明窗口 按应用和 compositor 检查绘制与输入区域
低分辨率缩放 核对显示模式、缩放、鼠标坐标和帧率
输入法 逐应用测试预编辑、候选窗与提交文本
32 位图形程序 核对 runner、WoW64、驱动与所需 Vulkan/OpenGL 功能

不能仅依据主版本号宣称 feature-complete 或所有场景都可脱离 XWayland。

4. 开发版功能应如何记录

原材料提及 DLL 加载启发式、Android 驱动、VBScript 函数与 Vulkan 规范更新,但这些都属于特定开发快照的功能清单,不是普遍兼容保证。DLL/mod 加载要看对应版本和游戏日志;Android 还涉及目标平台构建;VBScript 要按具体函数及程序复核;Vulkan 头文件更新也不代表驱动支持全部扩展。

本次官方 WineHQ 11.0 发布说明访问受限,未据此确认原材料对 11.x/11.6 的具体发布状态。保留上述技术方向和验证方法,不把未经核验的未来/最新版本描述写成事实。

Wine 的局限性#

兼容性不可靠

Wine 的 API 实现靠"逆向工程 + 行为匹配",非 Microsoft 官方代码。任何未实现的 corner case 都可能导致崩溃。WineHQ AppDB 记录了各应用兼容评级(Platinum → Garbage)。

配置复杂度高

纯命令行操作需要理解 DLL 覆盖、注册表编辑、架构约束。GUI 工具(Bottles、Lutris)提供了更低的学习门槛。

安全边界薄弱

Wine 不是沙箱。Wine 内运行的程序可以访问 Linux 文件系统(默认 Z: 映射到 /),恶意程序可读写当前用户及运行环境允许访问的文件;权限不足的文件不会因此自动可写。Flatpak 可提供额外限制,但有效边界取决于实际授权、挂载、设备与网络,不能仅凭“通过 Bottles 运行”就视为安全。

不支持的场景

  • 内核级反作弊(EasyAntiCheat/BattlEye 内核模式)——需游戏开发商主动适配 Linux
  • 硬件驱动依赖——某些外设或加密狗无 Linux 驱动
  • UWP/Windows Store 生态——涉及应用模型、商店、服务和签名等多重限制,不能把运行传统 Win32 程序的方法等同于完整支持

来源与核验边界#

以下参考定义相关机制与支持范围。安装、构建、激活、前缀状态与实际应用行为需要按目标环境分别核验;示例命令没有附带任何主机运行成功的结论。

参考与延伸

  1. Wine 项目 ↗
  2. Linux NTSYNC 接口 ↗
  3. Winetricks 上游 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Wine 与应用环境

  1. 01umu、Wine 与 Proton:看懂兼容层,再选 Bottles 运行器
  2. 02Wine、Proton 与 Bottles 的关系
  3. 03Wine:兼容层与前缀
  4. 04Bottles:运行器与应用环境
CONTINUE READING / 下一篇Proton:游戏运行环境

区分 Steam、官方 Proton、GE 与 umu,并按游戏管理运行器和前缀。