mirror of
https://github.com/winapps-org/winapps.git
synced 2025-06-06 07:07:18 +02:00
Merge branch 'main' into feat-nix-packaging
This commit is contained in:
commit
b7b5b34b27
58
README.md
58
README.md
@ -2,7 +2,7 @@
|
|||||||
<p align="center"><img align="center" width="700" src="./icons/banner_dark.svg#gh-light-mode-only"/></p>
|
<p align="center"><img align="center" width="700" src="./icons/banner_dark.svg#gh-light-mode-only"/></p>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
Run Windows applications (including [Microsoft 365](https://www.microsoft365.com/) and [Adobe Creative Cloud](https://www.adobe.com/creativecloud.html)) on GNU/Linux with `KDE`, `GNOME` or `XFCE`, integrated seamlessly as if they were native to the OS.
|
Run Windows applications (including [Microsoft 365](https://www.microsoft365.com/) and [Adobe Creative Cloud](https://www.adobe.com/creativecloud.html)) on GNU/Linux with `KDE Plasma`, `GNOME` or `XFCE`, integrated seamlessly as if they were native to the OS.
|
||||||
|
|
||||||
<p align="center"><img src="./demo/demo.png" width=1000 alt="WinApps Demonstration."></p>
|
<p align="center"><img src="./demo/demo.png" width=1000 alt="WinApps Demonstration."></p>
|
||||||
|
|
||||||
@ -284,33 +284,25 @@ The following guides are available:
|
|||||||
|
|
||||||
If you already have a Windows VM or server you wish to use with WinApps, you will need to merge `install/RDPApps.reg` into the Windows Registry manually.
|
If you already have a Windows VM or server you wish to use with WinApps, you will need to merge `install/RDPApps.reg` into the Windows Registry manually.
|
||||||
|
|
||||||
### Step 2: Clone WinApps Repository and Dependencies
|
### Step 2: Install Dependencies
|
||||||
1. Clone the WinApps GitHub repository.
|
Install the required dependencies.
|
||||||
```bash
|
- Debian/Ubuntu:
|
||||||
git clone --recurse-submodules --remote-submodules https://github.com/winapps-org/winapps.git && cd winapps
|
```bash
|
||||||
```
|
sudo apt install -y dialog freerdp3-x11 iproute2 libnotify-bin netcat
|
||||||
|
```
|
||||||
2. Install the required dependencies.
|
- Fedora/RHEL:
|
||||||
- Debian/Ubuntu:
|
```bash
|
||||||
```bash
|
sudo dnf install -y dialog freerdp iproute libnotify nmap-ncat
|
||||||
sudo apt install -y dialog freerdp3-x11 iproute2 libnotify-bin netcat
|
```
|
||||||
```
|
- Arch Linux:
|
||||||
- Fedora/RHEL:
|
```bash
|
||||||
```bash
|
sudo pacman -Syu --needed -y dialog freerdp iproute2 libnotify
|
||||||
sudo dnf install -y dialog freerdp iproute libnotify nmap-ncat
|
gnu-netcat
|
||||||
```
|
```
|
||||||
- Arch Linux:
|
- Gentoo Linux:
|
||||||
```bash
|
```bash
|
||||||
sudo pacman -Syu --needed -y dialog freerdp iproute2 libnotify gnu-netcat
|
sudo emerge --ask=n sys-libs/dialog net-misc/freerdp:3 net-misc/iproute2 x11-libs/libnotify net-analyzer/netcat
|
||||||
```
|
```
|
||||||
- Gentoo Linux:
|
|
||||||
```bash
|
|
||||||
sudo emerge --ask=n sys-libs/dialog net-misc/freerdp:3 net-misc/iproute2 x11-libs/libnotify net-analyzer/netcat
|
|
||||||
```
|
|
||||||
|
|
||||||
- `Docker Engine`: https://docs.docker.com/engine/install/
|
|
||||||
- `Podman`: https://podman.io/docs/installation
|
|
||||||
- `podman-compose`: https://github.com/containers/podman-compose
|
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> WinApps requires `FreeRDP` version 3 or later. If not available for your distribution through your package manager, you can install the [Flatpak](https://flathub.org/apps/com.freerdp.FreeRDP).
|
> WinApps requires `FreeRDP` version 3 or later. If not available for your distribution through your package manager, you can install the [Flatpak](https://flathub.org/apps/com.freerdp.FreeRDP).
|
||||||
@ -443,10 +435,10 @@ FREERDP_COMMAND=""
|
|||||||
### Step 4: Run the WinApps Installer
|
### Step 4: Run the WinApps Installer
|
||||||
Run the WinApps installer.
|
Run the WinApps installer.
|
||||||
```bash
|
```bash
|
||||||
./installer.sh
|
bash <(curl https://raw.githubusercontent.com/winapps-org/winapps/main/setup.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
A list of supported additional arguments can be accessed by running `./installer.sh --help`.
|
A list of supported additional arguments can be accessed by running `./setup.sh --help`.
|
||||||
|
|
||||||
<img src="./demo/installer.gif" width=1000 alt="WinApps Installer Animation.">
|
<img src="./demo/installer.gif" width=1000 alt="WinApps Installer Animation.">
|
||||||
|
|
||||||
@ -461,15 +453,15 @@ Adding your own applications with custom icons and MIME types to the installer i
|
|||||||
WinApps offers a manual mode for running applications that were not configured by the WinApps installer. This is completed with the `manual` flag. Executables that are in the Windows PATH do not require full path definition.
|
WinApps offers a manual mode for running applications that were not configured by the WinApps installer. This is completed with the `manual` flag. Executables that are in the Windows PATH do not require full path definition.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/winapps manual "C:\my\directory\executableNotInPath.exe"
|
winapps manual "C:\my\directory\executableNotInPath.exe"
|
||||||
./bin/winapps manual executableInPath.exe
|
winapps manual executableInPath.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
## Updating WinApps
|
## Updating WinApps
|
||||||
The installer can be run multiple times. To update your installation of WinApps:
|
The installer can be run multiple times. To update your installation of WinApps:
|
||||||
1. Run the WinApps installer to remove WinApps from your system.
|
1. Run the WinApps installer to remove WinApps from your system.
|
||||||
2. Pull the latest changes from the WinApps GitHub repository.
|
2. Pull the latest changes from the WinApps GitHub repository.
|
||||||
3. Re-install WinApps using the WinApps installer.
|
3. Re-install WinApps using the WinApps installer by running `winapps-setup`.
|
||||||
|
|
||||||
## Installation using Nix
|
## Installation using Nix
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ docker compose --file ~/.config/winapps/compose.yaml up
|
|||||||
> Since no Windows user password is set by default, Windows may automatically log in, which may cause the WinApps installation to fail due to complications establishing an RDP connection. To avoid this issue, please use the VNC connection to ensure that the Windows user is logged out before starting the WinApps installation.
|
> Since no Windows user password is set by default, Windows may automatically log in, which may cause the WinApps installation to fail due to complications establishing an RDP connection. To avoid this issue, please use the VNC connection to ensure that the Windows user is logged out before starting the WinApps installation.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./installer.sh
|
bash <(curl https://raw.githubusercontent.com/winapps-org/winapps/main/setup.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Changing `compose.yaml`
|
### Changing `compose.yaml`
|
||||||
|
@ -52,6 +52,19 @@ Together, these components form a powerful and flexible virtualization stack, wi
|
|||||||
sudo reboot # Reboot the system to ensure the user is added to the relevant groups.
|
sudo reboot # Reboot the system to ensure the user is added to the relevant groups.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: Due to a known bug in `rpm-ostree`, which affects various distributions such as Silverblue, Bazzite, Bluefin, Kinoite, Aurora, UCore, and others, the commands provided earlier may not properly add your user to all required groups. If the `groups $USER` command does not show your user as being part of the necessary groups, you'll need to manually add these groups to `/etc/group` if they are present in `/usr/lib/group`.
|
||||||
|
|
||||||
|
To resolve this:
|
||||||
|
1. Identify which groups are missing from the output of `groups $USER`.
|
||||||
|
2. Use the following snippet to add each missing group to `/etc/group`. Ensure you replace "kvm" with the name of the missing group.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep -E '^kvm:' /usr/lib/group | sudo tee -a /etc/group
|
||||||
|
sudo usermod -aG kvm $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Reboot your system to ensure that the user is correctly added to the relevant groups.
|
||||||
|
|
||||||
6. If relevant to your distribution, disable `AppArmor` for the `libvirt` daemon.
|
6. If relevant to your distribution, disable `AppArmor` for the `libvirt` daemon.
|
||||||
``` bash
|
``` bash
|
||||||
sudo ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/ # Disable AppArmor for the libvirt daemon by creating a symbolic link.
|
sudo ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/ # Disable AppArmor for the libvirt daemon by creating a symbolic link.
|
||||||
@ -583,21 +596,20 @@ Once you get to the point of selecting the location for installation, you will s
|
|||||||
<img src="./libvirt_images/20.png" width="700px"/>
|
<img src="./libvirt_images/20.png" width="700px"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
The next hurdle will be bypassing the network selection screen. As the `VirtIO` drivers
|
The next hurdle will be bypassing the network selection screen. As the `VirtIO` drivers for networking have not yet been loaded, the virtual machine will not be able to be connected to the internet.
|
||||||
for networking have not yet been loaded, the virtual machine will not be able to be connected to the internet.
|
- For Windows 11: When prompted to select your country or region, press "Shift + F10" to open the command prompt. Enter `OOBE\BYPASSNRO` and press Enter. The system will restart, allowing you to select "I don't have internet" later on. It is crucial to run this command as soon as possible, as doing so later in the installation process will not work, and you may be required to create a Microsoft account despite not having an internet connection.
|
||||||
- For Windows 11: Press "Shift + F10" to open the command prompt. Type 'OOBE\BYPASSNRO' (without the surrounding quotation marks) and press Enter. The system will restart and now allow you to click `I don't have internet`.
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./libvirt_images/21.png" width="700px"/>
|
<img src="./libvirt_images/21.png" width="700px"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
- For Windows 10: Simply click `I don't have internet`.
|
- For Windows 10: Simply click "I don't have internet".
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./libvirt_images/22.png" width="700px"/>
|
<img src="./libvirt_images/22.png" width="700px"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Following the above, choose to `Continue with limited setup`.
|
Following the above, choose to "Continue with limited setup".
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./libvirt_images/23.png" width="700px"/>
|
<img src="./libvirt_images/23.png" width="700px"/>
|
||||||
@ -668,6 +680,59 @@ Scroll down to `Remote Desktop`, and enable `Enable Remote Desktop`.
|
|||||||
|
|
||||||
At this point, you will need to restart the Windows virtual machine.
|
At this point, you will need to restart the Windows virtual machine.
|
||||||
|
|
||||||
|
## (Optional) Configuring a Fallback Shared Folder
|
||||||
|
When connecting to Windows through FreeRDP, your home folder will be shared automatically. However, this sharing setup does not apply when using Windows via virt-manager. To configure a fallback shared folder, follow these steps:
|
||||||
|
|
||||||
|
1. Navigate to "Virtual Hardware Details", then "Memory" and then check the box for "Enable shared memory".
|
||||||
|
|
||||||
|
2. Add filesystem hardware by going to "Virtual Hardware Details" and selecting "Add Hardware" followed by "Filesystem". Choose `virtiofs` as the driver, enter the path to the shared folder, and provide a name for the shared folder in the target path (e.g., "Windows Shared Folder").
|
||||||
|
|
||||||
|
3. Install [`WinFSP`](https://github.com/winfsp/winfsp/releases/) on Windows.
|
||||||
|
|
||||||
|
4. Enable and start a 'VirtIO Filesystem' service within Windows by running the following commands within a PowerShell prompt.
|
||||||
|
```PowerShell
|
||||||
|
sc.exe create VirtioFsSvc binpath= "C:\Program Files\Virtio-Win\VioFS\virtiofs.exe" start=auto depend="WinFsp.Launcher/VirtioFsDrv" DisplayName="Virtio Filesystem Service"
|
||||||
|
sc.exe start VirtioFsSvc
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Reboot Windows.
|
||||||
|
|
||||||
|
## (Optional) Configuring a Static IP Address
|
||||||
|
1. Identify the Windows MAC address.
|
||||||
|
```bash
|
||||||
|
virsh dumpxml "RDPWindows" | grep "mac address"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Edit the virtual network configuration.
|
||||||
|
1. Identify the correct network name.
|
||||||
|
```bash
|
||||||
|
virsh net-list # Will likely return "default"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Edit the configuration file.
|
||||||
|
```bash
|
||||||
|
virsh net-edit "default" # Replace "default" with the appropriate network name if different
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Update the `<dhcp>` section in the configuration file using the MAC address you obtained earlier. In the below example, "RDPWindows" has MAC address "df:87:4c:75:e5:fb" and is assigned the static IP address "192.168.122.2".
|
||||||
|
```xml
|
||||||
|
<dhcp>
|
||||||
|
<range start="192.168.122.2" end="192.168.122.254"/>
|
||||||
|
<host mac="df:87:4c:75:e5:fb" name="RDPWindows" ip="192.168.122.2"/>
|
||||||
|
<host mac="53:45:6b:de:a0:7b" name="Debian" ip="192.168.122.3"/>
|
||||||
|
<host mac="7d:62:4f:59:ef:f5" name="FreeBSD" ip="192.168.122.4"/>
|
||||||
|
</dhcp>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Restart the virtual network.
|
||||||
|
```bash
|
||||||
|
virsh net-destroy "default" # Replace with the correct name on your system
|
||||||
|
virsh net-start "default" # Replace with the correct name on your system
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Reboot Windows.
|
||||||
|
|
||||||
|
## Installing Windows Software and Configuring WinApps
|
||||||
You may now proceed to install other applications like 'Microsoft 365', 'Adobe Creative Cloud' or any other applications you would like to use through WinApps.
|
You may now proceed to install other applications like 'Microsoft 365', 'Adobe Creative Cloud' or any other applications you would like to use through WinApps.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
@ -679,5 +744,5 @@ You may now proceed to install other applications like 'Microsoft 365', 'Adobe C
|
|||||||
Finally, restart the virtual machine, but **DO NOT** log in. Close the virtual machine viewer and proceed to run the WinApps installation.
|
Finally, restart the virtual machine, but **DO NOT** log in. Close the virtual machine viewer and proceed to run the WinApps installation.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./installer.sh
|
bash <(curl https://raw.githubusercontent.com/winapps-org/winapps/main/setup.sh)
|
||||||
```
|
```
|
||||||
|
@ -103,11 +103,9 @@ function GetApplicationName {
|
|||||||
[string]$exePath
|
[string]$exePath
|
||||||
)
|
)
|
||||||
|
|
||||||
if ((Get-Item $exePath).VersionInfo.FileDescription) {
|
try {
|
||||||
# Remove leading/trailing whitespace and replace multiple spaces with a single space.
|
|
||||||
$productName = (Get-Item $exePath).VersionInfo.FileDescription.Trim() -replace '\s+', ' '
|
$productName = (Get-Item $exePath).VersionInfo.FileDescription.Trim() -replace '\s+', ' '
|
||||||
} else {
|
} catch {
|
||||||
# Get the executable file name without the file extension.
|
|
||||||
$productName = [System.IO.Path]::GetFileNameWithoutExtension($exePath)
|
$productName = [System.IO.Path]::GetFileNameWithoutExtension($exePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,10 +123,7 @@ function GetUWPApplicationName {
|
|||||||
|
|
||||||
# Query the application executable for the application name.
|
# Query the application executable for the application name.
|
||||||
if (Test-Path $exePath) {
|
if (Test-Path $exePath) {
|
||||||
if ((Get-Item $exePath).VersionInfo.FileDescription) {
|
$productName = GetApplicationName -exePath $exePath
|
||||||
# Remove leading/trailing whitespace and replace multiple spaces with a single space.
|
|
||||||
$productName = (Get-Item $exePath).VersionInfo.FileDescription.Trim() -replace '\s+', ' '
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use the 'DisplayName' (if available) if the previous method failed.
|
# Use the 'DisplayName' (if available) if the previous method failed.
|
||||||
@ -180,6 +175,7 @@ function AppSearchWinReg {
|
|||||||
# Initialise empty arrays.
|
# Initialise empty arrays.
|
||||||
$exeNames = @()
|
$exeNames = @()
|
||||||
$exePaths = @()
|
$exePaths = @()
|
||||||
|
$validPaths = @()
|
||||||
|
|
||||||
# Query windows registry for unique installed executable files.
|
# Query windows registry for unique installed executable files.
|
||||||
$exePaths = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\*" |
|
$exePaths = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\*" |
|
||||||
@ -192,11 +188,14 @@ function AppSearchWinReg {
|
|||||||
|
|
||||||
# Get corresponding application names for unique installed executable files.
|
# Get corresponding application names for unique installed executable files.
|
||||||
foreach ($exePath in $exePaths) {
|
foreach ($exePath in $exePaths) {
|
||||||
$exeNames += GetApplicationName -exePath $exePath
|
if (Test-Path -Path $exePath) {
|
||||||
|
$validPaths += $exePath
|
||||||
|
$exeNames += GetApplicationName -exePath $exePath
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Process extracted executable file paths.
|
# Process extracted executable file paths.
|
||||||
PrintArrayData -Names $exeNames -Paths $exePaths -Source "winreg"
|
PrintArrayData -Names $exeNames -Paths $validPaths -Source "winreg"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Name: 'AppSearchUWP'
|
# Name: 'AppSearchUWP'
|
||||||
|
@ -37,6 +37,9 @@ readonly EC_INVALID_FLAVOR="16" # Backend specified is not 'libvirt', 'docker'
|
|||||||
readonly SYS_BIN_PATH="/usr/local/bin" # UNIX path to 'bin' directory for a '--system' WinApps installation.
|
readonly SYS_BIN_PATH="/usr/local/bin" # UNIX path to 'bin' directory for a '--system' WinApps installation.
|
||||||
readonly USER_BIN_PATH="${HOME}/.local/bin" # UNIX path to 'bin' directory for a '--user' WinApps installation.
|
readonly USER_BIN_PATH="${HOME}/.local/bin" # UNIX path to 'bin' directory for a '--user' WinApps installation.
|
||||||
readonly USER_BIN_PATH_WIN='\\tsclient\home\.local\bin' # WINDOWS path to 'bin' directory for a '--user' WinApps installation.
|
readonly USER_BIN_PATH_WIN='\\tsclient\home\.local\bin' # WINDOWS path to 'bin' directory for a '--user' WinApps installation.
|
||||||
|
# 'SOURCE'
|
||||||
|
readonly SYS_SOURCE_PATH="${SYS_BIN_PATH}/winapps" # UNIX path to WinApps source directory for a '--system' WinApps installation.
|
||||||
|
readonly USER_SOURCE_PATH="${USER_BIN_PATH}/winapps" # UNIX path to WinApps source directory for a '--system' WinApps installation.
|
||||||
# 'APP'
|
# 'APP'
|
||||||
readonly SYS_APP_PATH="/usr/share/applications" # UNIX path to 'applications' directory for a '--system' WinApps installation.
|
readonly SYS_APP_PATH="/usr/share/applications" # UNIX path to 'applications' directory for a '--system' WinApps installation.
|
||||||
readonly USER_APP_PATH="${HOME}/.local/share/applications" # UNIX path to 'applications' directory for a '--user' WinApps installation.
|
readonly USER_APP_PATH="${HOME}/.local/share/applications" # UNIX path to 'applications' directory for a '--user' WinApps installation.
|
||||||
@ -98,6 +101,7 @@ SUDO="" # Set to "sudo" if the user specifies '--system', or "" if the u
|
|||||||
BIN_PATH="" # Set to $SYS_BIN_PATH if the user specifies '--system', or $USER_BIN_PATH if the user specifies '--user'.
|
BIN_PATH="" # Set to $SYS_BIN_PATH if the user specifies '--system', or $USER_BIN_PATH if the user specifies '--user'.
|
||||||
APP_PATH="" # Set to $SYS_APP_PATH if the user specifies '--system', or $USER_APP_PATH if the user specifies '--user'.
|
APP_PATH="" # Set to $SYS_APP_PATH if the user specifies '--system', or $USER_APP_PATH if the user specifies '--user'.
|
||||||
APPDATA_PATH="" # Set to $SYS_APPDATA_PATH if the user specifies '--system', or $USER_APPDATA_PATH if the user specifies '--user'.
|
APPDATA_PATH="" # Set to $SYS_APPDATA_PATH if the user specifies '--system', or $USER_APPDATA_PATH if the user specifies '--user'.
|
||||||
|
SOURCE_PATH="" # Set to $SYS_SOURCE_PATH if the user specifies '--system', or $USER_SOURCE_PATH if the user specifies '--user'.
|
||||||
|
|
||||||
# INSTALLATION PROCESS
|
# INSTALLATION PROCESS
|
||||||
INSTALLED_EXES=() # List of executable file names of officially supported applications that have already been configured during the current installation process.
|
INSTALLED_EXES=() # List of executable file names of officially supported applications that have already been configured during the current installation process.
|
||||||
@ -125,38 +129,52 @@ function waTerminateScript() {
|
|||||||
# Role: Displays usage information for the script.
|
# Role: Displays usage information for the script.
|
||||||
function waUsage() {
|
function waUsage() {
|
||||||
echo -e "Usage:
|
echo -e "Usage:
|
||||||
${COMMAND_TEXT}./installer.sh --user${CLEAR_TEXT} # Install WinApps and selected applications in ${HOME}
|
${COMMAND_TEXT}./setup.sh --user${CLEAR_TEXT} # Install WinApps and selected applications in ${HOME}
|
||||||
${COMMAND_TEXT}./installer.sh --system${CLEAR_TEXT} # Install WinApps and selected applications in /usr
|
${COMMAND_TEXT}./setup.sh --system${CLEAR_TEXT} # Install WinApps and selected applications in /usr
|
||||||
${COMMAND_TEXT}./installer.sh --user --setupAllOfficiallySupportedApps${CLEAR_TEXT} # Install WinApps and all officially supported applications in ${HOME}
|
${COMMAND_TEXT}./setup.sh --user --setupAllOfficiallySupportedApps${CLEAR_TEXT} # Install WinApps and all officially supported applications in ${HOME}
|
||||||
${COMMAND_TEXT}./installer.sh --system --setupAllOfficiallySupportedApps${CLEAR_TEXT} # Install WinApps and all officially supported applications in /usr
|
${COMMAND_TEXT}./setup.sh --system --setupAllOfficiallySupportedApps${CLEAR_TEXT} # Install WinApps and all officially supported applications in /usr
|
||||||
${COMMAND_TEXT}./installer.sh --user --uninstall${CLEAR_TEXT} # Uninstall everything in ${HOME}
|
${COMMAND_TEXT}./setup.sh --user --uninstall${CLEAR_TEXT} # Uninstall everything in ${HOME}
|
||||||
${COMMAND_TEXT}./installer.sh --system --uninstall${CLEAR_TEXT} # Uninstall everything in /usr
|
${COMMAND_TEXT}./setup.sh --system --uninstall${CLEAR_TEXT} # Uninstall everything in /usr
|
||||||
${COMMAND_TEXT}./installer.sh --help${CLEAR_TEXT} # Display this usage message."
|
${COMMAND_TEXT}./setup.sh --help${CLEAR_TEXT} # Display this usage message."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Name: 'waSetWorkingDirectory'
|
# Name: 'waGetSourceCode'
|
||||||
# Role: Changes the working directory to the directory containing the script.
|
# Role: Grab the WinApps source code using Git.
|
||||||
function waSetWorkingDirectory() {
|
function waGetSourceCode() {
|
||||||
# Declare variables.
|
# Declare variables.
|
||||||
local SCRIPT_DIR_PATH="" # Stores the absolute path of the directory containing the script.
|
local SCRIPT_DIR_PATH="" # Stores the absolute path of the directory containing the script.
|
||||||
|
|
||||||
# Determine the absolute path to the directory containing the script.
|
# Determine the absolute path to the directory containing the script.
|
||||||
SCRIPT_DIR_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
|
SCRIPT_DIR_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
|
||||||
|
|
||||||
|
# Check if winapps is currently installed on $SOURCE_PATH
|
||||||
|
if [ -f "$SCRIPT_DIR_PATH/winapps" ] && [ "$SCRIPT_DIR_PATH" -ne "$SOURCE_PATH" ]; then
|
||||||
|
# Display a warning.
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} You are running a WinApps installation located outside of default location '${SOURCE_PATH}'. A new installation will be created."
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} You might want to remove your old installation on '${SCRIPT_DIR_PATH}'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$SOURCE_PATH" ]]; then
|
||||||
|
$SUDO git clone --recurse-submodules --remote-submodules https://github.com/winapps-org/winapps.git "$SOURCE_PATH"
|
||||||
|
else
|
||||||
|
echo -e "${INFO_TEXT}WinApps installation already present at ${CLEAR_TEXT}${COMMAND_TEXT}${SOURCE_PATH}${CLEAR_TEXT}${INFO_TEXT}. Updating...${CLEAR_TEXT}"
|
||||||
|
$SUDO git -C "$SOURCE_PATH" pull --no-rebase
|
||||||
|
fi
|
||||||
|
|
||||||
# Silently change the working directory.
|
# Silently change the working directory.
|
||||||
if ! cd "$SCRIPT_DIR_PATH" &>/dev/null; then
|
if ! cd "$SOURCE_PATH" &>/dev/null; then
|
||||||
# Display the error type.
|
# Display the error type.
|
||||||
echo -e "${ERROR_TEXT}ERROR:${CLEAR_TEXT} ${BOLD_TEXT}DIRECTORY CHANGE FAILURE.${CLEAR_TEXT}"
|
echo -e "${ERROR_TEXT}ERROR:${CLEAR_TEXT} ${BOLD_TEXT}DIRECTORY CHANGE FAILURE.${CLEAR_TEXT}"
|
||||||
|
|
||||||
# Display error details.
|
# Display error details.
|
||||||
echo -e "${INFO_TEXT}Failed to change the working directory to ${CLEAR_TEXT}${COMMAND_TEXT}${SCRIPT_DIR_PATH}${CLEAR_TEXT}${INFO_TEXT}.${CLEAR_TEXT}"
|
echo -e "${INFO_TEXT}Failed to change the working directory to ${CLEAR_TEXT}${COMMAND_TEXT}${SOURCE_PATH}${CLEAR_TEXT}${INFO_TEXT}.${CLEAR_TEXT}"
|
||||||
|
|
||||||
# Display the suggested action(s).
|
# Display the suggested action(s).
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
echo "Ensure:"
|
echo "Ensure:"
|
||||||
echo -e " - ${COMMAND_TEXT}${SCRIPT_DIR_PATH}${CLEAR_TEXT} exists."
|
echo -e " - ${COMMAND_TEXT}${SOURCE_PATH}${CLEAR_TEXT} exists."
|
||||||
echo -e " - ${COMMAND_TEXT}${SCRIPT_DIR_PATH}${CLEAR_TEXT} is valid and does not contain syntax errors."
|
echo -e " - ${COMMAND_TEXT}${SOURCE_PATH}${CLEAR_TEXT} has been cloned and checked out properly."
|
||||||
echo -e " - The current user has sufficient permissions to access ${COMMAND_TEXT}${SCRIPT_DIR_PATH}${CLEAR_TEXT}."
|
echo -e " - The current user has sufficient permissions to access and write to ${COMMAND_TEXT}${SOURCE_PATH}${CLEAR_TEXT}."
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
|
||||||
# Terminate the script.
|
# Terminate the script.
|
||||||
@ -164,6 +182,22 @@ function waSetWorkingDirectory() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Name: 'waGetInquirer'
|
||||||
|
# Role: Loads the inquirer script, even if the source isn't cloned yet
|
||||||
|
function waGetInquirer() {
|
||||||
|
local INQUIRER=$INQUIRER_PATH
|
||||||
|
|
||||||
|
if [ ! -d "$SYS_SOURCE_PATH" ] && [ ! -d "$USER_SOURCE_PATH" ]; then
|
||||||
|
INQUIRER="/tmp/waInquirer.sh"
|
||||||
|
rm -f "$INQUIRER"
|
||||||
|
|
||||||
|
curl -o "$INQUIRER" "https://raw.githubusercontent.com/winapps-org/winapps/main/install/inquirer.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null # Exclude this file from being checked by ShellCheck.
|
||||||
|
source "$INQUIRER"
|
||||||
|
}
|
||||||
|
|
||||||
# Name: 'waCheckInput'
|
# Name: 'waCheckInput'
|
||||||
# Role: Sanitises input and guides users through selecting appropriate options if no arguments are provided.
|
# Role: Sanitises input and guides users through selecting appropriate options if no arguments are provided.
|
||||||
function waCheckInput() {
|
function waCheckInput() {
|
||||||
@ -301,11 +335,13 @@ function waCheckInput() {
|
|||||||
function waConfigurePathsAndPermissions() {
|
function waConfigurePathsAndPermissions() {
|
||||||
if [ "$OPT_USER" -eq 1 ]; then
|
if [ "$OPT_USER" -eq 1 ]; then
|
||||||
SUDO=""
|
SUDO=""
|
||||||
|
SOURCE_PATH="$USER_SOURCE_PATH"
|
||||||
BIN_PATH="$USER_BIN_PATH"
|
BIN_PATH="$USER_BIN_PATH"
|
||||||
APP_PATH="$USER_APP_PATH"
|
APP_PATH="$USER_APP_PATH"
|
||||||
APPDATA_PATH="$USER_APPDATA_PATH"
|
APPDATA_PATH="$USER_APPDATA_PATH"
|
||||||
elif [ "$OPT_SYSTEM" -eq 1 ]; then
|
elif [ "$OPT_SYSTEM" -eq 1 ]; then
|
||||||
SUDO="sudo"
|
SUDO="sudo"
|
||||||
|
SOURCE_PATH="$SYS_SOURCE_PATH"
|
||||||
BIN_PATH="$SYS_BIN_PATH"
|
BIN_PATH="$SYS_BIN_PATH"
|
||||||
APP_PATH="$SYS_APP_PATH"
|
APP_PATH="$SYS_APP_PATH"
|
||||||
APPDATA_PATH="$SYS_APPDATA_PATH"
|
APPDATA_PATH="$SYS_APPDATA_PATH"
|
||||||
@ -337,7 +373,7 @@ function waCheckExistingInstall() {
|
|||||||
echo -n "Checking for existing conflicting WinApps installations... "
|
echo -n "Checking for existing conflicting WinApps installations... "
|
||||||
|
|
||||||
# Check for an existing 'user' installation.
|
# Check for an existing 'user' installation.
|
||||||
if [ -f "${USER_BIN_PATH}/winapps" ]; then
|
if [[ -f "${USER_BIN_PATH}/winapps" || -d "${USER_SOURCE_PATH}/winapps" ]]; then
|
||||||
# Complete the previous line.
|
# Complete the previous line.
|
||||||
echo -e "${FAIL_TEXT}Failed!${CLEAR_TEXT}\n"
|
echo -e "${FAIL_TEXT}Failed!${CLEAR_TEXT}\n"
|
||||||
|
|
||||||
@ -349,7 +385,7 @@ function waCheckExistingInstall() {
|
|||||||
|
|
||||||
# Display the suggested action(s).
|
# Display the suggested action(s).
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
echo -e "Please remove the existing WinApps installation using ${COMMAND_TEXT}./installer.sh --user --uninstall${CLEAR_TEXT}."
|
echo -e "Please remove the existing WinApps installation using ${COMMAND_TEXT}./setup.sh --user --uninstall${CLEAR_TEXT}."
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
|
||||||
# Terminate the script.
|
# Terminate the script.
|
||||||
@ -357,7 +393,7 @@ function waCheckExistingInstall() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for an existing 'system' installation.
|
# Check for an existing 'system' installation.
|
||||||
if [ -f "${SYS_BIN_PATH}/winapps" ]; then
|
if [[ -f "${SYS_BIN_PATH}/winapps" || -d "${SYS_SOURCE_PATH}/winapps" ]]; then
|
||||||
# Complete the previous line.
|
# Complete the previous line.
|
||||||
echo -e "${FAIL_TEXT}Failed!${CLEAR_TEXT}\n"
|
echo -e "${FAIL_TEXT}Failed!${CLEAR_TEXT}\n"
|
||||||
|
|
||||||
@ -369,7 +405,7 @@ function waCheckExistingInstall() {
|
|||||||
|
|
||||||
# Display the suggested action(s).
|
# Display the suggested action(s).
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
echo -e "Please remove the existing WinApps installation using ${COMMAND_TEXT}./installer.sh --system --uninstall${CLEAR_TEXT}."
|
echo -e "Please remove the existing WinApps installation using ${COMMAND_TEXT}./setup.sh --system --uninstall${CLEAR_TEXT}."
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
|
||||||
# Terminate the script.
|
# Terminate the script.
|
||||||
@ -450,6 +486,54 @@ function waLoadConfig() {
|
|||||||
# Name: 'waCheckScriptDependencies'
|
# Name: 'waCheckScriptDependencies'
|
||||||
# Role: Terminate script if dependencies are missing.
|
# Role: Terminate script if dependencies are missing.
|
||||||
function waCheckScriptDependencies() {
|
function waCheckScriptDependencies() {
|
||||||
|
# 'Git'
|
||||||
|
if ! command -v git &>/dev/null; then
|
||||||
|
# Display the error type.
|
||||||
|
echo -e "${ERROR_TEXT}ERROR:${CLEAR_TEXT} ${BOLD_TEXT}MISSING DEPENDENCIES.${CLEAR_TEXT}"
|
||||||
|
|
||||||
|
# Display the error details.
|
||||||
|
echo -e "${INFO_TEXT}Please install 'git' to proceed.${CLEAR_TEXT}"
|
||||||
|
|
||||||
|
# Display the suggested action(s).
|
||||||
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
echo "Debian/Ubuntu-based systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo apt install git${CLEAR_TEXT}"
|
||||||
|
echo "Red Hat/Fedora-based systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo dnf install git${CLEAR_TEXT}"
|
||||||
|
echo "Arch Linux systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo pacman -S git${CLEAR_TEXT}"
|
||||||
|
echo "Gentoo Linux systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo emerge --ask dev-vcs/git${CLEAR_TEXT}"
|
||||||
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
# Terminate the script.
|
||||||
|
return "$EC_MISSING_DEPS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 'curl'
|
||||||
|
if ! command -v curl &>/dev/null; then
|
||||||
|
# Display the error type.
|
||||||
|
echo -e "${ERROR_TEXT}ERROR:${CLEAR_TEXT} ${BOLD_TEXT}MISSING DEPENDENCIES.${CLEAR_TEXT}"
|
||||||
|
|
||||||
|
# Display the error details.
|
||||||
|
echo -e "${INFO_TEXT}Please install 'curl' to proceed.${CLEAR_TEXT}"
|
||||||
|
|
||||||
|
# Display the suggested action(s).
|
||||||
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
echo "Debian/Ubuntu-based systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo apt install curl${CLEAR_TEXT}"
|
||||||
|
echo "Red Hat/Fedora-based systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo dnf install curl${CLEAR_TEXT}"
|
||||||
|
echo "Arch Linux systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo pacman -S curl${CLEAR_TEXT}"
|
||||||
|
echo "Gentoo Linux systems:"
|
||||||
|
echo -e " ${COMMAND_TEXT}sudo emerge --ask net-misc/curl${CLEAR_TEXT}"
|
||||||
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
|
||||||
|
# Terminate the script.
|
||||||
|
return "$EC_MISSING_DEPS"
|
||||||
|
fi
|
||||||
|
|
||||||
# 'Dialog'.
|
# 'Dialog'.
|
||||||
if ! command -v dialog &>/dev/null; then
|
if ! command -v dialog &>/dev/null; then
|
||||||
# Display the error type.
|
# Display the error type.
|
||||||
@ -852,7 +936,7 @@ function waCheckContainerRunning() {
|
|||||||
# Display the suggested action(s).
|
# Display the suggested action(s).
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
echo "Please ensure Windows is powered on:"
|
echo "Please ensure Windows is powered on:"
|
||||||
echo -e "${COMMAND_TEXT}${COMPOSE_COMMAND} --file ~/.config/winapps/winapps.conf start${CLEAR_TEXT}"
|
echo -e "${COMMAND_TEXT}${COMPOSE_COMMAND} --file ~/.config/winapps/compose.yaml start${CLEAR_TEXT}"
|
||||||
echo "--------------------------------------------------------------------------------"
|
echo "--------------------------------------------------------------------------------"
|
||||||
|
|
||||||
# Terminate the script.
|
# Terminate the script.
|
||||||
@ -1536,8 +1620,9 @@ function waInstall() {
|
|||||||
# Check for installed applications.
|
# Check for installed applications.
|
||||||
waFindInstalled
|
waFindInstalled
|
||||||
|
|
||||||
# Install the WinApps bash script.
|
# Install the WinApps bash scripts.
|
||||||
$SUDO cp "./bin/winapps" "${BIN_PATH}/winapps"
|
$SUDO ln -s "./bin/winapps" "${BIN_PATH}/winapps"
|
||||||
|
$SUDO ln -s "./setup.sh" "${BIN_PATH}/winapps-setup"
|
||||||
|
|
||||||
# Configure the Windows RDP session application launcher.
|
# Configure the Windows RDP session application launcher.
|
||||||
waConfigureWindows
|
waConfigureWindows
|
||||||
@ -1553,10 +1638,27 @@ function waInstall() {
|
|||||||
waConfigureDetectedApps
|
waConfigureDetectedApps
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure BIN_PATH is on PATH
|
||||||
|
waEnsureOnPath
|
||||||
|
|
||||||
# Print feedback.
|
# Print feedback.
|
||||||
echo -e "${SUCCESS_TEXT}INSTALLATION COMPLETE.${CLEAR_TEXT}"
|
echo -e "${SUCCESS_TEXT}INSTALLATION COMPLETE.${CLEAR_TEXT}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Name: 'waEnsureOnPath'
|
||||||
|
# Role: Ensures that $BIN_PATH is on $PATH.
|
||||||
|
function waEnsureOnPath() {
|
||||||
|
if [[ ":$PATH:" == *":$BIN_PATH:"* ]]; then
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} It seems like '${BIN_PATH}' is not on PATH."
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} You can add it by running:"
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} - For Bash: ${COMMAND_TEXT}echo 'export PATH="${BIN_PATH}:\$PATH"' >> ~/.bashrc${CLEAR_TEXT}"
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} - For ZSH: ${COMMAND_TEXT}echo 'export PATH="${BIN_PATH}:\$PATH"' >> ~/.zshrc${CLEAR_TEXT}"
|
||||||
|
echo -e "${WARNING_TEXT}[WARNING]${CLEAR_TEXT} Make sure to restart your Terminal afterwards.\n"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Name: 'waUninstall'
|
# Name: 'waUninstall'
|
||||||
# Role: Uninstalls WinApps.
|
# Role: Uninstalls WinApps.
|
||||||
function waUninstall() {
|
function waUninstall() {
|
||||||
@ -1570,8 +1672,9 @@ function waUninstall() {
|
|||||||
local DESKTOP_FILE_NAME="" # Stores the name of the '.desktop' file for the application.
|
local DESKTOP_FILE_NAME="" # Stores the name of the '.desktop' file for the application.
|
||||||
local BASH_SCRIPT_NAME="" # Stores the name of the application.
|
local BASH_SCRIPT_NAME="" # Stores the name of the application.
|
||||||
|
|
||||||
# Remove the 'WinApps' bash script.
|
# Remove the 'WinApps' bash scripts.
|
||||||
$SUDO rm -f "${BIN_PATH}/winapps"
|
$SUDO rm -f "${BIN_PATH}/winapps"
|
||||||
|
$SUDO rm -f "${BIN_PATH}/winapps-setup"
|
||||||
|
|
||||||
# Remove WinApps configuration data, temporary files and logs.
|
# Remove WinApps configuration data, temporary files and logs.
|
||||||
rm -rf "$USER_APPDATA_PATH"
|
rm -rf "$USER_APPDATA_PATH"
|
||||||
@ -1622,9 +1725,10 @@ function waUninstall() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Print caveats.
|
# Print caveats.
|
||||||
echo -e "\n${INFO_TEXT}Please note your WinApps configuration folder was not removed.${CLEAR_TEXT}"
|
echo -e "\n${INFO_TEXT}Please note that your WinApps configuration and the WinApps source code were not removed.${CLEAR_TEXT}"
|
||||||
echo -e "${INFO_TEXT}You can remove this manually by running:${CLEAR_TEXT}"
|
echo -e "${INFO_TEXT}You can remove these manually by running:${CLEAR_TEXT}"
|
||||||
echo -e "${COMMAND_TEXT}rm -r $(dirname "$CONFIG_PATH")${CLEAR_TEXT}\n"
|
echo -e "${COMMAND_TEXT}rm -r $(dirname "$CONFIG_PATH")${CLEAR_TEXT}"
|
||||||
|
echo -e "${COMMAND_TEXT}rm -r ${SOURCE_PATH}${CLEAR_TEXT}\n"
|
||||||
|
|
||||||
# Print feedback.
|
# Print feedback.
|
||||||
echo -e "${SUCCESS_TEXT}UNINSTALLATION COMPLETE.${CLEAR_TEXT}"
|
echo -e "${SUCCESS_TEXT}UNINSTALLATION COMPLETE.${CLEAR_TEXT}"
|
||||||
@ -1644,11 +1748,7 @@ ${CLEAR_TEXT}"
|
|||||||
waCheckScriptDependencies
|
waCheckScriptDependencies
|
||||||
|
|
||||||
# Source the contents of 'inquirer.sh'.
|
# Source the contents of 'inquirer.sh'.
|
||||||
# shellcheck source=/dev/null # Exclude this file from being checked by ShellCheck.
|
waGetInquirer
|
||||||
source "$INQUIRER_PATH"
|
|
||||||
|
|
||||||
# Set the working directory.
|
|
||||||
waSetWorkingDirectory
|
|
||||||
|
|
||||||
# Sanitise and parse the user input.
|
# Sanitise and parse the user input.
|
||||||
waCheckInput "$@"
|
waCheckInput "$@"
|
||||||
@ -1656,6 +1756,9 @@ waCheckInput "$@"
|
|||||||
# Configure paths and permissions.
|
# Configure paths and permissions.
|
||||||
waConfigurePathsAndPermissions
|
waConfigurePathsAndPermissions
|
||||||
|
|
||||||
|
# Get the source code
|
||||||
|
waGetSourceCode
|
||||||
|
|
||||||
# Install or uninstall WinApps.
|
# Install or uninstall WinApps.
|
||||||
if [ "$OPT_UNINSTALL" -eq 1 ]; then
|
if [ "$OPT_UNINSTALL" -eq 1 ]; then
|
||||||
waUninstall
|
waUninstall
|
Loading…
x
Reference in New Issue
Block a user