Jak na Linuxu pohodlně spustit Windows aplikaci

Jak na Linuxu pohodlně spustit Windows aplikaci
Zajímalo by mě, kolik vody (jestli nám nelžou) je potřeba na vygenerování jednoho takového krásného náhledového obrázku 🤔

S příchodem Windows 11 jsem se definitivně rozloučil s oknama a dal volný průchod nejmenované linuxové distribuci (arch btw), kterou jsem je nahradil. Myslím si, že pro někoho, kdo programuje a chce se ve věcích vrtat o trochu víc než průměrný (STRAŠNĚ RÁD používám pojem hloupý uživatel*) uživatel, to není vůbec špatná věc.

✳️
Pojem "hloupý uživatel" neznamená, že by byl člověk hloupý. Správně by to mělo být "koncový (průměrný) uživatel". Jen mi to nezní tak vtipně a navíc koncoví uživatelé občas dělají hloupé věci ¯\_(ツ)_/¯

Co nejhoršího se může stát? Člověk špatně nainstaluje zavaděč (přece nechci bootovat), omylem si zcihluje systém... Tohle jsou věci, které způsobí obvykle lidská blbost (prostě to tak je). Protože... s velkou mocí přichází velká zodpovědnost. Wow. Prostě je to něco za něco. Člověk má nad svým strojem větší moc, ale uživatelská přívětivost nebo softwarová výbava může zezačátku drhnout (pro člověka zvyklého jenom na Windows - to já naštěstí nejsem). A to je důvod proč jsem zjistil, že si chci na Linuxovou distribuci nainstalovat PowerPoint (ne že bych nebyl spokojen s OnlyOffice, ale chybí mi tam Designer funkce, aby ta prezentace vizuálně za něco stála).

Přelomová designer funkce v PowerPointu kvůli které vzniká tento post.

Proto vznikl tento návod, jak pomocí projektu WinApps spustit skoro nativně Windows aplikace v Linuxovém prostředí. Díky WinApps (cituju) můžete "spouštějte aplikace pro Windows (včetně Microsoft 365 a Adobe Creative Cloud) na GNU/Linuxu s KDE Plasma, GNOME nebo XFCE, které jsou integrovány tak hladce, jako by byly nativní pro daný operační systém". To prostě znamená že pohodlně a bez problému.

1) Konfigurace virtálního Windows kontejneru

Prvním krokem je konfigurace virtuálního Windows, ze kterého se budou aplikace spouštět. V principu se totiž aplikace spustí na virtuálním Windowsu na vašem počítači a obsah okna je vzdálenou plochou přenášen tak, aby to vypadalo, že se jedná o nativní program. (Jde dokonce nakonfigurovat i spouštění na již existující vzdálené ploše bez použití lokální virtualizace, já ale budu virtualizovat lokálně pomocí Dockeru)

Virtuální Windows může být realizován třemi způsoby: Docker, Podman nebo libvirt. V tomto návodu použiju Docker, protože už na svém počítači mám nainstalovaný Docker Engine. Popíšu zde instalaci na Arch Linux, poklud máte jiný operační systém, zde je originální návod.

Vytvoření virtuálního Windows pomocí Dockeru

Tato část vychází z originálního návodu pro instalaci Windows.

Předpokládejme, že už máte nainstalovaný Docker Engine (dokumentace k instalaci).
Vytvořte si nový adresář (například winapps) pro konfiguraci Windows a v něm vytvořte soubor compose.yaml podle šablony:

compose.yaml

# For documentation, FAQ, additional configuration options and technical help, visit: https://github.com/dockur/windows

name: "winapps" # Docker Compose Project Name.
volumes:
  # Create Volume 'data'.
  # Located @ '/var/lib/docker/volumes/winapps_data/_data' (Docker).
  # Located @ '/var/lib/containers/storage/volumes/winapps_data/_data' or '~/.local/share/containers/storage/volumes/winapps_data/_data' (Podman).
  data:
