Este script Bash automatiza completamente la habilitación e integración de compatibilidad con aplicaciones de Windows en sistemas Linux, incluyendo:
- Instalación de Wine y sus dependencias.
- Interfaz gráfica para Wine.
- Asociación automática de archivos .exe en el gestor de archivos.
- Generación automática de iconos (miniaturas) para ejecutables de Windows.
- Fuentes TrueType de Windows.
- Runtimes de Visual Basic,Visual C++, .NET Framework y .NET 6.0+
- DirectX y codecs de video.
- Librerías DLL específicas y componentes auxiliares.
- Acceso a la consola CMD de Windows
Con todos estos componentes instalados he podido ejecutar bajo Linux casi cualquier aplicación para Windows, la mayoría modernas, así como también video juegos antiguos que no son de Steam.
No van a funcionar absolutamente todas las aplicaciones de Windows, ya que por lo poco que sé Wine no soporta .NET Framework 4.x en su totalidad, y alguna aplicación puede solicitar librerías específicas que habría que copiar directamente desde una instalación de Windows a Linux, y luego registrar los archivos con regsvr32.exe en caso de ser necesario (y suerte intentando hacer que eso funcione), pero la mayoría de software que he probado ha funcionado correctamente sin hacer nada especial, incluyendo software compilado bajo .NET 8 y .NET 9 que apuntan a Windows.
El script ha sido probado en Xubuntu (XFCE) y Kubuntu (KDE).

(hacer click en la imagen para agrandar)
Cabe mencionar que, y según creo tener entendido, 'sudo' se puede configurar para que siempre pida contraseña cada vez que se invoca durante la misma sesión de la terminal, o que después de 1 minuto / un tiempo configurable se vuelva a pedir contraseña la próxima vez que se invoque, así que en esos casos pues el script no realizará un procedimiento totalmente automatizado...
Tras la instalación de todos estos componentes el script generará varios accesos directos y lanzadores en el escritorio de nuestro gestor de archivos (no sé si funcionará para todos) para abrir los componentes de Wine, la carpeta del disco "C:\" de Windows y la CMD, además, en caso de tener instalado el gestor de archivos Thunar también se generarán unas acciones personalizadas en el menú contextual del gestor para ejecutar un programa con Wine y también para abrir la CMD en el directorio actual o abrir el directorio en "Windows Explorer".
Todo esto con la finalidad de mejorar un poquito más la experiencia de integración con Wine.

