diff --git a/Agent/Services/AppLauncherLinux.cs b/Agent/Services/AppLauncherLinux.cs index 0f04ebcd0..23637e07d 100644 --- a/Agent/Services/AppLauncherLinux.cs +++ b/Agent/Services/AppLauncherLinux.cs @@ -126,13 +126,26 @@ private int StartLinuxDesktopApp(string args) { try { - var whoLine = whoString - .Split('\n', StringSplitOptions.RemoveEmptyEntries) - .First(); - - var whoSplit = whoLine.Split(' ', StringSplitOptions.RemoveEmptyEntries); - username = whoSplit[0]; - display = whoSplit.Last().TrimStart('(').TrimEnd(')'); + var whoLines = whoString + .Split('\n', StringSplitOptions.RemoveEmptyEntries); + + for(int i = 0; i < whoLines.Length; i++) + { + var whoLine = whoLines[i]; + var whoSplit = whoLine.Split(' ', StringSplitOptions.RemoveEmptyEntries); + + username = whoSplit[0]; + Logger.Write($"split last: {whoSplit.Last()}"); + + display = whoSplit.Last().TrimStart('(').TrimEnd(')'); + Logger.Write($"display: {display}"); + + if(display.Length >0 && display[0] == ':') + { + break; + } + + } xauthority = $"/home/{username}/.Xauthority"; args = $"-u {username} {args}"; } diff --git a/Desktop.XPlat/Native/Linux/LibX11_32.cs b/Desktop.XPlat/Native/Linux/LibX11_32.cs new file mode 100644 index 000000000..fd369db79 --- /dev/null +++ b/Desktop.XPlat/Native/Linux/LibX11_32.cs @@ -0,0 +1,38 @@ +/* + +Copyright 1985, 1986, 1987, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +using System; +using System.Runtime.InteropServices; + +namespace Remotely.Desktop.XPlat.Native.Linux +{ + public static unsafe class LibX11_32 + { + + [DllImport("libX11")] + public static extern IntPtr XGetImage(IntPtr display, IntPtr drawable, int x, int y, int width, int height, uint plane_mask, int format); + } +} diff --git a/Desktop.XPlat/Native/Linux/LibXtst_32.cs b/Desktop.XPlat/Native/Linux/LibXtst_32.cs new file mode 100644 index 000000000..5c2cb2135 --- /dev/null +++ b/Desktop.XPlat/Native/Linux/LibXtst_32.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.InteropServices; + +namespace Remotely.Desktop.XPlat.Native.Linux +{ + public class LibXtst_32 + { + [DllImport("libXtst")] + public static extern void XTestFakeKeyEvent(IntPtr display, uint keycode, bool is_press, uint delay); + [DllImport("libXtst")] + public static extern void XTestFakeButtonEvent(IntPtr display, uint button, bool is_press, uint delay); + [DllImport("libXtst")] + public static extern void XTestFakeMotionEvent(IntPtr display, int screen_number, int x, int y, uint delay); + } +} diff --git a/Desktop.XPlat/Properties/PublishProfiles/desktop-linux-arm.pubxml b/Desktop.XPlat/Properties/PublishProfiles/desktop-linux-arm.pubxml new file mode 100644 index 000000000..9ad02ee4f --- /dev/null +++ b/Desktop.XPlat/Properties/PublishProfiles/desktop-linux-arm.pubxml @@ -0,0 +1,19 @@ + + + + + FileSystem + Release + arm + net6.0 + ..\Server\wwwroot\Content\Linux-arm\ + linux-arm + true + True + False + true + true + + \ No newline at end of file diff --git a/Desktop.XPlat/Properties/PublishProfiles/packaged-linux-arm.pubxml b/Desktop.XPlat/Properties/PublishProfiles/packaged-linux-arm.pubxml new file mode 100644 index 000000000..94d882739 --- /dev/null +++ b/Desktop.XPlat/Properties/PublishProfiles/packaged-linux-arm.pubxml @@ -0,0 +1,17 @@ + + + + + FileSystem + Release + arm + net6.0 + ..\Agent\bin\Release\net6.0\linux-arm\publish\Desktop + linux-arm + true + False + False + + \ No newline at end of file diff --git a/Desktop.XPlat/Services/KeyboardMouseInputLinux.cs b/Desktop.XPlat/Services/KeyboardMouseInputLinux.cs index 86f6046db..65bb2f6cc 100644 --- a/Desktop.XPlat/Services/KeyboardMouseInputLinux.cs +++ b/Desktop.XPlat/Services/KeyboardMouseInputLinux.cs @@ -32,7 +32,13 @@ public void SendKeyDown(string key) } var keyCode = LibX11.XKeysymToKeycode(Display, keySim); - LibXtst.XTestFakeKeyEvent(Display, keyCode, true, 0); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeKeyEvent(Display, keyCode, true, 0); + } + else{ + LibXtst_32.XTestFakeKeyEvent(Display, keyCode, true, 0); + } LibX11.XSync(Display, false); } catch (Exception ex) @@ -55,7 +61,13 @@ public void SendKeyUp(string key) } var keyCode = LibX11.XKeysymToKeycode(Display, keySim); - LibXtst.XTestFakeKeyEvent(Display, keyCode, false, 0); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeKeyEvent(Display, keyCode, false, 0); + } + else{ + LibXtst_32.XTestFakeKeyEvent(Display, keyCode, false, 0); + } LibX11.XSync(Display, false); } catch (Exception ex) @@ -75,8 +87,14 @@ public void SendMouseButtonAction(int button, ButtonAction buttonAction, double var mouseButton = (uint)(button + 1); InitDisplay(); - SendMouseMove(percentX, percentY, viewer); - LibXtst.XTestFakeButtonEvent(Display, mouseButton, isPressed, 0); + SendMouseMove(percentX, percentY, viewer); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeButtonEvent(Display, mouseButton, isPressed, 0); + } + else{ + LibXtst_32.XTestFakeButtonEvent(Display, mouseButton, isPressed, 0); + } LibX11.XSync(Display, false); } catch (Exception ex) @@ -92,11 +110,22 @@ public void SendMouseMove(double percentX, double percentY, Viewer viewer) InitDisplay(); var screenBounds = viewer.Capturer.CurrentScreenBounds; - LibXtst.XTestFakeMotionEvent(Display, - LibX11.XDefaultScreen(Display), - screenBounds.X + (int)(screenBounds.Width * percentX), - screenBounds.Y + (int)(screenBounds.Height * percentY), + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeMotionEvent(Display, + LibX11.XDefaultScreen(Display), + screenBounds.X + (int)(screenBounds.Width * percentX), + screenBounds.Y + (int)(screenBounds.Height * percentY), + 0); + } + else{ + LibXtst_32.XTestFakeMotionEvent(Display, + LibX11.XDefaultScreen(Display), + screenBounds.X + (int)(screenBounds.Width * percentX), + screenBounds.Y + (int)(screenBounds.Height * percentY), 0); + } + LibX11.XSync(Display, false); } catch (Exception ex) @@ -114,11 +143,27 @@ public void SendMouseWheel(int deltaY) { LibXtst.XTestFakeButtonEvent(Display, 4, true, 0); LibXtst.XTestFakeButtonEvent(Display, 4, false, 0); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeButtonEvent(Display, 4, true, 0); + LibXtst.XTestFakeButtonEvent(Display, 4, false, 0); + } + else{ + LibXtst_32.XTestFakeButtonEvent(Display, 4, true, 0); + LibXtst_32.XTestFakeButtonEvent(Display, 4, false, 0); + } } else { - LibXtst.XTestFakeButtonEvent(Display, 5, true, 0); - LibXtst.XTestFakeButtonEvent(Display, 5, false, 0); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeButtonEvent(Display, 5, true, 0); + LibXtst.XTestFakeButtonEvent(Display, 5, false, 0); + } + else{ + LibXtst_32.XTestFakeButtonEvent(Display, 5, true, 0); + LibXtst_32.XTestFakeButtonEvent(Display, 5, false, 0); + } } LibX11.XSync(Display, false); } @@ -134,7 +179,13 @@ public void SendRightMouseDown(double percentX, double percentY, Viewer viewer) { InitDisplay(); SendMouseMove(percentX, percentY, viewer); - LibXtst.XTestFakeButtonEvent(Display, 3, true, 0); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeButtonEvent(Display, 3, true, 0); + } + else{ + LibXtst_32.XTestFakeButtonEvent(Display, 3, true, 0); + } LibX11.XSync(Display, false); } catch (Exception ex) @@ -149,7 +200,13 @@ public void SendRightMouseUp(double percentX, double percentY, Viewer viewer) { InitDisplay(); SendMouseMove(percentX, percentY, viewer); - LibXtst.XTestFakeButtonEvent(Display, 3, false, 0); + if(EnvironmentHelper.Is64) + { + LibXtst.XTestFakeButtonEvent(Display, 3, false, 0); + } + else{ + LibXtst_32.XTestFakeButtonEvent(Display, 3, false, 0); + } LibX11.XSync(Display, false); } catch (Exception ex) diff --git a/Desktop.XPlat/Services/ScreenCapturerLinux.cs b/Desktop.XPlat/Services/ScreenCapturerLinux.cs index 0adb07155..a46329469 100644 --- a/Desktop.XPlat/Services/ScreenCapturerLinux.cs +++ b/Desktop.XPlat/Services/ScreenCapturerLinux.cs @@ -146,14 +146,35 @@ private Bitmap GetX11Capture() var window = LibX11.XDefaultRootWindow(Display); - var imagePointer = LibX11.XGetImage(Display, - window, - CurrentScreenBounds.X, - CurrentScreenBounds.Y, - CurrentScreenBounds.Width, - CurrentScreenBounds.Height, - ~0, - 2); + IntPtr imagePointer = IntPtr.Zero; + + if(EnvironmentHelper.Is64) + { + imagePointer = LibX11.XGetImage(Display, + window, + CurrentScreenBounds.X, + CurrentScreenBounds.Y, + CurrentScreenBounds.Width, + CurrentScreenBounds.Height, + ~0, + 2); + } + else + { + imagePointer = LibX11_32.XGetImage(Display, + window, + CurrentScreenBounds.X, + CurrentScreenBounds.Y, + CurrentScreenBounds.Width, + CurrentScreenBounds.Height, + 0xffffffff, + 2); + } + + if(imagePointer == IntPtr.Zero) + { + Logger.Write($"libX11 XGetImage error"); + } var image = Marshal.PtrToStructure(imagePointer); diff --git a/Server.Installer/Models/WebServerType.cs b/Server.Installer/Models/WebServerType.cs index e7ad4db3a..309c5bdd6 100644 --- a/Server.Installer/Models/WebServerType.cs +++ b/Server.Installer/Models/WebServerType.cs @@ -14,6 +14,7 @@ public enum WebServerType UbuntuNginx, CentOsCaddy, CentOsNginx, - IisWindows + IisWindows, + LinuxNginx } } diff --git a/Server.Installer/Program.cs b/Server.Installer/Program.cs index ca418323d..145fe0ffa 100644 --- a/Server.Installer/Program.cs +++ b/Server.Installer/Program.cs @@ -103,7 +103,8 @@ public static async Task Main(string[] args) "Nginx on Ubuntu", "Caddy on CentOS", "Nginx on CentOS", - "IIS on Windows Server 2016+"); + "IIS on Windows Server 2016+", + "Nginx on linux-arm"); if (Enum.TryParse(webServerType, out var result)) { diff --git a/Server.Installer/Resources/LinuxArm_Nginx_Install.sh b/Server.Installer/Resources/LinuxArm_Nginx_Install.sh new file mode 100644 index 000000000..d811fc23e --- /dev/null +++ b/Server.Installer/Resources/LinuxArm_Nginx_Install.sh @@ -0,0 +1,169 @@ +#!/bin/bash +echo "Thanks for trying Remotely!" +echo + +Args=( "$@" ) +ArgLength=${#Args[@]} + +for (( i=0; i<${ArgLength}; i+=2 )); +do + if [ "${Args[$i]}" = "--host" ]; then + HostName="${Args[$i+1]}" + elif [ "${Args[$i]}" = "--approot" ]; then + AppRoot="${Args[$i+1]}" + fi +done + +if [ -z "$AppRoot" ]; then + read -p "Enter path where the Remotely server files should be installed (typically /var/www/remotely): " AppRoot + if [ -z "$AppRoot" ]; then + AppRoot="/var/www/remotely" + fi +fi + +if [ -z "$HostName" ]; then + read -p "Enter server host (e.g. remotely.yourdomainname.com): " HostName +fi + +chmod +x "$AppRoot/Remotely_Server" + +echo "Using $AppRoot as the Remotely website's content directory." + +UbuntuVersion=$(lsb_release -r -s) + +apt-get -y install curl +apt-get -y install software-properties-common +apt-get -y install gnupg + +# Install .NET Core Runtime. +# Install .NET Core Runtime. +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 6.0 +echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc +echo 'export PATH=$PATH:$HOME/.dotnet' >> ~/.bashrc +source ~/.bashrc + +# Install other prerequisites. +apt-get -y install unzip +apt-get -y install acl +apt-get -y install libc6-dev +apt-get -y install libgdiplus + + +# Set permissions on Remotely files. +setfacl -R -m u:www-data:rwx $AppRoot +chown -R "$USER":www-data $AppRoot +chmod +x "$AppRoot/Remotely_Server" + + +# Install Nginx +apt-get update +apt-get -y install nginx + +systemctl start nginx + + +# Configure Nginx +nginxConfig=" + +server { + listen 80; + server_name $HostName *.$HostName; + location / { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection keep-alive; + proxy_set_header Host \$host; + proxy_cache_bypass \$http_upgrade; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + + location /_blazor { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection \"upgrade\"; + proxy_set_header Host \$host; + proxy_cache_bypass \$http_upgrade; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + location /AgentHub { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection \"upgrade\"; + proxy_set_header Host \$host; + proxy_cache_bypass \$http_upgrade; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + location /ViewerHub { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection \"upgrade\"; + proxy_set_header Host \$host; + proxy_cache_bypass \$http_upgrade; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + location /CasterHub { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection \"upgrade\"; + proxy_set_header Host \$host; + proxy_cache_bypass \$http_upgrade; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } +}" + +echo "$nginxConfig" > /etc/nginx/sites-available/remotely + +ln -s /etc/nginx/sites-available/remotely /etc/nginx/sites-enabled/remotely + +# Test config. +nginx -t + +# Reload. +nginx -s reload + + + + +# Create service. + +serviceConfig="[Unit] +Description=Remotely Server + +[Service] +WorkingDirectory=$AppRoot +ExecStart=/home/pi/.dotnet/dotnet $AppRoot/Remotely_Server.dll +Restart=always +# Restart service after 10 seconds if the dotnet service crashes: +RestartSec=10 +SyslogIdentifier=remotely +User=www-data +Environment=ASPNETCORE_ENVIRONMENT=Production +Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false + +[Install] +WantedBy=multi-user.target" + +echo "$serviceConfig" > /etc/systemd/system/remotely.service + +chown -R www-data:www-data /var/www/remotely + +# Enable service. +systemctl enable remotely.service +# Start service. +systemctl restart remotely.service + + +# Install Certbot and get SSL cert. +apt-get -y install certbot python3-certbot-nginx + +certbot --nginx \ No newline at end of file diff --git a/Server.Installer/Services/ServerInstaller.cs b/Server.Installer/Services/ServerInstaller.cs index 5540530a7..b3073cfe7 100644 --- a/Server.Installer/Services/ServerInstaller.cs +++ b/Server.Installer/Services/ServerInstaller.cs @@ -136,6 +136,7 @@ private async Task LaunchExternalInstaller(CliParams cliParams) WebServerType.CentOsCaddy => "CentOS_Caddy_Install.sh", WebServerType.CentOsNginx => "CentOS_Nginx_Install.sh", WebServerType.IisWindows => "IIS_Windows_Install.ps1", + WebServerType.LinuxNginx => "LinuxArm_Nginx_Install.sh", _ => throw new Exception("Unrecognized reverse proxy type."), }; diff --git a/Server/API/ClientDownloadsController.cs b/Server/API/ClientDownloadsController.cs index 86e51f6fa..9c43b1585 100644 --- a/Server/API/ClientDownloadsController.cs +++ b/Server/API/ClientDownloadsController.cs @@ -50,6 +50,11 @@ public async Task GetDesktop(string platformID) var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "Linux-x64", "Remotely_Desktop"); return await GetDesktopFile(filePath); } + case "linux-arm": + { + var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "Linux-arm", "Remotely_Desktop"); + return await GetDesktopFile(filePath); + } case "MacOS-x64": { var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "MacOS-x64", "Remotely_Desktop"); @@ -86,6 +91,11 @@ public async Task GetDesktop(string platformId, string organizati var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "Linux-x64", "Remotely_Desktop"); return await GetDesktopFile(filePath, organizationId); } + case "linux-arm": + { + var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "Linux-arm", "Remotely_Desktop"); + return await GetDesktopFile(filePath, organizationId); + } case "MacOS-x64": { var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "MacOS-x64", "Remotely_Desktop"); @@ -190,6 +200,12 @@ private async Task GetInstallFile(string organizationId, string p { var fileName = "Install-Ubuntu-x64.sh"; + return await GetBashInstaller(fileName, organizationId); + } + case "armInstaller": + { + var fileName = "Install-arm.sh"; + return await GetBashInstaller(fileName, organizationId); } case "MacOSInstaller-x64": diff --git a/Server/Pages/Downloads.razor b/Server/Pages/Downloads.razor index 6e7efb13e..dfbc24025 100644 --- a/Server/Pages/Downloads.razor +++ b/Server/Pages/Downloads.razor @@ -32,6 +32,12 @@ Ubuntu Executable

+
+ Linux arm-32 +

+ Linux arm-32 Executable +

+
@*
macOS x64 (10.12 - 10.15)

@@ -176,6 +182,31 @@

+
+ Linux arm-32-Bit +

+ linux-arm-32bit Bash Installer +
+ Linux Files Only +

+

+

Example Install:
+ + sudo chmod +x [path]/Install-arm.sh + sudo [path]/./Install-arm.sh +

+

+

Example Local Install:
+ + sudo [path]/Install-arm.sh --path [path]/Remotely-Linux.zip +

+

+

Uninstall:
+ + sudo [path]/Install-arm.sh --uninstall +

+
+
macOS x64 (10.12 - 10.15)

diff --git a/Server/wwwroot/Content/Install-arm.sh b/Server/wwwroot/Content/Install-arm.sh new file mode 100644 index 000000000..94cda9a52 --- /dev/null +++ b/Server/wwwroot/Content/Install-arm.sh @@ -0,0 +1,114 @@ +#!/bin/bash +HostName= +Organization= +GUID=$(cat /proc/sys/kernel/random/uuid) +UpdatePackagePath="" + + +Args=( "$@" ) +ArgLength=${#Args[@]} + +for (( i=0; i<${ArgLength}; i+=2 )); +do + if [ "${Args[$i]}" = "--uninstall" ]; then + systemctl stop remotely-agent + rm -r -f /usr/local/bin/Remotely + rm -f /etc/systemd/system/remotely-agent.service + systemctl daemon-reload + exit + elif [ "${Args[$i]}" = "--path" ]; then + UpdatePackagePath="${Args[$i+1]}" + fi +done + +UbuntuVersion=$(lsb_release -r -s) + +# Install .NET Core Runtime. +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -c 6.0 +echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc +echo 'export PATH=$PATH:$HOME/.dotnet' >> ~/.bashrc +source ~/.bashrc + +apt-get -y install libx11-dev +apt-get -y install libxrandr-dev +apt-get -y install unzip +apt-get -y install libc6-dev +apt-get -y install libgdiplus +apt-get -y install libxtst-dev +apt-get -y install xclip +apt-get -y install jq +apt-get -y install curl + +sudo curl -fsSL https://deb.nodesource.com/setup_17.x | bash - +sudo apt install nodejs + +if [ -f "/usr/local/bin/Remotely/ConnectionInfo.json" ]; then + SavedGUID=`cat "/usr/local/bin/Remotely/ConnectionInfo.json" | jq -r '.DeviceID'` + if [[ "$SavedGUID" != "null" && -n "$SavedGUID" ]]; then + GUID="$SavedGUID" + fi +fi + +rm -r -f /usr/local/bin/Remotely +rm -f /etc/systemd/system/remotely-agent.service + +mkdir -p /usr/local/bin/Remotely/ +cd /usr/local/bin/Remotely/ + +if [ -z "$UpdatePackagePath" ]; then + echo "Downloading client..." >> /tmp/Remotely_Install.log + wget $HostName/Content/Remotely-Linux-arm.zip +else + echo "Copying install files..." >> /tmp/Remotely_Install.log + cp "$UpdatePackagePath" /usr/local/bin/Remotely/Remotely-Linux-arm.zip + rm -f "$UpdatePackagePath" +fi + +unzip ./Remotely-Linux-arm.zip +rm -f ./Remotely-Linux-arm.zip +chmod +x ./Remotely_Agent +chmod +x ./Desktop/Remotely_Desktop + + +connectionInfo="{ + \"DeviceID\":\"$GUID\", + \"Host\":\"$HostName\", + \"OrganizationID\": \"$Organization\", + \"ServerVerificationToken\":\"\" +}" + +echo "$connectionInfo" > ./ConnectionInfo.json + +runtimeOptions="{ + \"runtimeOptions\": { + \"configProperties\": { + \"System.Drawing.EnableUnixSupport\": true + } + } +}" + +echo "$runtimeOptions" > ./Desktop/Remotely_Desktop.runtimeconfig.json + +curl --head $HostName/Content/Remotely-Linux.zip | grep -i "etag" | cut -d' ' -f 2 > ./etag.txt + +echo Creating service... >> /tmp/Remotely_Install.log + +serviceConfig="[Unit] +Description=The Remotely agent used for remote access. + +[Service] +WorkingDirectory=/usr/local/bin/Remotely/ +ExecStart=/usr/local/bin/Remotely/Remotely_Agent +Restart=always +StartLimitIntervalSec=0 +RestartSec=10 + +[Install] +WantedBy=graphical.target" + +echo "$serviceConfig" > /etc/systemd/system/remotely-agent.service + +systemctl enable remotely-agent +systemctl restart remotely-agent + +echo Install complete. >> /tmp/Remotely_Install.log diff --git a/Shared/Utilities/EnvironmentHelper.cs b/Shared/Utilities/EnvironmentHelper.cs index 66379c020..6ff1ce84f 100644 --- a/Shared/Utilities/EnvironmentHelper.cs +++ b/Shared/Utilities/EnvironmentHelper.cs @@ -60,6 +60,8 @@ public static bool IsDebug public static bool IsWindows => OperatingSystem.IsWindows(); + public static bool Is64 => Environment.Is64BitProcess; + public static Platform Platform { get diff --git a/Utilities/Publish.ps1 b/Utilities/Publish.ps1 index 74c7a584a..ceb39797e 100644 --- a/Utilities/Publish.ps1 +++ b/Utilities/Publish.ps1 @@ -116,23 +116,30 @@ if ((Test-Path -Path "$Root\Agent\bin\Release\net6.0\win10-x86\publish" ) -eq $ if ((Test-Path -Path "$Root\Agent\bin\Release\net6.0\linux-x64\publish") -eq $true) { Get-ChildItem -Path "$Root\Agent\bin\Release\net6.0\linux-x64\publish" | Remove-Item -Force -Recurse } +if ((Test-Path -Path "$Root\Agent\bin\Release\net6.0\linux-arm\publish") -eq $true) { + Get-ChildItem -Path "$Root\Agent\bin\Release\net6.0\linux-arm\publish" | Remove-Item -Force -Recurse +} # Publish Core clients. dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime win10-x64 --self-contained --configuration Release --output "$Root\Agent\bin\Release\net6.0\win10-x64\publish" "$Root\Agent" dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime linux-x64 --self-contained --configuration Release --output "$Root\Agent\bin\Release\net6.0\linux-x64\publish" "$Root\Agent" dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime win10-x86 --self-contained --configuration Release --output "$Root\Agent\bin\Release\net6.0\win10-x86\publish" "$Root\Agent" +dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime linux-arm --self-contained --configuration Release --output "$Root\Agent\bin\Release\net6.0\linux-arm\publish" "$Root\Agent" New-Item -Path "$Root\Agent\bin\Release\net6.0\win10-x64\publish\Desktop\" -ItemType Directory -Force New-Item -Path "$Root\Agent\bin\Release\net6.0\win10-x86\publish\Desktop\" -ItemType Directory -Force New-Item -Path "$Root\Agent\bin\Release\net6.0\linux-x64\publish\Desktop\" -ItemType Directory -Force +New-Item -Path "$Root\Agent\bin\Release\net6.0\linux-arm\publish\Desktop\" -ItemType Directory -Force # Publish Linux ScreenCaster dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion -p:PublishProfile=packaged-linux-x64 --configuration Release "$Root\Desktop.XPlat\" +dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion -p:PublishProfile=packaged-linux-arm --configuration Release "$Root\Desktop.XPlat\" # Publish Linux GUI App dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion -p:PublishProfile=desktop-linux-x64 --configuration Release "$Root\Desktop.XPlat\" +dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion -p:PublishProfile=desktop-linux-arm --configuration Release "$Root\Desktop.XPlat\" # Publish Windows ScreenCaster (32-bit) @@ -159,7 +166,7 @@ if ($SignAssemblies) { &"$Root\Utilities\signtool.exe" sign /f "$CertificatePath" /p $CertificatePassword /t http://timestamp.digicert.com "$Root\Server\wwwroot\Content\Win-x86\Remotely_Desktop.exe" } -# Build installer. +# Build installer (Windows). &"$MSBuildPath" "$Root\Agent.Installer.Win" /t:Restore &"$MSBuildPath" "$Root\Agent.Installer.Win" /t:Build /p:Configuration=Release /p:Platform=AnyCPU /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion Copy-Item -Path "$Root\Agent.Installer.Win\bin\Release\Remotely_Installer.exe" -Destination "$Root\Server\wwwroot\Content\Remotely_Installer.exe" -Force @@ -189,6 +196,13 @@ while ((Test-Path -Path "$PublishDir\Remotely-Linux.zip") -eq $false){ } Move-Item -Path "$PublishDir\Remotely-Linux.zip" -Destination "$Root\Server\wwwroot\Content\Remotely-Linux.zip" -Force +$PublishDir = "$Root\Agent\bin\Release\net6.0\linux-arm\publish" +Compress-Archive -Path "$PublishDir\*" -DestinationPath "$PublishDir\Remotely-Linux-arm.zip" -Force +while ((Test-Path -Path "$PublishDir\Remotely-Linux-arm.zip") -eq $false){ + Start-Sleep -Seconds 1 +} +Move-Item -Path "$PublishDir\Remotely-Linux-arm.zip" -Destination "$Root\Server\wwwroot\Content\Remotely-Linux-arm.zip" -Force + if ($RID.Length -gt 0 -and $OutDir.Length -gt 0) {