services:
  windows:
    image: ghcr.io/dockur/windows:latest
    container_name: WinApps # Created Docker VM Name.
    environment:
      # Version of Windows to configure. For valid options, visit:
      # https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-select-the-windows-version
      # https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-install-a-custom-image
      VERSION: "11"
      RAM_SIZE: "4G" # RAM allocated to the Windows VM.
      CPU_CORES: "4" # CPU cores allocated to the Windows VM.
      DISK_SIZE: "64G" # Size of the primary hard disk.
      # DISK2_SIZE: "32G" # Uncomment to add an additional hard disk to the Windows VM. Ensure it is mounted as a volume below.
      USERNAME: "MyWindowsUser" # Edit here to set a custom Windows username. The default is 'MyWindowsUser'.
      PASSWORD: "MyWindowsPassword" # Edit here to set a password for the Windows user. The default is 'MyWindowsPassword'.
      HOME: "${HOME}" # Set path to Linux user home folder.
    ports:
      - 8006:8006 # Map '8006' on Linux host to '8006' on Windows VM --> For VNC Web Interface @ http://127.0.0.1:8006.
      - 3389:3389/tcp # Map '3389' on Linux host to '3389' on Windows VM --> For Remote Desktop Protocol (RDP).
      - 3389:3389/udp # Map '3389' on Linux host to '3389' on Windows VM --> For Remote Desktop Protocol (RDP).
    cap_add:
      - NET_ADMIN  # Add network permission
    stop_grace_period: 120s # Wait 120 seconds before sending SIGTERM when attempting to shut down the Windows VM.
    restart: on-failure # Restart the Windows VM if the exit code indicates an error.
    volumes:
      - data:/storage # Mount volume 'data' to use as Windows 'C:' drive.
      - ${HOME}:/shared # Mount Linux user home directory @ '\\host.lan\Data'.
      #- /path/to/second/hard/disk:/storage2 # Uncomment to create a virtual second hard disk and mount it within the Windows VM. Ensure 'DISK2_SIZE' is specified above.
      - ./oem:/oem # Enables automatic post-install execution of 'oem/install.bat', applying Windows registry modifications contained within 'oem/RDPApps.reg'.
      #- /path/to/windows/install/media.iso:/custom.iso # Uncomment to use a custom Windows ISO. If specified, 'VERSION' (e.g. 'tiny11') will be ignored.
    devices:
      - /dev/kvm # Enable KVM.
      - /dev/net/tun # Enable tuntap
      # Uncomment to mount a disk directly within the Windows VM.
      # WARNING: /dev/sdX paths may change after reboot. Use persistent identifiers!
      # NOTE: 'disk1' will be mounted as the main drive. THIS DISK WILL BE FORMATTED BY DOCKER.
      # All following disks (disk2, ...) WILL NOT BE FORMATTED.
      # - /dev/disk/by-id/:/disk1
      # - /dev/disk/by-id/:/disk2
    # group_add:      # uncomment this line and the next one for using rootless podman containers
    #   - keep-groups # to make /dev/kvm work with podman. needs "crun" installed, "runc" will not work! Add your user to the 'kvm' group or another that can access /dev/kvm.

Můžete také upravit hodnoty RAM_SIZE, CPU_CORES a další pro nastavení RAM, počet jader procesoru nebo další. Pomocí následujícího příkazu spustíte instalaci:

sudo docker compose --file ./compose.yaml up

Po stažení Docker obrazu se spustí kontejner a začne připravovat nejnovější verzi Windows (verze jde také nastavit v compose.yml). V konzoli se po chvíli čekání vypíše "WinApps | ❯ Windows started successfully, visit http://127.0.0.1:8006/ to view the screen..." a virtuální Windows je hotový. Na uvedené adrese nůžete navštívit plochu.

Krásná a nádherná plocha virtuálního Windows 11 (paradoxně) v prohlížeči na adrese http://127.0.0.1:8006

V terminálu teď můžete Windows vypnout pomocí CTRL+C.

2) Instalace potřebných balíků

Tímto příkazem nainstalujte další potřebné balíky pro spuštění WinApps:

sudo pacman -Syu --needed -y curl dialog freerdp git iproute2 libnotify openbsd-netcat

3) Konfigurační soubor WinApps

Vytvořte konfikurační soubor ~/.config/winapps/winapps.conf s následujícím obsahem:

(Chtěl bych jen podotknout že v compose.yml i v tomto souboru nechávám nastaveny výchozí hodnoty)

winapps.conf

##################################
#   WINAPPS CONFIGURATION FILE   #
##################################

# INSTRUCTIONS
# - Leading and trailing whitespace are ignored.
# - Empty lines are ignored.
# - Lines starting with '#' are ignored.
# - All characters following a '#' are ignored.

# [WINDOWS USERNAME]
RDP_USER="MyWindowsUser"