(hacer click en la imagen para agrandar)
Nota: La instalación podría demorar entre 30~60 minutos aprox. dependiendo del hardware y la velocidad de conexión a Internet. En mi caso, usando una máquina virtual con el sistema operativo Xubuntu, con 6 GB de RAM y 4 núcleos, tarda unos 40 minutos. Y se requiere de aprox. 10 GB de espacio libre en disco para los archivos a instalar, además de archivos temporales adicionales que se descargan durante el procedimiento de instalación; El script elimina estos archivos temporales después de completar la instalación y el espacio total utilizado se reduce aprox. 2,50 GB, dejando unos 7,50 GB utilizados.
Tengan en cuenta que escribir este script me ha supuesto muchas horas de esfuerzo e investigación ya que no tengo experiencia con Bash (este es de mis primeros scripts) ni con Wine ni con Linux en general, así que he recurrido a ChatGPT en muchas ocasiones para armar hasta la línea de código más básica, a base de mucho ensayo y error (20% errores míos, 80% errores de esta IA inútil), y también horas de tediosa experimentación, ya que instalar un componente o una librería "equivocada" con winetricks supone que Wine se vaya al carajo y no funcione ningún ejecutable de Windows, lo cual me ha ocurrido varias veces... y vuelta a empezar de cero.
¿Mi motivación para escribir este script?, el simple capricho de poder usar WinRAR y otras aplicaciones para Windows que considero esenciales y sin un equivalente digno para Linux, sumado a mi cabezonería y el tiempo libre para experimentar.
El script de instalación:
Wine_Install.sh
Código:
#!/bin/bash
set -e
###############################################################################
# CONFIGURATION #
###############################################################################
DESKTOP_DIR="$(xdg-user-dir DESKTOP)"
###############################################################################
# FUNCTIONS #
###############################################################################
create_desktop_launcher() {
local EXEC_PATH="$1" # Path to executable or URL (required)
local APP_NAME="$2" # Display name of the app (required)
local COMMENT="${3:-}" # Comment/description (optional)
local ICON_PATH="${4:-}" # Path to icon file or URL (optional)
local TERMINAL="${5:-false}" # true or false to run in terminal (optional, default false)
local TYPE="${6:-Application}" # Desktop entry type (Application, Link, etc.) (optional)
local CATEGORIES="${7:-Utility;}" # Categories for the launcher (optional)
local ARGS="${8:-}" # Arguments for the executable (optional)
local DESKTOP_FILE="${9:-$DESKTOP_DIR/$APP_NAME.desktop}" # Path to .desktop file (optional)
# Validate required params
if [ -z "$EXEC_PATH" ] || [ -z "$APP_NAME" ]; then
echo "❌ Usage: create_desktop_launcher <exec_path> <app_name> [comment] [icon_path] [terminal:true|false] [type] [categories] [args] [desktop_file]"
return 1
fi
# Handle icon: if URL, download it to ~/.local/share/icons/<app_name>.png
if [[ "$ICON_PATH" == http* ]]; then
local ICON_DIR="$HOME/.local/share/icons"
mkdir -p "$ICON_DIR"
local SAFE_APP_NAME=$(echo "$APP_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')
local LOCAL_ICON_PATH="$ICON_DIR/$SAFE_APP_NAME.png"
if [ ! -f "$LOCAL_ICON_PATH" ]; then
# echo "⬇️ Downloading icon from URL: $ICON_PATH"
if command -v wget > /dev/null 2>&1; then
wget -qO "$LOCAL_ICON_PATH" "$ICON_PATH"
elif command -v curl > /dev/null 2>&1; then
curl -sL "$ICON_PATH" -o "$LOCAL_ICON_PATH"
else
echo "❌ Neither wget nor curl found. Cannot download icon for desktop launcher."
# return 1
fi
if [ ! -f "$LOCAL_ICON_PATH" ]; then
echo "❌ Icon download failed for desktop launcher. Check your internet connection or URL."
# return 1
fi
fi
ICON_PATH="$LOCAL_ICON_PATH"
fi
# Write .desktop file
{
echo "[Desktop Entry]"
echo "Name=$APP_NAME"
[ -n "$COMMENT" ] && echo "Comment=$COMMENT"
echo "Exec=$EXEC_PATH $ARGS"
[ -n "$ICON_PATH" ] && echo "Icon=$ICON_PATH"
echo "Terminal=$TERMINAL"
echo "Type=$TYPE"
echo "Categories=$CATEGORIES"
} > "$DESKTOP_FILE"
}
create_thunar_custom_action() {
local UCA_FILE="$HOME/.config/Thunar/uca.xml"
local UNIQUE_ID="$1"
local ICON="$2"
local NAME="$3"
local SUBMENU="$4"
local COMMAND="$5"
local DESCRIPTION="$6"
local RANGE="$7"
local PATTERNS="$8"
local EXTRA_TAGS="${9}"
if [ ! -f "$UCA_FILE" ]; then
sudo mkdir -p "$(dirname "$UCA_FILE")"
echo '<?xml version="1.0" encoding="UTF-8"?>
<actions>
</actions>' > "$UCA_FILE"
# echo "✨ Created new uca.xml configuration file."
fi
if grep -q "<unique-id>$UNIQUE_ID</unique-id>" "$UCA_FILE"; then
# echo "⚠️ Custom Action '$NAME' already exists in Thunar."
return
fi
local ACTION_BLOCK=" <action>
<icon>$ICON</icon>
<name>$NAME</name>
<submenu>$SUBMENU</submenu>
<unique-id>$UNIQUE_ID</unique-id>
<command>$COMMAND</command>
<description>$DESCRIPTION</description>
<range>$RANGE</range>
<patterns>$PATTERNS</patterns>"
if [ -n "$EXTRA_TAGS" ]; then
ACTION_BLOCK="${ACTION_BLOCK}
$EXTRA_TAGS"
fi
ACTION_BLOCK="${ACTION_BLOCK}
</action>"
awk -v block="$ACTION_BLOCK" '
/<\/actions>/ {
print block
}
{ print }
' "$UCA_FILE" > "$UCA_FILE.tmp" && mv "$UCA_FILE.tmp" "$UCA_FILE"
# echo "✅ Custom Action '$NAME' added successfully to Thunar."
}
###############################################################################
# MAIN SCRIPT EXECUTION #
###############################################################################
echo "ℹ️ INFO: This script will install Wine and required components and tools"
echo " to integrate and run Windows applications on your Linux system."
echo ""
echo "⚠️ About 10 GB of free space is required to download and install all componentes."
echo " The installation may take approximately 40~60 minutes."
echo
echo -n "Do you want to continue? [Y/N]: "
while true; do
read -n1 confirm
echo
if [[ -z "$confirm" || "$confirm" =~ ^[Yy]$ ]]; then
break
elif [[ "$confirm" =~ ^[Nn]$ ]]; then
echo "❌ Operation cancelled."
exit 1
else
echo "⚠️ Invalid option. Please press Y or N."
fi
done
clear
echo "🛠️ Adding support for 32-bit architecture and packages (required to install wine32)..."
sudo dpkg --add-architecture i386
echo -e "\n🔄 Updating package list to fetch latest info..."
sudo apt-get update
echo -e "\n🍷 Installing Wine (wine32, wine64), required to run Windows apps on Linux..."
# https://www.winehq.org/
sudo apt-get install --install-recommends -y wine wine32 wine64 libwine fonts-wine
echo -e "\n🍷 Installing Qt GUI for Wine..."
# https://github.com/brezerk/q4wine
sudo apt-get install --install-recommends -y q4wine
echo -e "\n🍷 Installing Winbind, required for Windows user authentication integration with Wine..."
# https://www.samba.org/samba/docs/current/man-html/winbindd.8.html
sudo apt-get install -y winbind
echo -e "\n🍷 Installing WineTricks for automatic installation of Windows runtimes and libraries with Wine..."
# https://github.com/Winetricks/winetricks
sudo apt-get install --install-recommends -y winetricks
# Installs latest winetricks script, allowing later dotnetdesktop8 and dotnetdesktop9 runtime installation.
# https://github.com/Winetricks/winetricks/issues/2178#issuecomment-2299877869
yes | sudo winetricks --self-update # Use sudo, it requires @root permissions to self update.
echo -e "\n🍷 Installing wine-binfmt, which causes Wine to be invoked automatically whenever a Windows .exe file is to be launched..."
# https://packages.debian.org/sid/wine-binfmt
# https://binfmt-support.nongnu.org/
sudo apt-get install -y wine-binfmt binfmt-support
if command -v thunar >/dev/null 2>&1; then
echo -e "\n📦 Installing Tumbler and its plugins to enable thumbnail generation for various file types in Thunar file manager."
# https://docs.xfce.org/xfce/thunar/4.14/tumbler
# https://packages.debian.org/sid/xfce/tumbler-plugins-extra
sudo apt-get install -y tumbler tumbler-plugins-extra
fi
echo -e "\n📦 Installing icoextract-thumbnailer (exe-thumbnailer), which generates thumbnail previews for Windows .exe files in your file manager..."
# https://github.com/jlu5/icoextract?tab=readme-ov-file#installing-from-source
sudo apt-get install --install-recommends -y icoextract-thumbnailer
echo -e "\n🆕 Creating file: '/usr/local/share/thumbnailers/exe-thumbnailer.thumbnailer' with thumbnail previews configuration for Windows PE files..."
# https://github.com/jlu5/icoextract/blob/master/exe-thumbnailer.thumbnailer
sudo mkdir -p "/usr/local/share/thumbnailers/" && {
if [ ! -f "/usr/local/share/thumbnailers/exe-thumbnailer.thumbnailer" ]; then
sudo tee "/usr/local/share/thumbnailers/exe-thumbnailer.thumbnailer" > /dev/null << EOF
[Thumbnailer Entry]
Exec=exe-thumbnailer -v -s %s %i %o
MimeType=application/x-ms-dos-executable;application/x-dosexec;application/x-msdownload;application/vnd.microsoft.portable-executable
EOF
fi
}
echo -e "\n🧹 Removing existing Wine configuration in '~/.wine' (if any)..."
rm -rf ~/.wine
echo -e "\n🆕 Creating new Wine configuration with Windows 10 settings..."
sudo WINEPREFIX="/root/.wine" wine-stable winecfg -v win10
WINEPREFIX=~/.wine wine-stable winecfg -v win10
echo -e "\n🅰️ Installing Microsoft Windows fonts for better app compatibility..."
winetricks --unattended corefonts calibri cambria consolas uff
echo -e "\n⚙️ Installing Microsoft Windows runtimes..."
winetricks --unattended vb6run
winetricks --unattended vcrun6sp6 vcrun2005 vcrun2008 vcrun2010 vcrun2012 vcrun2013
winetricks --unattended --force vcrun2022 # Force installation due installer file checksum missmatch.
{
winetricks --unattended dotnet48
# These registry keys forces all .NET Framework assemblies to run on the latest installed CLR (i.e., dotnet48)
# It also solves issue: https://bugs.winehq.org/show_bug.cgi?id=41727#c5
wine reg add "HKLM\\Software\\Microsoft\\.NETFramework" /v "OnlyUseLatestCLR" /t "REG_DWORD" /d "0001" /f
wine reg add "HKLM\\Software\\WOW6432Node\\Microsoft\\.NetFramework" /v "OnlyUseLatestCLR" /t "REG_DWORD" /d "0001" /f
}
winetricks --unattended dotnetdesktop6 dotnetdesktop7
# .NET 8 and .NET 9 are available only from latest winetricks release which we got with 'winetricks --self-update' command.
winetricks --unattended dotnetdesktop8 dotnetdesktop9
echo -e "\n🎥 Installing codecs for media playback (also useful for Windows video games)..."
winetricks --unattended cinepak directshow ffdshow l3codecx openal
echo -e "\n📚 Installing essential Microsoft Windows libraries..."
winetricks --unattended cabinet crypt32 dbghelp gdiplus hid iertutil msacm32 msxml6 \
ole32 oleaut32 setupapi uiribbon urlmon webio wininet
echo -e "\n🖥️ Installing DirectX runtimes and APIs for graphics and gaming..."
winetricks --unattended d3dx9 d3dx10 dxdiag d3drm d3dxof dx8vb dxtrans \
devenum dinput8 directmusic directplay mdx sdl
echo -e "\n🖥️ Installing Vulkan APIs for advanced graphics support..."
winetricks --unattended dxvk vkd3d
echo -e "\n💾 Installing Microsoft Windows CMD..."
winetricks --unattended cmd
echo -e "\n🔄 Restoring Wine configuration to Windows 10 settings..."
wine winecfg -v win10
echo -e "\n🧹 Cleaning winetricks cache folder in '~/.cache/winetricks'..."
rm -rf ~/.cache/winetricks/*
echo -e "\n🚀 Creating desktop link: 'Wine (C:\)'..."
if command -v dolphin >/dev/null 2>&1; then
WINE_DIR_ICON="folder-windows-symbolic"
else
WINE_DIR_ICON="wine"
fi
printf '%s\n' \
"[Desktop Entry]" \
"Type=Link" \
'Name=Wine (C:\\)' \
"Icon=$WINE_DIR_ICON" \
"URL=file://$HOME/.wine/drive_c" \
> "$DESKTOP_DIR/wine-open-drive_c.desktop"
echo -e "\n🚀 Creating desktop launcher: 'Wine Configuration'..."
create_desktop_launcher \
"wine-stable winecfg" \
"Wine Configuration" \
"Launch Wine Configuration" \
"wine-stable" \
"false" \
"Application" \
"Utility;" \
"" \
"$DESKTOP_DIR/wine-configuration.desktop"
echo -e "\n🚀 Creating desktop launcher: 'Qt GUI for Wine'..."
create_desktop_launcher \
"q4wine" \
"Qt GUI for Wine" \
"Launch Qt GUI for Wine" \
"q4wine" \
"false" \
"Application" \
"Utility;" \
"" \
"$DESKTOP_DIR/qt-gui-for-wine.desktop"
echo -e "\n🚀 Creating desktop launcher: 'Winetricks'..."
create_desktop_launcher \
"winetricks --gui" \
"Winetricks" \
"Launch Winetricks with GUI" \
"winetricks" \
"false" \
"Application" \
"Utility;" \
"" \
"$DESKTOP_DIR/winetricks.desktop"
if command -v thunar >/dev/null 2>&1; then
CMD_EXEC="xfce4-terminal --title=\"CMD\" --color-bg=#000000 --color-text=#FFFFFF -e 'sudo wine-stable cmd.exe'"
CMD_RUN_IN_TERMINAL=true
elif command -v dolphin >/dev/null 2>&1; then
CMD_EXEC="konsole --hold -e sudo wine-stable cmd.exe"
CMD_RUN_IN_TERMINAL=false
fi
if [[ -n "$CMD_EXEC" ]]; then
echo -e "\n🚀 Creating desktop launcher: 'CMD'..."
create_desktop_launcher \
"$CMD_EXEC" \
"CMD" \
"Launch Microsoft Windows CMD as root" \
"https://upload.wikimedia.org/wikipedia/commons/7/7b/CMD-Icon_%28small%29.png" \
$CMD_RUN_IN_TERMINAL \
"Application" \
"Utility;" \
"" \
"$DESKTOP_DIR/cmd.desktop"
fi
if command -v thunar >/dev/null 2>&1; then
echo -e "\n🚀 Creating Thunar custom action: 'Run with Wine'..."
create_thunar_custom_action \
"wine-run-with-wine" \
"wine" \
"Run with Wine" \
"" \
"wine-stable %f" \
"Run a Microsoft Windows executable with Wine" \
"*" \
"*.exe" \
"<other-files/>"
echo -e "\n🚀 Creating Thunar custom action: 'Run with Wine (Terminal)'..."
create_thunar_custom_action \
"wine-run-with-wine-terminal" \
"wine" \
"Run with Wine (Terminal)" \
"" \
"xfce4-terminal --hold -e "wine-stable %f"" \
"Run a Microsoft Windows executable with Wine (Terminal)" \
"*" \
"*.exe" \
"<other-files/>"
echo -e "\n🚀 Creating Thunar custom action: 'Open CMD here'..."
create_thunar_custom_action \
"wine-open-cmd-here" \
"cmd" \
"Open CMD here" \
"" \
"sudo xfce4-terminal --title="CMD" --color-bg=#000000 --color-text=#FFFFFF -e "wine start /wait /b /d %f cmd"" \
"Open a Windows CMD in the current directory" \
"*" \
"*" \
"<directories/>"
echo -e "\n🚀 Creating Thunar custom action: 'Open in Explorer (Wine)'..."
create_thunar_custom_action \
"wine-open-in-explorer" \
"folder" \
"Open in Explorer (Wine)" \
"" \
"wine-stable explorer %f" \
"Open the current directory in Explorer (Wine)" \
"*" \
"*" \
"<directories/>"
fi
echo -n -e "\n🏁 Operation completed."
echo
read -n1 -r -s -p "Press any key to finish..."
echo
exit
Adicionalmente, recomiendo utilizar estos comandos para instalar los runtimes de .NET 8 y 9 en Linux:
Código:
sudo apt install -y dotnet-runtime-8.0
sudo apt install -y dotnet-runtime-9.0
He preferido no incluir la instalación de estos runtimes en el script por que son parte del soporte nativo en Linux para aplicaciones .NET 8 y .NET 9 que apuntan a Linux; No tienen relación ni influencia sobre Wine. El script ya instala los respectivos runtimes de .NET 8 y 9 dentro de su entorno para poder ejecutar con Wine los binarios de .NET 8 y 9 que apuntan a Windows.
Por último, comparto este script para revertir la instalación de Wine y sus componentes:
Wine_Uninstall.sh
Código:
#!/bin/bash
###############################################################################
# MAIN SCRIPT EXECUTION #
###############################################################################
echo "⚠️ WARNING: This script will uninstall Wine and related components, directories, caches and configurations COMPLETELY."
echo
echo -n "Do you want to continue? [Y/N]: "
while true; do
read -n1 confirm
echo
if [[ -z "$confirm" || "$confirm" =~ ^[Yy]$ ]]; then
break
elif [[ "$confirm" =~ ^[Nn]$ ]]; then
echo "❌ Operation cancelled."
exit 1
else
echo "⚠️ Invalid option. Please press Y or N."
fi
done
clear
# Remove wine directory, including "drive_c" and its contents.
WINEPREFIX="/root/.wine" winetricks --unattended annihilate
WINEPREFIX="$HOME/.wine" winetricks --unattended annihilate
sudo rm -rf "/root/.wine"
rm -rf "$HOME/.wine"
rm -rf "$HOME/.cache/winetricks"
# Remove packages that are part of Wine or strictly related to.
sudo apt-get remove --purge -y wine wine32 wine64 libwine fonts-wine \
q4wine winetricks wine-binfmt
# Remove auxiliary packages that are not strictly tied to Wine but are "safe" to remove.
sudo apt-get remove --purge -y binfmt-support winbind \
samba-common samba-common-bin samba-dsdb-modules
# Additional package cleanup.
sudo apt-get autoremove -y
sudo apt-get clean
echo -e "\n🏁 Operation completed."
read -n1 -r -s -p "Press any key to finish..."
echo
exit 0
⚠️ Este script de desinstalación eliminará por completo el directorio de Windows (~/.wine) y todo lo que haya en él, sin embargo, no revierte por completo todos los paquetes instalados previamente por el script del instalador de Wine, en parte por que me parece peligroso forzar la desinstalación de ciertos paquetes relacionados con gtk que se instalaron por parte del paquete q4wine con el parámetro --install-recommends, entre otros paquetes recomendados que se instalan relacionados con Python, ya que todo eso podría depender de otros paquetes que el usuario tuviera instalado anteriormente, así que solo desinstala los paquetes estrictamente relacionados con Wine y los que considero que prácticamente nadie estará utilizando para otras cosas: binfmt-support, winbind, samba*
Revisen los paquetes que este script desinstala antes de usarlo. No me hago responsable.