Steam Run UU远程(Windows版本)
目录
在 Linux 下通过 Steam/Proton 运行 UU远程(Windows版)完整指南
在steam中安装uu远程
steam - 库 - 添加非steam游戏
然后右键属性-目标改成下载的exe安装程序。
兼容性-使用特定兼容工具-proton Experimental
ps: 这里是通用步骤,后面是特定于uu远程的修复方法
然后这里安装后会卡住,原因就是后面的IPC通讯问题,强制停止即可。然后后面使用脚本启动的时候这里的兼容性取消掉,因为是启动shell脚本,不需要兼容启动。
问题背景
UU远程(网易 GameViewer)只有 Windows 版本,在 Linux 下需要通过 Steam 的 Proton 兼容层运行。但在实际使用中会遇到一个核心问题:GameViewerService 无法启动子进程,导致整个远程串流功能不可用。
错误现象
启动 UU远程后,查看日志会发现以下循环报错:
GetWinlogonPid: 0
GetWinlogonPid OpenProcess failed: 87
GetWinlogonPid result: 0
[RollingCounter::recordCrash] backoff delay:1
延迟不断翻倍:1s → 2s → 4s → 8s → 16s → 32s → 64s → 128s → 256s…
同时客户端日志持续报:
[IpcSvrProxy::onIpcServerCheckTimeout] check ipc server timeout
根本原因
GameViewerService 使用 GetWinlogonPid 函数查找 Windows 的 winlogon.exe 进程 PID,然后通过 CreateProcessAsUser API 在用户会话中启动 GameViewerServer.exe 和 GameViewerHealthd.exe。
但 Wine/Proton 环境中没有真实的 winlogon.exe 进程,导致:
EnumProcesses找不到 winlogon → PID 返回 0OpenProcess(0, ...)失败,错误码 87(ERROR_INVALID_PARAMETER)- 子进程无法启动 → IPC 服务器不存在 → 客户端无限超时
修复方案
核心思路:创建一个最小的 winlogon.exe 桩程序,让 GameViewerService 能找到一个有效的进程 PID。
第一步:创建 winlogon.exe 桩程序
源代码
创建文件 winlogon_stub.c:
#include <windows.h>
int main(void) {
while(1) {
Sleep(60000);
}
return 0;
}
这是一个最简单的 Windows 程序,启动后进入无限循环,每 60 秒休眠一次。它的唯一作用就是作为一个持续运行的进程,让 GameViewerService 的 GetWinlogonPid 能找到一个有效的 PID。
编译
需要安装 mingw-w64 交叉编译器:
# Ubuntu/Debian
sudo apt install gcc-mingw-w64
# Arch Linux
sudo pacman -S mingw-w64-gcc
# Fedora
sudo dnf install mingw64-gcc
编译命令:
x86_64-w64-mingw32-gcc -mwindows -static -o winlogon.exe winlogon_stub.c
参数说明:
x86_64-w64-mingw32-gcc:64 位 Windows 交叉编译器-o winlogon.exe:输出文件名-static:静态链接,不依赖额外的 DLL-mwindows:把生成的 Windows 可执行文件标记为 Windows GUI 子系统(GUI subsystem),而不是 Console 子系统(CUI subsystem)。默认是 创建控制台窗口(cmd黑框)
安装到 Wine 前缀
# 设置前缀路径(根据你的实际路径修改)
PFX="$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx"
# 复制到 system32 目录
cp winlogon.exe "$PFX/drive_c/windows/system32/winlogon.exe"
第二步:创建设备配置文件(可选)
GameViewer 启动时会读取设备标识配置,如果缺失会产生一些警告日志。可以创建配置文件消除这些警告。
PFX="$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx"
# 生成 UUID
DEVICE_UUID=$(python3 -c "import uuid; print(uuid.uuid4())")
USER_UUID=$(python3 -c "import uuid; print(uuid.uuid4())")
# 创建配置目录
mkdir -p "$PFX/drive_c/ProgramData/Netease/GameViewer/config"
# 创建配置文件
cat > "$PFX/drive_c/ProgramData/Netease/GameViewer/config/device.ini" << EOF
[Device]
deviceId=$DEVICE_UUID
userId=$USER_UUID
uuid=$DEVICE_UUID
EOF
第三步:创建启动脚本
创建文件 start_uuremote.sh:
#!/bin/bash
# UU Remote (GameViewer) 启动脚本 - 适用于 Steam/Proton 环境
# 修复 Wine 中缺少 winlogon.exe 导致服务无法启动子进程的问题
set -x
PFX="$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx"
PROTON_DIR="/mnt/nvme/steamapps/common/Proton - Experimental"
PROTON="$PROTON_DIR/proton"
# 设置环境变量
export WINEPREFIX="$PFX"
export STEAM_COMPAT_DATA_PATH="$HOME/.local/share/Steam/steamapps/compatdata/4065807528"
export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.local/share/Steam"
export DXVK_ASYNC=1
export WINEDLLOVERRIDES="dxva2=n;mfplat=n"
export LIBVA_DRIVER_NAME=radeonsi
WINEPREFIX=$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx '/mnt/nvme/steamapps/common/Proton - Experimental/files/bin/wineserver' -k
# 清理所有残留的 Wine/GameViewer 进程
pkill -f "GameViewerService" 2>/dev/null
pkill -f "GameViewerServer" 2>/dev/null
pkill -f "GameViewerHealthd" 2>/dev/null
pkill -f "crashpad_handler" 2>/dev/null
pkill -f "winedevice.exe" 2>/dev/null
pkill -f "xalia.exe" 2>/dev/null
killall wineserver 2>/dev/null
killall winlogon.exe
sleep 2
echo "[UU Remote] Starting winlogon.exe stub..."
"$PROTON" run "$PFX/drive_c/windows/system32/winlogon.exe" &
WINLOGON_PID=$!
echo "[UU Remote] winlogon.exe started with PID: $WINLOGON_PID"
echo sleep 2
sleep 2
echo "[UU Remote] Starting GameViewer..."
"$PROTON" run "$PFX/drive_c/users/steamuser/Desktop/UU远程.lnk" "$@" &> /tmp/gameviewer.log
EXIT_CODE=$?
echo "[UU Remote] GameViewer exited with code: $EXIT_CODE"
sleep 20
exit $EXIT_CODE
设置执行权限:
chmod +x start_uuremote.sh
路径说明
| 变量 | 说明 | 如何查找 |
|---|---|---|
PFX |
Wine 前缀目录 | ~/.local/share/Steam/steamapps/compatdata/<APPID>/pfx |
PROTON_DIR |
Proton 安装目录 | Steam 库文件夹下的 common/Proton - Experimental |
APPID |
Steam 应用 ID | 在 Steam 中右键游戏 → 属性 → 更新 → 查看 |
查找 Proton wine 路径的方法:
# 查找 compatdata 目录
ls ~/.local/share/Steam/steamapps/compatdata/
# 查找 proton 脚本
find ~/.local/share/Steam/steamapps/common -name "proton" -type f
# 或者查找 wine 二进制
find ~/.local/share/Steam/steamapps/common -name "wine" -type f
使用方式
方式一:直接运行脚本
./start_uuremote.sh
方式二:在 Steam 中设置启动选项
在 Steam 中右键 UU远程 → 属性 → 启动选项,输入:
bash $HOME/start_uuremote.sh
注意:不要加 %command%,因为脚本内部已经自己调用 proton 启动了。
方式三:创建桌面快捷方式
cat > ~/Desktop/UU远程修复版.desktop << 'EOF'
[Desktop Entry]
Name=UU远程修复版
Exec=bash $HOME/start_uuremote.sh
Type=Application
Icon=applications-games
Terminal=false
Categories=Network;RemoteAccess;
EOF
chmod +x ~/Desktop/UU远程修复版.desktop
验证修复是否成功
检查进程
ps aux | grep -i gameviewer
应该能看到以下进程都在运行:
GameViewerService.exe --serviceGameViewerServer.exeGameViewerHealthdwinlogon.exe(桩程序)
检查日志
查看服务日志,确认 GetWinlogonPid 不再返回 0:
# 找到最新的服务日志
ls -lt ~/.local/share/Steam/steamapps/compatdata/4065807528/pfx/drive_c/Program\ Files/Netease/GameViewer/log/service/Log/ | head -3
# 查看日志内容
cat ~/.local/share/Steam/steamapps/compatdata/4065807528/pfx/drive_c/Program\ Files/Netease/GameViewer/log/service/Log/log_最新文件.txt | grep -i winlogon
成功标志:
GetWinlogonPid: 288 # PID 不再是 0
GetWinlogonPid result: 1 # 成功
CreateProcessAsUser id:xxx # 子进程成功启动
检查 IPC 超时
客户端日志中应该不再出现 check ipc server timeout 的循环。
已知限制
1. 硬件视频解码不可用
在 Wine/Proton 下,DXVA2/D3D11VA 硬件视频解码通常不可用,串流会使用软件解码。可以通过设置环境变量尝试启用:
export WINEDLLOVERRIDES="dxva2=n;mfplat=n"
export LIBVA_DRIVER_NAME=radeonsi # AMD 显卡
2. 手柄支持有限
VigEmBus 驱动在 Wine 下无法安装,手柄模拟功能不可用。
3. 虚拟显示器驱动
虚拟显示器驱动可能无法正常工作,取决于具体的 Wine 版本和内核模块支持。
文件清单
修复完成后,涉及的文件:
| 文件 | 位置 | 说明 |
|---|---|---|
winlogon_stub.c |
用户主目录 | 桩程序源代码(可删除) |
winlogon.exe |
~/ 和 Wine 前缀 system32/ |
编译后的桩程序 |
start_uuremote.sh |
~/ |
启动包装脚本 |
device.ini |
Wine 前缀 ProgramData/Netease/GameViewer/config/ |
设备配置(可选) |
环境变量说明
| 变量 | 值 | 说明 |
|---|---|---|
WINEPREFIX |
前缀路径 | 指定 Wine 前缀 |
STEAM_COMPAT_DATA_PATH |
compatdata 路径 | Proton 兼容数据路径 |
STEAM_COMPAT_CLIENT_INSTALL_PATH |
Steam 路径 | Steam 客户端安装路径 |
DXVK_ASYNC |
1 |
启用 DXVK 异步编译,减少卡顿 |
WINEDLLOVERRIDES |
dxva2=n;mfplat=n |
覆盖 DLL 加载顺序 |
LIBVA_DRIVER_NAME |
radeonsi |
AMD 显卡的 VA-API 驱动 |
完整文件内容
winlogon_stub.c
#include <windows.h>
int main(void) {
while(1) {
Sleep(60000);
}
return 0;
}
编译和安装一条命令
x86_64-w64-mingw32-gcc -o winlogon.exe winlogon_stub.c -mwindows -static && \
cp winlogon.exe "$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx/drive_c/windows/system32/winlogon.exe" && \
echo "安装完成"
start_uuremote.sh
#!/bin/bash
# UU Remote (GameViewer) 启动脚本 - 适用于 Steam/Proton 环境
# 修复 Wine 中缺少 winlogon.exe 导致服务无法启动子进程的问题
set -x
PFX="$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx"
PROTON_DIR="/mnt/nvme/steamapps/common/Proton - Experimental"
PROTON="$PROTON_DIR/proton"
# 设置环境变量
export WINEPREFIX="$PFX"
export STEAM_COMPAT_DATA_PATH="$HOME/.local/share/Steam/steamapps/compatdata/4065807528"
export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.local/share/Steam"
export DXVK_ASYNC=1
export WINEDLLOVERRIDES="dxva2=n;mfplat=n"
export LIBVA_DRIVER_NAME=radeonsi
WINEPREFIX=$HOME/.local/share/Steam/steamapps/compatdata/4065807528/pfx '/mnt/nvme/steamapps/common/Proton - Experimental/files/bin/wineserver' -k
# 清理所有残留的 Wine/GameViewer 进程
pkill -f "GameViewerService" 2>/dev/null
pkill -f "GameViewerServer" 2>/dev/null
pkill -f "GameViewerHealthd" 2>/dev/null
pkill -f "crashpad_handler" 2>/dev/null
pkill -f "winedevice.exe" 2>/dev/null
pkill -f "xalia.exe" 2>/dev/null
killall wineserver 2>/dev/null
killall winlogon.exe
sleep 2
echo "[UU Remote] Starting winlogon.exe stub..."
"$PROTON" run "$PFX/drive_c/windows/system32/winlogon.exe" &
WINLOGON_PID=$!
echo "[UU Remote] winlogon.exe started with PID: $WINLOGON_PID"
echo sleep 2
sleep 2
echo "[UU Remote] Starting GameViewer..."
"$PROTON" run "$PFX/drive_c/users/steamuser/Desktop/UU远程.lnk" "$@" &> /tmp/gameviewer.log
EXIT_CODE=$?
echo "[UU Remote] GameViewer exited with code: $EXIT_CODE"
sleep 20
exit $EXIT_CODE