# [WINDOWS PASSWORD]
# NOTES:
# - If using FreeRDP v3.9.0 or greater, you *have* to set a password
RDP_PASS="MyWindowsPassword"

# [WINDOWS DOMAIN]
# DEFAULT VALUE: '' (BLANK)
RDP_DOMAIN=""

# [WINDOWS IPV4 ADDRESS]
# NOTES:
# - If using 'libvirt', 'RDP_IP' will be determined by WinApps at runtime if left unspecified.
# DEFAULT VALUE:
# - 'docker': '127.0.0.1'
# - 'podman': '127.0.0.1'
# - 'libvirt': '' (BLANK)
RDP_IP="127.0.0.1"

# [VM NAME]
# NOTES:
# - Only applicable when using 'libvirt'
# - The libvirt VM name must match so that WinApps can determine VM IP, start the VM, etc.
# DEFAULT VALUE: 'RDPWindows'
VM_NAME="RDPWindows"

# [WINAPPS BACKEND]
# DEFAULT VALUE: 'docker'
# VALID VALUES:
# - 'docker'
# - 'podman'
# - 'libvirt'
# - 'manual'
WAFLAVOR="docker"

# [DISPLAY SCALING FACTOR]
# NOTES:
# - If an unsupported value is specified, a warning will be displayed.
# - If an unsupported value is specified, WinApps will use the closest supported value.
# DEFAULT VALUE: '100'
# VALID VALUES:
# - '100'
# - '140'
# - '180'
RDP_SCALE="100"

# [MOUNTING REMOVABLE PATHS FOR FILES]
# NOTES:
# - By default, `udisks` (which you most likely have installed) uses /run/media for mounting removable devices.
#   This improves compatibility with most desktop environments (DEs).
# ATTENTION: The Filesystem Hierarchy Standard (FHS) recommends /media instead. Verify your system's configuration.
# - To manually mount devices, you may optionally use /mnt.
# REFERENCE: https://wiki.archlinux.org/title/Udisks#Mount_to_/media
REMOVABLE_MEDIA="/run/media"

# [ADDITIONAL FREERDP FLAGS & ARGUMENTS]
# NOTES:
# - You can try adding /network:lan to these flags in order to increase performance, however, some users have faced issues with this.
#   If this does not work or if it does not work without the flag, you can try adding /nsc and /gfx.
# DEFAULT VALUE: '/cert:tofu /sound /microphone +home-drive'
# VALID VALUES: See https://github.com/awakecoding/FreeRDP-Manuals/blob/master/User/FreeRDP-User-Manual.markdown
RDP_FLAGS="/cert:tofu /sound /microphone +home-drive"

# [DEBUG WINAPPS]
# NOTES:
# - Creates and appends to ~/.local/share/winapps/winapps.log when running WinApps.
# DEFAULT VALUE: 'true'
# VALID VALUES:
# - 'true'
# - 'false'
DEBUG="true"

# [AUTOMATICALLY PAUSE WINDOWS]
# NOTES:
# - This is currently INCOMPATIBLE with 'manual'.
# DEFAULT VALUE: 'off'
# VALID VALUES:
# - 'on'
# - 'off'
AUTOPAUSE="off"

# [AUTOMATICALLY PAUSE WINDOWS TIMEOUT]
# NOTES:
# - This setting determines the duration of inactivity to tolerate before Windows is automatically paused.
# - This setting is ignored if 'AUTOPAUSE' is set to 'off'.
# - The value must be specified in seconds (to the nearest 10 seconds e.g., '30', '40', '50', etc.).
# - For RemoteApp RDP sessions, there is a mandatory 20-second delay, so the minimum value that can be specified here is '20'.
# - Source: https://techcommunity.microsoft.com/t5/security-compliance-and-identity/terminal-services-remoteapp-8482-session-termination-logic/ba-p/246566
# DEFAULT VALUE: '300'
# VALID VALUES: >=20
AUTOPAUSE_TIME="300"

# [FREERDP COMMAND]
# NOTES:
# - WinApps will attempt to automatically detect the correct command to use for your system.
# DEFAULT VALUE: '' (BLANK)
# VALID VALUES: The command required to run FreeRDPv3 on your system (e.g., 'xfreerdp', 'xfreerdp3', etc.).
FREERDP_COMMAND=""

