mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Update Avalonia UI version.
This commit is contained in:
parent
fa6411b654
commit
767f6d18c3
@ -1,7 +1,7 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Remotely.Desktop.Unix;assembly=Remotely_Desktop"
|
||||
x:Class="Remotely.Desktop.Unix.App">
|
||||
xmlns:local="clr-namespace:Remotely.Desktop.Linux;assembly=Remotely_Desktop"
|
||||
x:Class="Remotely.Desktop.Linux.App">
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
</Application.DataTemplates>
|
||||
29
Desktop.Linux/App.xaml.cs
Normal file
29
Desktop.Linux/App.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Remotely.Desktop.Linux.ViewModels;
|
||||
using Remotely.Desktop.Linux.Views;
|
||||
|
||||
namespace Remotely.Desktop.Linux
|
||||
{
|
||||
public class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
DataContext = new MainWindowViewModel(),
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 477 B After Width: | Height: | Size: 477 B |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
@ -3,8 +3,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Remotely.Desktop.Unix.Controls.HostNamePrompt"
|
||||
xmlns:ViewModels="clr-namespace:Remotely.Desktop.Unix.ViewModels;assembly=Remotely_Desktop"
|
||||
x:Class="Remotely.Desktop.Linux.Controls.HostNamePrompt"
|
||||
xmlns:ViewModels="clr-namespace:Remotely.Desktop.Linux.ViewModels;assembly=Remotely_Desktop"
|
||||
Title="Remotely Host Name" Height="150" Width="350" WindowStartupLocation="CenterOwner">
|
||||
<Window.DataContext>
|
||||
<ViewModels:HostNamePromptViewModel/>
|
||||
@ -1,8 +1,9 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Remotely.Desktop.Linux.Views;
|
||||
|
||||
namespace Remotely.Desktop.Unix.Controls
|
||||
namespace Remotely.Desktop.Linux.Controls
|
||||
{
|
||||
public class HostNamePrompt : Window
|
||||
{
|
||||
@ -17,7 +18,7 @@ namespace Remotely.Desktop.Unix.Controls
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
this.Icon = App.Current?.MainWindow?.Icon;
|
||||
this.Icon = MainWindow.Current?.Icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,8 +3,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
xmlns:vm="clr-namespace:Remotely.Desktop.Unix.ViewModels;assembly=Remotely_Desktop"
|
||||
x:Class="Remotely.Desktop.Unix.Controls.MessageBox"
|
||||
xmlns:vm="clr-namespace:Remotely.Desktop.Linux.ViewModels;assembly=Remotely_Desktop"
|
||||
x:Class="Remotely.Desktop.Linux.Controls.MessageBox"
|
||||
Title="{Binding Caption}" SizeToContent="WidthAndHeight" MinWidth="200" MinHeight="100" WindowStartupLocation="CenterOwner">
|
||||
<Window.DataContext>
|
||||
<vm:MessageBoxViewModel></vm:MessageBoxViewModel>
|
||||
@ -1,10 +1,11 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Remotely.Desktop.Unix.ViewModels;
|
||||
using Remotely.Desktop.Linux.ViewModels;
|
||||
using Remotely.Desktop.Linux.Views;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Desktop.Unix.Controls
|
||||
namespace Remotely.Desktop.Linux.Controls
|
||||
{
|
||||
public class MessageBox : Window
|
||||
{
|
||||
@ -29,11 +30,11 @@ namespace Remotely.Desktop.Unix.Controls
|
||||
|
||||
messageBox.DataContext = viewModel;
|
||||
|
||||
await messageBox.ShowDialog(App.Current.MainWindow);
|
||||
await messageBox.ShowDialog(MainWindow.Current);
|
||||
|
||||
return viewModel.Result;
|
||||
}
|
||||
private MessageBox()
|
||||
public MessageBox()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
#if DEBUG
|
||||
@ -46,7 +47,7 @@ namespace Remotely.Desktop.Unix.Controls
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
this.Icon = App.Current?.MainWindow?.Icon;
|
||||
this.Icon = MainWindow.Current?.Icon;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ApplicationIcon>Assets\favicon.ico</ApplicationIcon>
|
||||
<AssemblyName>Remotely_Desktop</AssemblyName>
|
||||
<RootNamespace>Remotely.Desktop.Unix</RootNamespace>
|
||||
<RootNamespace>Remotely.Desktop.Linux</RootNamespace>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
@ -32,9 +32,9 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.8.3" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.8.3" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.8.3" />
|
||||
<PackageReference Include="Avalonia" Version="0.9.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.9.0" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ScreenCast.Core\ScreenCast.Core.csproj" />
|
||||
@ -1,35 +1,25 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Logging.Serilog;
|
||||
using Remotely.Desktop.Unix.ViewModels;
|
||||
using Remotely.Desktop.Unix.Views;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Remotely.Desktop.Linux.ViewModels;
|
||||
using Remotely.Desktop.Linux.Views;
|
||||
|
||||
namespace Remotely.Desktop.Unix
|
||||
namespace Remotely.Desktop.Linux
|
||||
{
|
||||
class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
public static void Main(string[] args) => BuildAvaloniaApp().Start(AppMain, args);
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToDebug();
|
||||
|
||||
// Your application's entry point. Here you can initialize your MVVM framework, DI
|
||||
// container, etc.
|
||||
private static void AppMain(Application app, string[] args)
|
||||
{
|
||||
var window = new MainWindow
|
||||
{
|
||||
DataContext = new MainWindowViewModel(),
|
||||
};
|
||||
|
||||
app.Run(window);
|
||||
|
||||
}
|
||||
.LogToDebug()
|
||||
.UseReactiveUI();
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
@ -7,7 +7,7 @@ using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Desktop.Unix.Services
|
||||
namespace Remotely.Desktop.Linux.Services
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
@ -5,7 +5,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Remotely.Desktop.Unix.Services
|
||||
namespace Remotely.Desktop.Linux.Services
|
||||
{
|
||||
public class Executor : ICommand
|
||||
{
|
||||
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Remotely.Desktop.Unix.ViewModels;
|
||||
using Remotely.Desktop.Linux.ViewModels;
|
||||
|
||||
namespace Remotely.Desktop.Unix
|
||||
namespace Remotely.Desktop.Linux
|
||||
{
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Controls;
|
||||
using ReactiveUI;
|
||||
using Remotely.Desktop.Unix.Services;
|
||||
using Remotely.Desktop.Linux.Services;
|
||||
|
||||
namespace Remotely.Desktop.Unix.ViewModels
|
||||
namespace Remotely.Desktop.Linux.ViewModels
|
||||
{
|
||||
public class HostNamePromptViewModel : ViewModelBase
|
||||
{
|
||||
@ -2,8 +2,9 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using Remotely.Desktop.Unix.Controls;
|
||||
using Remotely.Desktop.Unix.Services;
|
||||
using Remotely.Desktop.Linux.Controls;
|
||||
using Remotely.Desktop.Linux.Services;
|
||||
using Remotely.Desktop.Linux.Views;
|
||||
using Remotely.ScreenCast.Core;
|
||||
using Remotely.ScreenCast.Core.Capture;
|
||||
using Remotely.ScreenCast.Core.Interfaces;
|
||||
@ -25,7 +26,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Remotely.Desktop.Unix.ViewModels
|
||||
namespace Remotely.Desktop.Linux.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : ReactiveObject
|
||||
{
|
||||
@ -37,6 +38,10 @@ namespace Remotely.Desktop.Unix.ViewModels
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
Current = this;
|
||||
if (!OSUtils.IsLinux)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var screenCaster = new LinuxScreenCaster();
|
||||
var casterSocket = new CasterSocket(new X11Input(), screenCaster, new LinuxAudioCapturer(), new LinuxClipboardService());
|
||||
Conductor = new Conductor(casterSocket, screenCaster);
|
||||
@ -140,11 +145,6 @@ namespace Remotely.Desktop.Unix.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
if (OSUtils.IsWindows)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await Conductor.CasterSocket.SendDeviceInfo(Conductor.ServiceID, Environment.MachineName, Conductor.DeviceID);
|
||||
await Conductor.CasterSocket.GetSessionID();
|
||||
}
|
||||
@ -156,8 +156,8 @@ namespace Remotely.Desktop.Unix.ViewModels
|
||||
{
|
||||
HostNamePromptViewModel.Current.Host = Host;
|
||||
}
|
||||
prompt.Owner = App.Current?.MainWindow;
|
||||
await prompt.ShowDialog(App.Current?.MainWindow);
|
||||
prompt.Owner = MainWindow.Current;
|
||||
await prompt.ShowDialog(MainWindow.Current);
|
||||
var result = HostNamePromptViewModel.Current.Host.TrimEnd("/".ToCharArray());
|
||||
if (result != Host)
|
||||
{
|
||||
@ -1,12 +1,12 @@
|
||||
using Avalonia.Controls;
|
||||
using Remotely.Desktop.Unix.Controls;
|
||||
using Remotely.Desktop.Unix.Services;
|
||||
using Remotely.Desktop.Linux.Controls;
|
||||
using Remotely.Desktop.Linux.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Remotely.Desktop.Unix.ViewModels
|
||||
namespace Remotely.Desktop.Linux.ViewModels
|
||||
{
|
||||
public class MessageBoxViewModel : ViewModelBase
|
||||
{
|
||||
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Remotely.Desktop.Unix.ViewModels
|
||||
namespace Remotely.Desktop.Linux.ViewModels
|
||||
{
|
||||
public class ViewModelBase : ReactiveObject
|
||||
{
|
||||
@ -1,14 +1,14 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:Remotely.Desktop.Unix.ViewModels;assembly=Remotely_Desktop"
|
||||
xmlns:vm="clr-namespace:Remotely.Desktop.Linux.ViewModels;assembly=Remotely_Desktop"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Remotely.Desktop.Unix.Views.MainWindow"
|
||||
x:Class="Remotely.Desktop.Linux.Views.MainWindow"
|
||||
Icon="/Assets/favicon.ico"
|
||||
Title="Remotely" Height="275" Width="350" HasSystemDecorations="False">
|
||||
<Window.DataContext>
|
||||
<vm:MainWindowViewModel/>
|
||||
<vm:MainWindowViewModel />
|
||||
</Window.DataContext>
|
||||
<Grid>
|
||||
<StackPanel>
|
||||
@ -1,15 +1,18 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Remotely.Desktop.Unix.ViewModels;
|
||||
using Remotely.Desktop.Linux.ViewModels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Desktop.Unix.Views
|
||||
namespace Remotely.Desktop.Linux.Views
|
||||
{
|
||||
public class MainWindow : Window
|
||||
{
|
||||
public static MainWindow Current { get; set; }
|
||||
public MainWindow()
|
||||
{
|
||||
Current = this;
|
||||
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
@ -18,23 +21,19 @@ namespace Remotely.Desktop.Unix.Views
|
||||
|
||||
private void TitleBanner_PointerPressed(object sender, Avalonia.Input.PointerPressedEventArgs e)
|
||||
{
|
||||
if (e.MouseButton == Avalonia.Input.MouseButton.Left)
|
||||
if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == Avalonia.Input.PointerUpdateKind.LeftButtonPressed)
|
||||
{
|
||||
this.BeginMoveDrag();
|
||||
this.BeginMoveDrag(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async void InitializeComponent()
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
this.FindControl<Border>("TitleBanner").PointerPressed += TitleBanner_PointerPressed;
|
||||
|
||||
while (App.Current.MainWindow == null)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
}
|
||||
await MainWindowViewModel.Current.Init();
|
||||
_ = (this.DataContext as MainWindowViewModel).Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Remotely.Desktop.Unix
|
||||
{
|
||||
public class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScreenCast.Core", "ScreenCa
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{3B1B36AE-7A60-4974-A868-1E24894D4149}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Desktop.Unix", "Desktop.Unix\Desktop.Unix.csproj", "{FF7FD66A-B3E2-4D39-A457-A00C94EDE9E6}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Desktop.Linux", "Desktop.Linux\Desktop.Linux.csproj", "{FF7FD66A-B3E2-4D39-A457-A00C94EDE9E6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
<p>
|
||||
<strong>Download:</strong>
|
||||
<br />
|
||||
<a href="~/Downloads/Remotely_Desktop.Unix.zip">Linux Zipped</a>
|
||||
<a href="~/Downloads/Remotely_Desktop.Linux.zip">Linux Zipped</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -80,7 +80,7 @@ if ($Hostname.Length -gt 0) {
|
||||
Replace-LineInFile -FilePath "$Root\Desktop.Win\Desktop.Win.csproj" -MatchPattern "<InstallUrl>" -ReplaceLineWith "<InstallUrl>$($Hostname)/Downloads/WinDesktop/</InstallUrl>" -MaxCount 1
|
||||
Replace-LineInFile -FilePath "$Root\Desktop.Win\Desktop.Win.csproj" -MatchPattern "<UpdateUrl>" -ReplaceLineWith "<UpdateUrl>$($Hostname)/Downloads/WinDesktop/</UpdateUrl>" -MaxCount 1
|
||||
Replace-LineInFile -FilePath "$Root\Desktop.Win\Services\Config.cs" -MatchPattern "public string Host " -ReplaceLineWith "public string Host { get; set; } = `"$($Hostname)`";" -MaxCount 1
|
||||
Replace-LineInFile -FilePath "$Root\Desktop.Unix\Services\Config.cs" -MatchPattern "public string Host " -ReplaceLineWith "public string Host { get; set; } = `"$($Hostname)`";" -MaxCount 1
|
||||
Replace-LineInFile -FilePath "$Root\Desktop.Linux\Services\Config.cs" -MatchPattern "public string Host " -ReplaceLineWith "public string Host { get; set; } = `"$($Hostname)`";" -MaxCount 1
|
||||
}
|
||||
else {
|
||||
Write-Host "`nERROR: No hostname parameter was specified. Application auto-updates will default to the public test server. Please supply your server's hostname.`n" -ForegroundColor Red
|
||||
@ -115,14 +115,14 @@ New-Item -Path "$Root\Agent\bin\Release\netcoreapp3.1\linux-x64\publish\ScreenCa
|
||||
dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime linux-x64 --configuration Release --output "$Root\Agent\bin\Release\netcoreapp3.1\linux-x64\publish\ScreenCast\" "$Root\ScreenCast.Linux\"
|
||||
|
||||
# Publish Linux GUI App
|
||||
$PublishDir = "$Root\Desktop.Unix\bin\Release\netcoreapp3.1\linux-x64\publish\"
|
||||
dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime linux-x64 --configuration Release --output "$PublishDir" "$Root\Desktop.Unix\"
|
||||
$PublishDir = "$Root\Desktop.Linux\bin\Release\netcoreapp3.1\linux-x64\publish\"
|
||||
dotnet publish /p:Version=$CurrentVersion /p:FileVersion=$CurrentVersion --runtime linux-x64 --configuration Release --output "$PublishDir" "$Root\Desktop.Linux\"
|
||||
# Compress Linux GUI App
|
||||
Compress-Archive -Path "$PublishDir\*" -DestinationPath "$PublishDir\Remotely_Desktop.Unix.zip" -CompressionLevel Optimal -Force
|
||||
while ((Test-Path -Path "$PublishDir\Remotely_Desktop.Unix.zip") -eq $false){
|
||||
Compress-Archive -Path "$PublishDir\*" -DestinationPath "$PublishDir\Remotely_Desktop.Linux.zip" -CompressionLevel Optimal -Force
|
||||
while ((Test-Path -Path "$PublishDir\Remotely_Desktop.Linux.zip") -eq $false){
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
Move-Item -Path "$PublishDir\Remotely_Desktop.Unix.zip" -Destination "$Root\Server\wwwroot\Downloads\Remotely_Desktop.Unix.zip" -Force
|
||||
Move-Item -Path "$PublishDir\Remotely_Desktop.Linux.zip" -Destination "$Root\Server\wwwroot\Downloads\Remotely_Desktop.Linux.zip" -Force
|
||||
|
||||
|
||||
# Build .NET Framework ScreenCaster (32-bit)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user