0%

在 Linux 上原生运行 Windows 应用

先放两张张混淆视听的图:

在 Ubuntu 上玩原神。

在 Ubuntu 上使用 VS 开发.net 平台应用。

前言

在 Linux 上运行 Windows 程序的需求历来已久,实现思路各有千秋。最根本的方式是直接开发对应的 Linux 程序,这样无疑增加了开发者的负担;最直接的想法是开一个虚拟机,但是对硬件的要求会很多,还会不得不运行诸多不必要的程序;还有在 Linux 上实现 Windows 依赖的 wine,毕竟不是原生,会有一些地方不尽如人意。

当然,这次介绍的方法也不是完美无暇的,本质上还是借用了 VM 的力量,对硬件条件有一定的要求,但是就表现而言,非常接近 Linux 原生应用,体验很不错。

也就是说,并不是真的原生应用,而是使用体验上十分接近原生应用。

本文使用了 KVM+WinApps 的组合。

KVM 是基于内核的虚拟机,它和 VMware 的区别可以参考 Redhat 的 KVM 虚拟机和 VMware 区别这篇文章,我也不怎么懂,反正就是快点。

WinApps 的介绍是这样的:

Run Windows apps such as Microsoft Office/Adobe in Linux (Ubuntu/Fedora) and GNOME/KDE as if they were a part of the native OS, including Nautilus integration.

翻译过来就是在 linux 上像原生应用一样使用 Windows 应用。emm,基于 KVM。

从下开始的步骤可以看作本人对 WinApps 中 Readme.md#installationKVM.md 的个人翻译、整理与补充。

使用 KVM 创建虚拟机

这一步将使用 KVM 创建一个 win10 的虚拟机。如果已经创建,只需要注意修改计算机名称为 RDPWindows 以及在虚拟机内安装 RDPApps.reg 即可跳过。

安装 KVM

使用以下命令安装 KVM 以及虚拟机系统管理器

1
sudo apt-get install -y virt-manager

一般而言这个时候 需要重启一下才能正常使用虚拟机系统管理器。

下载 Windows 镜像与 KVM 虚拟 IO 驱动

为了正常使用,需要使用 Windows 10 专业版或企业版,家庭版不能正常使用,同时,为了更好的表现以及更低的系统资源占用,需要安装 KVM 虚拟 IO 驱动,可以通过以下链接下载:

Windows 10 ISO:https://www.microsoft.com/zh-cn/software-download/windows10ISO

在非 Windows 系统下打开这个界面,可以下载最新的 Windows 10 镜像

但我个人更推荐使用 LTSC 版本,这样可以避免 Windows 更新造成的愈加臃肿。

最新的 LTSC 版本是基于 1809 的 Windows 10 Enterprise LTSC 2019,ed2k 链接整理自 I Tell You

ed2k://|file|cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso|4478906368|E7C526499308841A4A6D116C857DB669|/

KVM 虚拟 IO 驱动:https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

创建虚拟机

首先打开虚拟机系统管理器

接着,点开编辑 -> 首选项,勾选 Enable XML editing,之后点击关闭

接下来就可以新建虚拟机了。

选择本地安装介质(ISO映像或者光驱),然后点击前进

现在选中下载 Windows 10 ISO 镜像的位值,然后勾选 Automatically detect from the installation media / source,应该可以检测出选择的是 Microsoft Windows 10 系统。

接下来设置内存与 CPU,推荐设置 2 核 CPU 以及 4096MB 内存。(是的,这个配置跑得起来,当然更高点也没大问题)

值得说明的是,这里的 4096MB 并不是指从内存中扣除一块专门给 KVM,而是最大使用这么多的内存。

选择虚拟磁盘的大小,和上文相同,这是指最多占用这么多空间。

接下来给虚拟机命名为 RDPWindows,只有这样的命名才能让 WinApps 检测到虚拟机,然后选择在安装前自定义配置

在点击完成之后,确保在 CPU 的配置下复制主机CPU 配置被选中,然后点击应用

注意:在 Windows 虚拟机安装结束后,有可能这个选项会被勾掉,因此应在安装结束后再次检查。

接下来,在 XML 标签里,编辑 <clock> 部分为:

1
2
3
4
<clock offset='localtime'>
<timer name='hpet' present='yes'/>
<timer name='hypervclock' present='yes'/>
</clock>