# [TIMEOUTS]
# NOTES:
# - These settings control various timeout durations within the WinApps setup.
# - Increasing the timeouts is only necessary if the corresponding errors occur.
# - Ensure you have followed all the Troubleshooting Tips in the error message first.

# PORT CHECK
# - The maximum time (in seconds) to wait when checking if the RDP port on Windows is open.
# - Corresponding error: "NETWORK CONFIGURATION ERROR" (exit status 13).
# DEFAULT VALUE: '5'
PORT_TIMEOUT="5"

# RDP CONNECTION TEST
# - The maximum time (in seconds) to wait when testing the initial RDP connection to Windows.
# - Corresponding error: "REMOTE DESKTOP PROTOCOL FAILURE" (exit status 14).
# DEFAULT VALUE: '30'
RDP_TIMEOUT="30"

# APPLICATION SCAN
# - The maximum time (in seconds) to wait for the script that scans for installed applications on Windows to complete.
# - Corresponding error: "APPLICATION QUERY FAILURE" (exit status 15).
# DEFAULT VALUE: '60'
APP_SCAN_TIMEOUT="60"

# WINDOWS BOOT
# - The maximum time (in seconds) to wait for the Windows VM to boot if it is not running, before attempting to launch an application.
# DEFAULT VALUE: '120'
BOOT_TIMEOUT="120"

# FREERDP RAIL HIDEF
# - This option controls the value of the `hidef` option passed to the /app parameter of the FreeRDP command.
# - Setting this option to 'off' may resolve window misalignment issues related to maximized windows.
# DEFAULT VALUE: 'on'
HIDEF="on"

4) Test FreeRDP připojení

Následujícím příkazem můžete otestovat připojení na vzdálenou plochu (Windows musí běžet). Uživatelské jméno a heslo si samozřejmě nahraďte svým.

xfreerdp3 /u:"MyWindowsUser" /p:"MyWindowsPassword" /v:127.0.0.1 /cert:tofu
Test FreeRDP

Pokud se objeví chyba, zkuste nápovědu v originálním návodu.

5) Instalace požadovaných aplikací

Teď je čas nainstalovat programy, které chcete spouštět. Já jsem zvolil MS Office, který jsem pro vzdělávací účely stáhl a aktivoval pomocí projektu Microsoft-Activation-Scripts společně s Windows. Instalace aplikací se provádí stejně, jako by se jednalo o standartní Windows instalaci. Samozřejmě přes otevřené testovací FreeRDP. Po ukončení instalace můžete okno FreeRDP zavřít.

6) Instalace WinApps

V dalsím kroku nainstalujeme samotnou aplikaci WinApps. Instalace se spustí jednoduchým příkazem:

bash <(curl https://raw.githubusercontent.com/winapps-org/winapps/main/setup.sh)
Instalační program WinApps

Zde pokračujte Install > Current user > Manual (instalace aplikací) > Choose specific oficially supported applications to set up

Instalační program WinApps

Zde mezerníkem vyberte software, pro který chcete vytvořit zkratku ve vašem systému, a dokončete ionstalaci. A je to! Nyní máte mezi svými aplikacemi přidané zvolené Windows aplikace:

Seznam aplikací v prostředí GNOME
Spuštěný PowerPoint v prostředí GNOME

Pokud chcete přidat nebo odebrat další aplikace, musíte WinApps odinstalovat a znovu ho nainstalovat.

7) Spouštění vlastních aplikací

Pro vzdělávací účely jsem podle návodu nainsaloval na Windows také starší verzi Photoshopu. A protože tato stará verze nepatří mezi podporovaný software, který je automaticky detekován a můžete si pro něj vytvořit zkratku v kroku 6, je potřeba ho spouštět manuálně. To provedeme následujícím příkazem, kde zadáme cestu k .exe souboru:

winapps manual "C:\Program Files (x86)\Adobe Photoshop CS6\Photoshop.exe"

V kombinaci s programem Alacarte si můžete (alespoň na GNOME) vytvořit vlastní zkratku a přidat ji mezi ostatní aplikace:

Vytvoření zkratky pomocí Alacarte
Vlastní zkratka

10) Česká klávesnice

Aby aplikace používaly českou klávesnici je třeba provést dodatečnou konfiguraci.

Jako první standartně nastavte ve Windows český jazyk a klávesnici. Pomocí následujícího příkazu lze zjistit, hexidecimální kód českého rozložení klávesnice (je to x00000405):

xfreerdp3 /list:kbd | grep Czech

