Issue with Windows App Support

Pardon me for being blunt, but is this app proprietary? The reason I ask is because I can't find anything online about this app. It says it installs wine and bottles, but there's nothing online to verify that that's all it does. No source code, no links to download and inspect it, nothing on Zorin's GitHub page, nada.

I'm not implying that the Zorin team is doing anything malicious, but I also want to know, specifically, what this app is actually doing. I want to inspect the source code, and maybe even improve upon it if I can.

So, Zorin team, is the Windows App Support app open source and available for us to inspect, or is it proprietary and we should simply just take your word for it that it's safe to use on our systems?

Asking for a friend.

Thanks.

Decided to inspect the app in terminal, then took all the information and made a python script to replicate the installation process. Now you can use Windows App Support on any Linux Distro not exclusive to Zorin OS.

Enjoy!


"""
This script replicates the full logic of the Zorin "Windows App Support"
feature on any Debian-based distribution (like LMDE).

It performs two main actions based on my package audit:

1.  INSTALLATION:
    - Replicates the 'zorin-windows-app-support' meta-package.
    - Installs 'wine' and 'flatpak' using apt.
    - Replicates the 'zorin-windows-app-support.postinst' script.
    - Adds the Flathub remote.
    - Installs 'com.usebottles.bottles' from Flathub.

2.  CONFIGURATION:
    - Replicates the 'zorin-windows-app-support-desktop-files' package.
    - Creates a custom .desktop file for Bottles.
    - This file includes the crucial 'MimeType=' line to associate
      .exe and .msi files with Bottles, creating the "native" launch feel.

This script MUST be run with sudo privileges (e.g., "sudo python3 ...").
"""

import subprocess
import time
import sys
import os

# --- Part 1: Installation Logic ---

def check_root():
    """Check if the script is running as root."""
    if os.geteuid() != 0:
        print("This script must be run as root (use 'sudo').")
        print("Aborting.")
        sys.exit(1)
    print("Running with root privileges...")