然后点击应用,这将大大减少空闲的 CPU 使用率。

接下来,在内存配置界面,将当前分配降低至 1024MB,这是 VM 最少使用内存的用量。(还真能跑得动)点击应用

引导选项配置界面,勾选主机启动时启动虚拟机,相当于开机自启,记得点击应用

对于 SATA磁盘1,将磁盘总线设置为 VirtIO,点击应用

对于 NIC,将设备型号设置为 virtio,点击应用

点击位于左下角的添加硬件按钮,选中存储。对于设备类型,选择 CDROM设备,然后选择前文提到过的虚拟IO驱动。最后,点击完成以添加新的 CDROM 设备。

现在可以点击开始安装了。

接下来开始安装虚拟机

安装虚拟机

像正常安装那样安装 Windows 10。

当出现你想将Windows安装在哪里?这个界面时,点击加载驱动程序

然后选中 VirtIO,一般来讲是在 E:\

选择正确的驱动,一般而言是带着 w10 的那个

然后就能看到安装的磁盘了,点击下一步

接下来就全权交给它了,在安装过程中可能会重启多次。

然后按照个人意愿选择配置 Windows 10,注意先不要联网。

在安装结束后,登录进入安装的 Windows 系统,进到 E:\ 盘,就是那个 VirtIO 的镜像那个盘。双击 virt-win-gt-64.exe 启动驱动安装。

一切保持默认就好。

驱动安装结束后,需要修改一下注册表,访问 https://github.com/Fmstrat/winapps/blob/main/install/RDPApps.reg 下载 RDPApps.reg

可以通过右键单击 Raw 然后点击链接另存为

下载完成后,右键文件,选择合并,接下来一路确认。

之后,重命名操作系统为 RDPWindows,然后点击下一步,暂时不要重启。

最后,启用远程桌面。

在这之后就可以重启计算机然后进行自定义的设置了。

或者安装一些软件诸如 Visual Studio 或者 office 之类的,在之后会用到。

如果需要的话,可以安装 Spice Guest Tools,这样就能实现桌面大小的自适应和主机与虚拟机的复制粘贴。

一切结束后,重启虚拟机,但是不要登录,关闭虚拟系统管理器与虚拟机界面就好。

安装 WinApps

第一步:设置虚拟机

就是上文所说的那些,相当长的过程。

第二步:下载 WinApps 并做预准备

具体而言,执行如下命令

1
2
3
sudo apt-get install -y freerdp2-x11
git clone https://github.com/Fmstrat/winapps.git
cd winapps

第三步:创建 WinApps 配置文件

新建一个配置文件,路径为:~/.config/winapps/winapps.conf,写进如下的信息

1
2
3
4
5
6
7
8
RDP_USER="MyWindowsUser"
RDP_PASS="MyWindowsPassword"
#RDP_DOMAIN="MYDOMAIN"
#RDP_IP="192.168.123.111"
#RDP_SCALE=100
#RDP_FLAGS=""
#MULTIMON="true"
#DEBUG="true"

这个用户名和密码填写为 Windows 10 虚拟机设置的用户名与密码,值得注意的是,不能使用 PIN 码。

至于其它几个可选项(不很能理解,就贴原文了):

  • When using a pre-existing non-KVM RDP server, you can use the RDP_IP to specify it's location
  • If you are running a VM in KVM with NAT enabled, leave RDP_IP commented out and WinApps will auto-detect the right local IP
  • For domain users, you can uncomment and change RDP_DOMAIN
  • On high-resolution (UHD) displays, you can set RDP_SCALE to the scale you would like [100|140|160|180]
  • To add flags to the FreeRDP call, such as /audio-mode:1 to pass in a mic, use the RDP_FLAGS configuration option
  • For multi-monitor setups, you can try enabling MULTIMON, however if you get a black screen (FreeRDP bug) you will need to revert back
  • If you enable DEBUG, a log will be created on each application start in ~/.local/share/winapps/winapps.log

第四步:运行 WinApps 的安装脚本

首先检查一下是否能连接,相应的,使用如下命令:

1
bin/winapps check

一切正常的话,会通过远程界面登录虚拟机,并在最后弹出 Windows 10 的文件资源管理器窗口,这代表连接成功。然后就可以关闭文件资源管理器,按下 Ctrl-C 取消输出。