V souboru ~/.config/winapps/winapps.conf pak přidejte /kbd:layout:x00000405 k RDP_FLAGS. U mě to vypadá takto (přidal jsem ještě +span):

RDP_FLAGS="/cert:tofu /sound /microphone +home-drive +span /kbd:layout:0x00000405

Po restartu Windows kontejneru by mělo české rozložení klávesnice fungovat.

9) Bonus 1: WinApps-Launcher

Určitě není pohodlné manuálně spouštět virtuální Windows přes Docker příkazy nebo přes Portainer. Proto to jde pohodlně z plochy pomocí WinApps-Launcher.

Instalace balíčku yad

Nainstalujte nbásledujícím příkazem:

sudo pacman -Syu --needed yad

Nastavení WINAPPS_SRC_DIR

Dále je třeba nastavit proměnnou prostředí WINAPPS_SRC_DIR v terminálu. Pokud jste WinApps nainstalovali pouze pro jednoho uživatele, hodnota bude ~/.local/bin/winapps-src, pokud pro celý systém, použijte /usr/local/bin/winapps-src. Nastavte přidáním tohoto řádku do souboru /etc/environment:

WINAPPS_SRC_DIR="$HOME/.local/bin/winapps-src"

Změna se projeví po restartu nebo při dalšímn přihlášení.

Zklonování projektu

Dalším krokem je zklonování WinApps-Launcheru do složky WinApps:

# Zklonování do WinApps adresáře
git clone https://github.com/winapps-org/winapps-launcher.git "${WINAPPS_SRC_DIR}/winapps-launcher"
# Nastavení spustitelnosti skriptu
sudo chmod +x "${WINAPPS_SRC_DIR}/winapps-launcher/winapps-launcher.sh"

Vytvoření zkratky

Vytvořte sopubor ~/.local/share/applications/winapps-launcher.desktop s následujícím obsahem:

[Desktop Entry]
Type=Application
Name=WinApps Launcher
Comment=Taskbar Launcher for WinApps
Exec="$WINAPPS_SRC_DIR/winapps-launcher/winapps-launcher.sh"
Icon=$WINAPPS_SRC_DIR/winapps-launcher/icons/LinkIcon.svg
Terminal=false
Categories=Utility

Pomocí již zmíněného programu Alacarte jí můžete nastavit i ikonu, kterou ve výchozím stavu nemá.

WinApps Launcher zkratka

Automatické spuštění

Pro automatické spouštění WinApps-Launcheru vytvořte soubor ~/.config/systemd/user/winapps-launcher.service:

[Unit]
Description=Run 'WinApps Launcher'
After=graphical-session.target default.target
Wants=graphical-session.target

[Service]
Type=simple
Environment="PATH=%h/.local/bin:%h/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment="LIBVIRT_DEFAULT_URI=qemu:///system"
Environment="SCRIPT_PATH=$WINAPPS_SRC_DIR/winapps-launcher/winapps-launcher.sh"
Environment="LANG=C"
ExecStart=/bin/bash -c "\\"\$SCRIPT_PATH\\""
ExecStopPost=/bin/bash -c 'echo "[SYSTEMD] WINAPPS LAUNCHER SERVICE EXITED."'
TimeoutStartSec=5
TimeoutStopSec=5
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

A spusťe službu:

systemctl --user enable winapps-launcher --now

Nyní budete mít mezi ikonkami spuštěných aplikací ikonu WinApps pro rychlý přístup k Windows a nainstalovaným programům:

Ano, na GNOME se to takhle hezky buguje a je atm černé pozadí.

10) Bonus 2: Debloat

V této poslední části se chci věnovat úpravě Windows. Kromě nastavení barevného schématu a popřípadě tapety chceme pro optimální výkon upravit některá nastavení nebo odinstalovat zbytečný "bloat" software, kterého je Windows notoricky plný.

Na to se hodí nástroje jako Win11Debloat nebo pro Windows 10 DisableWinTracking. Můžou zrychlit systém a zbaví vás zbytečných programů a sledovacích featurek.

Závěr

WinApps není dokonalý, napříkal jsem měl problém s přesouváním okna na druhý monitor, okna se zasekávají a podobně. Je ale stálě ve vývoji a je to skvělý způsob, jak spustit téměř nativně Windows aplikace na vaší oblíbené distribuci. Celkově je pro práci například s balíkem Office nebo Photoshopem dostačující.