def run_command(cmd, description):
    """Helper function to run a system command and print its status."""
    print(f"[+] Starting: {description}...")
    try:
        subprocess.run(cmd, shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        print(f"[✔] Success: {description}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"[!] Error: {description} failed.")
        print(f"    Details: {e}")
        return False
    except FileNotFoundError as e:
        print(f"[!] Error: A command was not found (e.g., apt, flatpak).")
        print(f"    Details: {e}")
        return False

def install_apt_dependencies():
    """Replicates the 'Depends:' and 'Recommends:' from the meta-package."""
    print("\n--- Phase 1: Installing APT Dependencies (Wine & Flatpak) ---")
    
    if not run_command("apt-get update", "Update apt cache"):
        print("[!] Could not update apt cache. Aborting.")
        sys.exit(1)
    
    # This is the equivalent of the meta-package's dependencies
    cmd = "apt-get install -y wine flatpak"
    description = "Install apt dependencies (wine and flatpak)"
    if not run_command(cmd, description):
        print("[!] Could not install apt dependencies. Aborting.")
        sys.exit(1)

def install_bottles_with_retry(max_retries=5):
    """A direct Python translation of the '.postinst' script logic."""
    print("\n--- Phase 2: Installing Bottles from Flathub ---")
    
    # 1. Add the Flathub remote (from .postinst)
    cmd_remote = "flatpak remote-add --if-not-exists --system flathub https://dl.flathub.org/repo/flathub.flatpakrepo"
    description_remote = "Add Flathub remote"
    run_command(cmd_remote, description_remote) # Don't abort on failure, it might exist

    # 2. Install Bottles (from .postinst)
    cmd_install = "flatpak install --system --noninteractive flathub com.usebottles.bottles//stable"
    description_install = "Install Bottles from Flathub"

    # This 'for' loop replicates the retry logic
    for attempt in range(max_retries):
        print(f"--> Attempt {attempt + 1} of {max_retries} to install Bottles...")
        if run_command(cmd_install, description_install):
            print("[✔] Successfully installed Bottles.")
            return True # Success
        
        if attempt < max_retries - 1:
            print(f"    Install failed. Retrying in 5 seconds...")
            time.sleep(5) 

    print("[!] Fatal: Failed to install Bottles after {max_retries} attempts.")
    return False # Failure

# --- Part 2: Configuration Logic ---

# This is the content of the .desktop file I found.
# The most important line is 'MimeType=...'
DESKTOP_FILE_CONTENT = """
[Desktop Entry]
Name=Bottles
Comment=Run Windows Software
Icon=com.usebottles.bottles
Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=bottles --file-forwarding com.usebottles.bottles @@u %u @@
Terminal=false
Type=Application
Categories=Application;Wine;
StartupNotify=true
StartupWMClass=bottles
MimeType=x-scheme-handler/bottles;application/x-ms-dos-executable;application/x-msi;application/x-ms-shortcut;application/x-wine-extension-msp;
Keywords=wine;windows;
X-Flatpak=com.usebottles.bottles

# --- Begin translations (copied from Zorin file) ---
Name[it]=Bottles
Name[fr]=Bouteilles
Name[de]=Bottles
Name[hi]=Bottles
Name[pt]=Bottles
Name[es]=Botellas
Name[nb_NO]=Flasker
Name[pt_BR]=Bottles
Name[id]=Bottles
Name[nl]=Bottles
Name[tr]=Şişeler
Name[sv]=Bottles
Name[ru]=Bottles
Name[eo]=Boteloj
Name[zh_Hans]=Bottles
Name[fi]=Pullot
Name[ja]=Bottles
Name[hr]=Butelje
Name[cs]=Láhve
Name[uk]=Bottles
Name[hu]=Palackok
Name[pl]=Bottles
Name[zh_Hant]=Bottles
Name[ko]=Bottles
Name[vi]=Bottles
Name[eu]=Bottles
Name[bg]=„Bottles“
Name[el]=Bottles
Name[gl]=Botellas
Name[sk]=Fľaše
Name[ro]=Sticle
Name[ms]=Botol
Name[ckb]=بۆتڵز
Name[fa]=بطری‌ها
Name[th]=ขวด
Name[ar]=القوارير
Name[bn]=Bottles
Name[sl]=Steklenice
Name[ca]=Bottles
Name[lt]=Bottles
Name[sr]=Флаше
Name[ta]=பாட்டில்கள்
Name[ie]=Botelles
Comment[fr]=Exécutez des logiciels Windows
Comment[es]=Ejecute software de Windows
Comment[pt_BR]=Execute programas do Windows
Comment[nl]=Voer Windows-software uit
Comment[tr]=Windows yazılımlarını çalıştırın
Comment[ru]=Запуск программ Windows
Comment[zh_Hans]=运行 Windows 軟件
Comment[fi]=Suorita Windows-ohjelmistoja
Comment[ja]=Windowsソフトウェアを実行します
Comment[cs]=Spuštění softwaru systému Windows
Comment[uk]=Запуск програм Windows
Comment[hu]=Windows szoftverek futtatása
Comment[zh_Hant]=執行 Windows軟體
Comment[bg]=Използвайте софтуер за „Windows“
Comment[ro]=Folosește programe pentru Windows
Comment[ar]=شغِّل برامج ويندوز
Comment[ta]=விண்டோஸ் மென்பொருளை இயக்கவும்
Comment[ie]=Executer programmas por Windows
Keywords[it]=wine;windows;
Keywords[fr]=wine;windows;
Keywords[de]=Wine;Windows;
Keywords[hi]=wine;windows;
Keywords[pt]=wine;windows;
Keywords[es]=wine;windows;
Keywords[nb_NO]=WINE;Windows;
Keywords[pt_BR]=wine;windows;
Keywords[id]=wine;windows;
Keywords[nl]=wine;windows;
Keywords[tr]=wine;windows;
Keywords[sv]=wine;windows;
Keywords[ru]=wine;windows;
Keywords[eo]=wine;windows;
Keywords[zh_Hans]=wine;windows;
Keywords[fi]=wine;windows;
Keywords[ja]=wine;windows;
Keywords[hr]=wine;windows;
Keywords[cs]=wine;windows;
Keywords[uk]=wine;windows;
Keywords[hu]=wine;windows
Keywords[pl]=wine;windows;
Keywords[zh_Hant]=wine;windows;
Keywords[ko]=wine;windows;
Keywords[vi]=wine;windows;
Keywords[eu]=wine;windows;
Keywords[bg]=wine;windows;
Keywords[el]=wine;windows;
Keywords[gl]=wine;windows;
Keywords[sk]=wine;windows;
Keywords[ro]=wine;windows;
Keywords[ms]=wine;windows;
Keywords[ckb]=واین؛ویندۆز;
Keywords[fa]=wine؛ویندوز؛
Keywords[th]=wine;windows;
Keywords[ar]=wine;windows;
Keywords[bn]=ওয়াইন;উইন্ডোজ;
Keywords[ca]=wine;windows;
Keywords[lt]=wine;windows;
Keywords[sr]=вајн;виндовс;
Keywords[et]=wine;windows;
Keywords[ta]=ஒயின்;விண்டோஸ்;
Keywords[ie]=wine;windows;
"""

def create_mimetype_override():
    """
    This is the "Zorin Magic".
    
    We create a custom .desktop file in a high-priority location.
    This file's 'MimeType=' line tells the system to use Bottles
    to open .exe and .msi files, replicating the Zorin experience.
    """
    print("\n--- Phase 3: Configuring MimeType Association (The Zorin Magic) ---")
    
    # We use '/usr/local/share/applications/'. This is the standard
    # directory for system-wide admin overrides. It will take
    # precedence over the default .desktop file provided by Flatpak.
    
    desktop_file_dir = "/usr/local/share/applications"
    desktop_file_path = os.path.join(desktop_file_dir, "com.usebottles.bottles.desktop")
    
    try:
        # Create the directory if it doesn't exist
        print(f"[+] Ensuring directory exists: {desktop_file_dir}")
        os.makedirs(desktop_file_dir, exist_ok=True)
        
        # Write the custom .desktop file
        print(f"[+] Writing custom .desktop file to: {desktop_file_path}")
        with open(desktop_file_path, "w") as f:
            f.write(DESKTOP_FILE_CONTENT)
        
        print("[✔] Success: Created custom launcher file.")

    except Exception as e:
        print(f"[!] Error: Failed to write .desktop file.")
        print(f"    Details: {e}")
        return False
        
    # Finally, update the system's MimeType database
    run_command(f"update-desktop-database {desktop_file_dir}", "Update desktop application database")
    return True

# --- Main Execution ---

def main():
    """Run the full installation and configuration process."""
    print("--- Replicating Zorin 'Windows App Support' ---")
    
    check_root()
    
    # Run Installation Steps
    install_apt_dependencies()
    if not install_bottles_with_retry():
        print("[!] Failed to install Bottles. Aborting configuration.")
        sys.exit(1)
        
    # Run Configuration Step
    if create_mimetype_override():
        print("\n--- All Steps Complete ---")
        print("[✔] Wine, Flatpak, and Bottles are installed.")
        print("[✔] MimeType for .exe and .msi files is now associated with Bottles.")
        print("\nYou should now be able to double-click a .exe installer to run it.")
    else:
        print("\n--- Installation complete, but Configuration Failed ---")
        print("[!] Wine, Flatpak, and Bottles are installed.")
        print("[!] Failed to create the MimeType association.")
        print("    You can still use Bottles, but you'll have to launch it manually.")

if __name__ == "__main__":
    main()

In this, I believe you answered your own question.
It is a metapackage, not an application.