如果没有连接成功,尝试重新启动虚拟机,或者检查是否是以下原因:

  • 没有携带 check 参数
  • 没有在虚拟机里器用远程桌面
  • 如果设置了 IP,是否无法连接到 IP 地址
  • ~/.config/winapps/winapps.conf 配置文件中,没有正确填写用户名或者密码
  • 在虚拟机里没有合并注册表 RDPApps.reg

接着最后一步运行安装脚本安装已下载的软件:

1
./installer.sh

我已经安装了 Visual Studio,并且做了选择,因此在安装结束后我会看到这些图标:

并能使用 Visual Studio 进行 C# 的.net 开发,就很梦幻。

甚至完成了下面两张图的效果。

添加预定义应用

Visual Studio,powershell 以及 CMD 之所以可以直接使用,是因为对它们进行了配置,这些配置文件可以在 apps 里找到,对于每个文件夹,都有一个 ison.svginfoison.svg 是这个软件在 Ubuntu 上显示的图标,info 里则记录了该软件的名称,路径等信息。

之后,使用 installer.sh 时,会遍历这些配置文件,找到哪些软件已经安装,并展示出来,接着,由用户选择对哪些已安装建立连接,最后再以原生应用的体验进行使用。

在 linux 上玩原神

那么,一系列的环境都已经搭建好了,来尝试下在 linux 上玩玩原神。

首先,在虚拟机里安装原神,这一步没什么好说的,进入原神官网,选择 PC下载,下载安装原神游戏本体。

然后写配置文件,在 apps 文件夹下新建一个文件夹,命名为 Genshin-Impact,先找个原神的 logo,注意必须是 svg 格式,放进去重命名为 icon.svg,下面这张是我自己用的。

然后新建一个文件,命名为 info,编辑这个文件,写进去下面这些内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# GNOME shortcut name
NAME="Genshin"

# Used for descriptions and window class
FULL_NAME="Genshin Impact"

# The executable inside windows
WIN_EXECUTABLE="C:\Program Files\Genshin Impact\launcher.exe"

# GNOME categories
CATEGORIES="WinApps;Game"

# GNOME mimetypes
MIME_TYPES=""

再调用 installer.sh 脚本,进行安装。

一切都很美好,然后点击开始游戏

然后我们得知虚拟机不能运行原神。

但是虚拟机都有绕开虚拟机的方式,KVM 也不例外,根据这个回答,改一下设置就好。

具体而言,打开 CPU 的设置,选择 XML 标签页,修改 <cpu mode='host-model' check='partial'/> 这一项,在里面增加一项,最终的效果为:

1
2
3
<cpu mode='host-model' check='partial'>
<feature policy='disable' name='hypervisor'/>
</cpu>

然后在 <features> 这里也添加一项,效果:

1
2
3
4
5
6
7
8
9
10
<features>
...
<kvm>
<hidden state='on'/>
</kvm>
</features>
...
<cpu mode='host-model' check='partial'>
<feature policy='disable' name='hypervisor'/>
</cpu>

重启一下虚拟机,就可以绕开虚拟机检测了。

我这里本来应该放上游戏内的画面,但是限于我的硬件条件十分一般,延迟会稍微有点高,正常进入游戏是没问题,但是流畅玩耍就有点不行。

回头换个好点的配置试试。

尾声

我在进行实验时,对它的期望不算很高,毕竟在我的认知里,通过虚拟机(特指 VMware)使用另一个系统时,一定有相当大的延迟,交互还不是很好。

但是 KVM + WinApps 的组合让我感觉很不错,我在一块旧的机械硬盘上进行的实验,CPU 也是几年前的 i5,但是对与 CPU 以及内存的占用都没有飙升到特别高,KVM 的虚拟机是后台常驻的,但是在不使用程序时,几乎感知不到它的存在,而且貌似是因为加载程序时不需要完整运行整个系统,延迟也很低,配合上复制粘贴,和原生应用的体验已经十分的相像了。

我曾经对卸载 Windows,将 Linux 作为唯一的日常系统这一想法有些踌躇,但是 KVM + WinApps 的组合让我感觉可以向前迈进一大步了,说不定下次准备更换计算机,使用更高性能的机器时,已经可以完全做到抛弃双系统这一妥协方案了。

Gitalk 加载中 ...