mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Installer app completed.
This commit is contained in:
parent
b41659a10e
commit
30b2c5afaa
@ -50,10 +50,12 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
@ -72,10 +74,18 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Models\InstallerSettings.cs" />
|
||||
<Compile Include="..\Shared\Models\ConnectionInfo.cs">
|
||||
<Link>Models\ConnectionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Models\InstallerSettings.cs">
|
||||
<Link>Models\InstallerSettings.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Services\CommandLineParser.cs" />
|
||||
<Compile Include="Services\MessageBoxWrapper.cs" />
|
||||
<Compile Include="Services\Executor.cs" />
|
||||
<Compile Include="Services\InstallerService.cs" />
|
||||
<Compile Include="Services\Logger.cs" />
|
||||
<Compile Include="Services\ProcessWrapper.cs" />
|
||||
<Compile Include="ViewModels\MainWindowViewModel.cs" />
|
||||
<Compile Include="ViewModels\ViewModelBase.cs" />
|
||||
<Page Include="MainWindow.xaml">
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Remotely.Agent.Installer.Win"
|
||||
StartupUri="MainWindow.xaml" Startup="App_Startup">
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
<Style x:Key="TitlebarButton" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF464646"></Setter>
|
||||
@ -25,6 +25,7 @@
|
||||
<Setter Property="BorderThickness" Value="1"></Setter>
|
||||
<Setter Property="BorderBrush" Value="Black"></Setter>
|
||||
<Setter Property="Padding" Value="6,4"></Setter>
|
||||
<Setter Property="FontSize" Value="14"></Setter>
|
||||
</Style>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@ -17,24 +17,6 @@ namespace Remotely.Agent.Installer.Win
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
public void App_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
if (e.Args.Contains("-uninstall"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Write("Uninstall command received. Preparing temp directory.");
|
||||
var targetPath = Path.Combine(Path.GetTempPath(), "Remotely_Installer.exe");
|
||||
File.Copy(Assembly.GetExecutingAssembly().Location, targetPath, true);
|
||||
Logger.Write("Launching uninstaller.");
|
||||
Process.Start(targetPath, "-rununinstall");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,11 @@
|
||||
xmlns:local="clr-namespace:Remotely.Agent.Installer.Win"
|
||||
mc:Ignorable="d"
|
||||
WindowStyle="None"
|
||||
ResizeMode="NoResize"
|
||||
ResizeMode="CanResizeWithGrip"
|
||||
AllowsTransparency="True"
|
||||
MouseLeftButtonDown="Window_MouseLeftButtonDown"
|
||||
Loaded="Window_Loaded"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="Remotely Installer" Height="325" Width="500" Icon="Assets/favicon.ico">
|
||||
<Window.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
@ -36,17 +38,25 @@
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource SectionHeader}" Text="{Binding HeaderMessage}"></TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" Margin="25,5,0,0">
|
||||
<Run>Provider: </Run>
|
||||
<Run Text="{Binding OrganizationName}"></Run>
|
||||
</TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" Margin="25,5,0,0">
|
||||
<Run>Server URL: </Run>
|
||||
<Run Text="{Binding ServerUrl}"></Run>
|
||||
</TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" Margin="0,15,0,0" Text="{Binding SubMessage}"></TextBlock>
|
||||
<ProgressBar Height="25" Margin="0,25,0,0" Value="{Binding Progress}" Visibility="{Binding IsProgressVisible, Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar>
|
||||
<TextBlock TextWrapping="Wrap" Margin="0,15,0,0" Text="{Binding StatusMessage}"></TextBlock>
|
||||
<Grid Margin="25,5,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Text="Provider:" Margin="0,0,15,0" FontSize="14" />
|
||||
<TextBox Grid.Column="1" Grid.Row="0" IsReadOnly="True" Margin="0,0,0,10" TextWrapping="Wrap" Text="{Binding OrganizationName}" FontSize="14" />
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="0,0,15,0" Text="Server URL:" FontSize="14" />
|
||||
<TextBox Grid.Column="1" Grid.Row="1" IsReadOnly="True" TextWrapping="Wrap" Text="{Binding ServerUrl}" FontSize="14" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock TextWrapping="Wrap" Margin="0,25,0,0" Text="{Binding StatusMessage}" FontSize="14"></TextBlock>
|
||||
<ProgressBar Height="25" Margin="0,10,0,0" Value="{Binding Progress}" Visibility="{Binding IsProgressVisible, Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
@ -70,6 +80,7 @@
|
||||
HorizontalAlignment="Right"
|
||||
Style="{StaticResource NormalButton}"
|
||||
Margin="5,0,0,0"
|
||||
IsEnabled="{Binding IsReadyState}"
|
||||
Visibility="{Binding IsServiceMissing, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Command="{Binding InstallCommand}">
|
||||
Install
|
||||
@ -78,6 +89,7 @@
|
||||
HorizontalAlignment="Right"
|
||||
Style="{StaticResource NormalButton}"
|
||||
Margin="5,0,0,0"
|
||||
IsEnabled="{Binding IsReadyState}"
|
||||
Visibility="{Binding IsServiceInstalled, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Command="{Binding UninstallCommand}">
|
||||
Uninstall
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Remotely.Agent.Installer.Win.ViewModels;
|
||||
using Remotely.Agent.Installer.Win.Services;
|
||||
using Remotely.Agent.Installer.Win.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -23,6 +24,12 @@ namespace Remotely.Agent.Installer.Win
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
if (CommandLineParser.CommandLineArgs.ContainsKey("quiet"))
|
||||
{
|
||||
Hide();
|
||||
ShowInTaskbar = false;
|
||||
_ = new MainWindowViewModel().Init();
|
||||
}
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@ -31,9 +38,9 @@ namespace Remotely.Agent.Installer.Win
|
||||
DragMove();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
private async void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
(DataContext as MainWindowViewModel).Init();
|
||||
await (DataContext as MainWindowViewModel).Init();
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Agent.Installer.Win
|
||||
{
|
||||
[DataContract]
|
||||
public class InstallerSettings
|
||||
{
|
||||
[DataMember]
|
||||
public string OrganizationID { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public string OrganizationName { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public string ServerUrl { get; set; }
|
||||
}
|
||||
}
|
||||
67
Agent.Installer.Win/Services/CommandLineParser.cs
Normal file
67
Agent.Installer.Win/Services/CommandLineParser.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Remotely.Agent.Installer.Win.Services
|
||||
{
|
||||
public class CommandLineParser
|
||||
{
|
||||
private static Dictionary<string, string> commandLineArgs;
|
||||
public static Dictionary<string, string> CommandLineArgs
|
||||
{
|
||||
get
|
||||
{
|
||||
if (commandLineArgs is null)
|
||||
{
|
||||
commandLineArgs = new Dictionary<string, string>();
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
for (var i = 1; i < args.Length; i += 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var key = args?[i];
|
||||
if (key != null)
|
||||
{
|
||||
if (!key.Contains("-"))
|
||||
{
|
||||
Logger.Write("Command line arguments are invalid.");
|
||||
MessageBoxWrapper.Show("Command line arguments are invalid.", "Invalid Arguments", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
i -= 1;
|
||||
continue;
|
||||
}
|
||||
key = key.Trim().Replace("-", "").ToLower();
|
||||
if (i + 1 == args.Length)
|
||||
{
|
||||
commandLineArgs.Add(key, "true");
|
||||
continue;
|
||||
}
|
||||
var value = args?[i + 1];
|
||||
if (value != null)
|
||||
{
|
||||
if (value.StartsWith("-"))
|
||||
{
|
||||
commandLineArgs.Add(key, "true");
|
||||
i -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
commandLineArgs.Add(key, args[i + 1].Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return commandLineArgs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,38 +1,74 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using Remotely.Shared.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration.Install;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Windows;
|
||||
|
||||
namespace Remotely.Agent.Installer.Win.Services
|
||||
{
|
||||
public class InstallerService
|
||||
{
|
||||
public bool Install()
|
||||
public event EventHandler<string> ProgressMessageChanged;
|
||||
public event EventHandler<int> ProgressValueChanged;
|
||||
|
||||
private string InstallPath => Path.Combine(Path.GetPathRoot(Environment.SystemDirectory), "Program Files", "Remotely");
|
||||
private string Platform => Environment.Is64BitOperatingSystem ? "x64" : "x86";
|
||||
private JavaScriptSerializer Serializer { get; } = new JavaScriptSerializer();
|
||||
public async Task<bool> Install(string serverUrl,
|
||||
string organizationId,
|
||||
string deviceGroup,
|
||||
string deviceAlias)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Write("Install started.");
|
||||
if (!CheckIsAdministrator())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await InstallDesktpRuntimeIfNeeded();
|
||||
|
||||
StopService();
|
||||
|
||||
BackupOrCreateDirectory();
|
||||
|
||||
var connectionInfo = GetConnectionInfo(organizationId, serverUrl);
|
||||
|
||||
ClearInstallDirectory();
|
||||
|
||||
await DownloadRemotelyAgent(serverUrl);
|
||||
|
||||
File.WriteAllText(Path.Combine(InstallPath, "ConnectionInfo.json"), Serializer.Serialize(connectionInfo));
|
||||
|
||||
File.Copy(Assembly.GetExecutingAssembly().Location, Path.Combine(InstallPath, "Remotely_Installer.exe"));
|
||||
|
||||
CreateDeviceSetupOptions(deviceGroup, deviceAlias);
|
||||
|
||||
AddFirewallRule();
|
||||
|
||||
InstallService();
|
||||
|
||||
var programPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Remotely", "ScreenCast", "Remotely_ScreenCast.exe");
|
||||
Process.Start("netsh", "advfirewall firewall delete rule name=\"Remotely ScreenCast\"").WaitForExit();
|
||||
Process.Start("netsh", $"advfirewall firewall add rule name=\"Remotely ScreenCast\" program=\"{programPath}\" protocol=any dir=in enable=yes action=allow profile=Private,Domain description=\"The agent that allows screen sharing and remote control for Remotely.\"").WaitForExit();
|
||||
CreateUninstallKey();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
RestoreBackup();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -47,8 +83,12 @@ namespace Remotely.Agent.Installer.Win.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
Process.Start("cmd.exe", "/c sc delete Remotely_Service").WaitForExit();
|
||||
StopService();
|
||||
|
||||
ProcessWrapper.StartHidden("cmd.exe", "/c sc delete Remotely_Service").WaitForExit();
|
||||
|
||||
|
||||
ProgressMessageChanged?.Invoke(this, "Stopping Remotely processes.");
|
||||
var procs = Process.GetProcessesByName("Remotely_Agent").Concat(Process.GetProcessesByName("Remotely_ScreenCast"));
|
||||
|
||||
foreach (var proc in procs)
|
||||
@ -58,9 +98,13 @@ namespace Remotely.Agent.Installer.Win.Services
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
Directory.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Remotely"), true);
|
||||
ProgressMessageChanged?.Invoke(this, "Deleting files.");
|
||||
ClearInstallDirectory();
|
||||
ProcessWrapper.StartHidden("cmd.exe", $"/c timeout 5 & rd /s /q \"{InstallPath}\"");
|
||||
|
||||
Process.Start("netsh", "advfirewall firewall delete rule name=\"Remotely ScreenCast\"").WaitForExit();
|
||||
ProcessWrapper.StartHidden("netsh", "advfirewall firewall delete rule name=\"Remotely ScreenCast\"").WaitForExit();
|
||||
|
||||
Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Remotely", false);
|
||||
|
||||
return true;
|
||||
|
||||
@ -72,6 +116,32 @@ namespace Remotely.Agent.Installer.Win.Services
|
||||
}
|
||||
}
|
||||
|
||||
private void AddFirewallRule()
|
||||
{
|
||||
var screenCastPath = Path.Combine(InstallPath, "ScreenCast", "Remotely_ScreenCast.exe");
|
||||
ProcessWrapper.StartHidden("netsh", "advfirewall firewall delete rule name=\"Remotely ScreenCast\"").WaitForExit();
|
||||
ProcessWrapper.StartHidden("netsh", $"advfirewall firewall add rule name=\"Remotely ScreenCast\" program=\"{screenCastPath}\" protocol=any dir=in enable=yes action=allow profile=Private,Domain description=\"The agent that allows screen sharing and remote control for Remotely.\"").WaitForExit();
|
||||
}
|
||||
|
||||
private void BackupOrCreateDirectory()
|
||||
{
|
||||
if (Directory.Exists(InstallPath))
|
||||
{
|
||||
Logger.Write("Backing up current installation.");
|
||||
ProgressMessageChanged?.Invoke(this, "Backing up current installation.");
|
||||
var backupPath = Path.Combine(Path.GetTempPath(), "Remotely_Backup.zip");
|
||||
if (File.Exists(backupPath))
|
||||
{
|
||||
File.Delete(backupPath);
|
||||
}
|
||||
ZipFile.CreateFromDirectory(InstallPath, backupPath, CompressionLevel.Fastest, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Directory.CreateDirectory(InstallPath);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckIsAdministrator()
|
||||
{
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
@ -79,19 +149,159 @@ namespace Remotely.Agent.Installer.Win.Services
|
||||
var result = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
if (!result)
|
||||
{
|
||||
MessageBox.Show("Elevated privileges are required. Please restart the installer using 'Run as administrator'.", "Elevation Required", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBoxWrapper.Show("Elevated privileges are required. Please restart the installer using 'Run as administrator'.", "Elevation Required", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ClearInstallDirectory()
|
||||
{
|
||||
if (Directory.Exists(InstallPath))
|
||||
{
|
||||
foreach (var entry in Directory.GetFileSystemEntries(InstallPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(entry))
|
||||
{
|
||||
File.Delete(entry);
|
||||
}
|
||||
else if (Directory.Exists(entry))
|
||||
{
|
||||
Directory.Delete(entry, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDeviceSetupOptions(string deviceGroup, string deviceAlias)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(deviceGroup) ||
|
||||
!string.IsNullOrWhiteSpace(deviceAlias))
|
||||
{
|
||||
var setupOptions = new
|
||||
{
|
||||
DeviceGroup = deviceGroup,
|
||||
DeviceAlias = deviceAlias
|
||||
};
|
||||
|
||||
File.WriteAllText(Path.Combine(InstallPath, "DeviceSetupOptions.json"), Serializer.Serialize(setupOptions));
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateUninstallKey()
|
||||
{
|
||||
var remotelyKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Remotely", true);
|
||||
remotelyKey.SetValue("DisplayIcon", Path.Combine(InstallPath, "Remotely_Agent.exe"));
|
||||
remotelyKey.SetValue("DisplayName", "Remotely");
|
||||
remotelyKey.SetValue("DisplayVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
remotelyKey.SetValue("InstallDate", DateTime.Now.ToShortDateString());
|
||||
remotelyKey.SetValue("Publisher", "Translucency Software");
|
||||
remotelyKey.SetValue("VersionMajor", Assembly.GetExecutingAssembly().GetName().Version.Major.ToString(), RegistryValueKind.DWord);
|
||||
remotelyKey.SetValue("VersionMinor", Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString(), RegistryValueKind.DWord);
|
||||
remotelyKey.SetValue("UninstallString", Path.Combine(InstallPath, "Remotely_Installer.exe -uninstall"));
|
||||
remotelyKey.SetValue("QuietUninstallString", Path.Combine(InstallPath, "Remotely_Installer.exe -uninstall -quiet"));
|
||||
}
|
||||
private async Task DownloadRemotelyAgent(string serverUrl)
|
||||
{
|
||||
ProgressMessageChanged.Invoke(this, "Downloading Remotely agent.");
|
||||
var client = new WebClient();
|
||||
client.DownloadProgressChanged += (sender, args) =>
|
||||
{
|
||||
ProgressValueChanged?.Invoke(this, args.ProgressPercentage);
|
||||
};
|
||||
var targetFile = Path.Combine(Path.GetTempPath(), $"Remotely-Agent.zip");
|
||||
await client.DownloadFileTaskAsync($"{serverUrl}/Downloads/Remotely-Win10-{Platform}.zip", targetFile);
|
||||
|
||||
ProgressMessageChanged.Invoke(this, "Extracting Remotely files.");
|
||||
ProgressValueChanged?.Invoke(this, 0);
|
||||
await Task.Run(() => { ZipFile.ExtractToDirectory(targetFile, InstallPath); });
|
||||
}
|
||||
|
||||
private ConnectionInfo GetConnectionInfo(string organizationId, string serverUrl)
|
||||
{
|
||||
ConnectionInfo connectionInfo;
|
||||
var connectionInfoPath = Path.Combine(InstallPath, "ConnectionInfo.json");
|
||||
if (File.Exists(connectionInfoPath))
|
||||
{
|
||||
connectionInfo = Serializer.Deserialize<ConnectionInfo>(File.ReadAllText(connectionInfoPath));
|
||||
connectionInfo.ServerVerificationToken = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionInfo = new ConnectionInfo()
|
||||
{
|
||||
DeviceID = Guid.NewGuid().ToString()
|
||||
};
|
||||
}
|
||||
|
||||
connectionInfo.OrganizationID = organizationId;
|
||||
connectionInfo.Host = serverUrl;
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
private async Task InstallDesktpRuntimeIfNeeded()
|
||||
{
|
||||
Logger.Write("Checking for .NET Core runtime.");
|
||||
var uninstallKeys = new List<RegistryKey>();
|
||||
var runtimeInstalled = false;
|
||||
|
||||
foreach (var subkeyName in Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", false).GetSubKeyNames())
|
||||
{
|
||||
var subkey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" + subkeyName, false);
|
||||
if (subkey?.GetValue("DisplayName")?.ToString()?.Contains("Microsoft Windows Desktop Runtime - 3.1.2") == true)
|
||||
{
|
||||
runtimeInstalled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!runtimeInstalled)
|
||||
{
|
||||
Logger.Write("Downloading .NET Core runtime.");
|
||||
ProgressMessageChanged.Invoke(this, "Downloading the .NET Core runtime.");
|
||||
var client = new WebClient();
|
||||
client.DownloadProgressChanged += (sender, args) =>
|
||||
{
|
||||
ProgressValueChanged?.Invoke(this, args.ProgressPercentage);
|
||||
};
|
||||
var downloadUrl = string.Empty;
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
downloadUrl = "https://download.visualstudio.microsoft.com/download/pr/3240250e-6fe0-4258-af69-85abef6c00de/e01ee0af6c65d894f4a02bdf6705ec7b/windowsdesktop-runtime-3.1.2-win-x64.exe";
|
||||
}
|
||||
else
|
||||
{
|
||||
downloadUrl = "https://download.visualstudio.microsoft.com/download/pr/b824906f-bd6e-4067-86a6-95c61620674d/cfcdab84a01cee94fdaa31271c3d4d47/windowsdesktop-runtime-3.1.2-win-x86.exe";
|
||||
}
|
||||
var targetFile = Path.Combine(Path.GetTempPath(), "windowsdesktop-runtime.exe");
|
||||
await client.DownloadFileTaskAsync(downloadUrl, targetFile);
|
||||
|
||||
Logger.Write("Installing .NET Core runtime.");
|
||||
ProgressMessageChanged?.Invoke(this, "Installing the .NET Core runtime.");
|
||||
ProgressValueChanged?.Invoke(this, 0);
|
||||
|
||||
await Task.Run(() => { ProcessWrapper.StartHidden(targetFile, "/install /quiet /norestart").WaitForExit(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Write(".NET Core runtime already installed.");
|
||||
}
|
||||
}
|
||||
|
||||
private void InstallService()
|
||||
{
|
||||
Logger.Write("Install started.");
|
||||
var installPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||
Logger.Write("Installing service.");
|
||||
ProgressMessageChanged?.Invoke(this, "Installing Remotely service.");
|
||||
var serv = ServiceController.GetServices().FirstOrDefault(ser => ser.ServiceName == "Remotely_Service");
|
||||
if (serv == null)
|
||||
{
|
||||
var command = new string[] { "/assemblypath=" + installPath };
|
||||
var command = new string[] { "/assemblypath=" + Path.Combine(InstallPath, "Remotely_Agent.exe") };
|
||||
var serviceInstaller = new ServiceInstaller();
|
||||
var context = new InstallContext("", command);
|
||||
serviceInstaller.Context = context;
|
||||
@ -104,16 +314,51 @@ namespace Remotely.Agent.Installer.Win.Services
|
||||
var state = new System.Collections.Specialized.ListDictionary();
|
||||
serviceInstaller.Install(state);
|
||||
Logger.Write("Service installed.");
|
||||
serv = ServiceController.GetServices().FirstOrDefault(ser => ser.ServiceName == "Remotely_Service");
|
||||
|
||||
ProcessWrapper.StartHidden("cmd.exe", "/c sc.exe failure \"Remotely_Service\" reset=5 actions=restart/5000");
|
||||
}
|
||||
serv = ServiceController.GetServices().FirstOrDefault(ser => ser.ServiceName == "Remotely_Service");
|
||||
if (serv.Status != ServiceControllerStatus.Running)
|
||||
{
|
||||
serv.Start();
|
||||
}
|
||||
Logger.Write("Service started.");
|
||||
var psi = new ProcessStartInfo("cmd.exe", "/c sc.exe failure \"Remotely_Service\" reset=5 actions=restart/5000");
|
||||
psi.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
Process.Start(psi).WaitForExit();
|
||||
}
|
||||
|
||||
private void RestoreBackup()
|
||||
{
|
||||
try
|
||||
{
|
||||
var backupPath = Path.Combine(Path.GetTempPath(), "Remotely_Backup.zip");
|
||||
if (File.Exists(backupPath))
|
||||
{
|
||||
Logger.Write("Restoring backup.");
|
||||
ClearInstallDirectory();
|
||||
ZipFile.ExtractToDirectory(backupPath, InstallPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
}
|
||||
private void StopService()
|
||||
{
|
||||
try
|
||||
{
|
||||
var remotelyService = ServiceController.GetServices().FirstOrDefault(x => x.ServiceName == "Remotely_Service");
|
||||
if (remotelyService != null)
|
||||
{
|
||||
Logger.Write("Stopping existing Remotely service.");
|
||||
ProgressMessageChanged?.Invoke(this, "Stopping existing Remotely service.");
|
||||
remotelyService.Stop();
|
||||
remotelyService.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
Agent.Installer.Win/Services/MessageBoxWrapper.cs
Normal file
21
Agent.Installer.Win/Services/MessageBoxWrapper.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Remotely.Agent.Installer.Win.Services
|
||||
{
|
||||
public class MessageBoxWrapper
|
||||
{
|
||||
public static MessageBoxResult Show(string message, string caption, MessageBoxButton messageBoxButton, MessageBoxImage messageBoxImage)
|
||||
{
|
||||
if (!CommandLineParser.CommandLineArgs.ContainsKey("quiet"))
|
||||
{
|
||||
return MessageBox.Show(message, caption, messageBoxButton, messageBoxImage);
|
||||
}
|
||||
return MessageBoxResult.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Agent.Installer.Win/Services/ProcessWrapper.cs
Normal file
24
Agent.Installer.Win/Services/ProcessWrapper.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Agent.Installer.Win.Services
|
||||
{
|
||||
public static class ProcessWrapper
|
||||
{
|
||||
public static Process StartHidden(string filePath, string arguments)
|
||||
{
|
||||
var psi = new ProcessStartInfo()
|
||||
{
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
CreateNoWindow = true,
|
||||
Arguments = arguments,
|
||||
FileName = filePath
|
||||
};
|
||||
return Process.Start(psi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,17 @@
|
||||
using Remotely.Agent.Installer.Win.Services;
|
||||
using Remotely.Shared.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
@ -20,6 +21,7 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
{
|
||||
private string headerMessage;
|
||||
|
||||
private bool isReadyState = true;
|
||||
private bool isServiceInstalled;
|
||||
|
||||
private string organizationName;
|
||||
@ -30,8 +32,6 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
|
||||
private string statusMessage;
|
||||
|
||||
private string subMessage;
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
Installer = new InstallerService();
|
||||
@ -49,10 +49,23 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand InstallCommand => new Executor(Install);
|
||||
public ICommand InstallCommand => new Executor(async (param) => { await Install(param); });
|
||||
|
||||
public bool IsProgressVisible => Progress > 0;
|
||||
|
||||
public bool IsReadyState
|
||||
{
|
||||
get
|
||||
{
|
||||
return isReadyState;
|
||||
}
|
||||
set
|
||||
{
|
||||
isReadyState = value;
|
||||
FirePropertyChanged(nameof(IsReadyState));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsServiceInstalled
|
||||
{
|
||||
get
|
||||
@ -81,8 +94,8 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
Process.Start(logPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Log file doesn't exist.", "No Logs", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
{
|
||||
MessageBoxWrapper.Show("Log file doesn't exist.", "No Logs", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -141,33 +154,34 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public string SubMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
return subMessage;
|
||||
}
|
||||
set
|
||||
{
|
||||
subMessage = value;
|
||||
FirePropertyChanged(nameof(SubMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand UninstallCommand => new Executor(async (param) => { await Uninstall(param); });
|
||||
|
||||
private string DeviceAlias { get; set; }
|
||||
private string DeviceGroup { get; set; }
|
||||
private InstallerService Installer { get; }
|
||||
public async Task Init()
|
||||
{
|
||||
|
||||
Installer.ProgressMessageChanged += (sender, arg) =>
|
||||
{
|
||||
StatusMessage = arg;
|
||||
};
|
||||
|
||||
Installer.ProgressValueChanged += (sender, arg) =>
|
||||
{
|
||||
Progress = arg;
|
||||
};
|
||||
|
||||
IsServiceInstalled = ServiceController.GetServices().Any(x => x.ServiceName == "Remotely_Service");
|
||||
if (IsServiceInstalled)
|
||||
if (IsServiceMissing)
|
||||
{
|
||||
HeaderMessage = "Install the Remotely service.";
|
||||
SubMessage = "Installing the Remotely service will allow remote access by the above service provider.";
|
||||
StatusMessage = "Installing the Remotely service will allow remote access by the above service provider.";
|
||||
}
|
||||
else
|
||||
{
|
||||
HeaderMessage = "Uninstall the Remotely service.";
|
||||
SubMessage = "Uninstalling the Remotely service will remove all remote acess for the above service provider.";
|
||||
StatusMessage = "Uninstalling the Remotely service will remove all remote acess for the above service provider.";
|
||||
}
|
||||
|
||||
var installerSettings = ReadInstallerSettings();
|
||||
@ -176,10 +190,23 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
ServerUrl = installerSettings?.ServerUrl;
|
||||
OrganizationID = installerSettings?.OrganizationID;
|
||||
|
||||
if (Environment.GetCommandLineArgs().Contains("-rununinstaller"))
|
||||
CopyCommandLineArgs();
|
||||
|
||||
if (CommandLineParser.CommandLineArgs.ContainsKey("install"))
|
||||
{
|
||||
await Install(null);
|
||||
}
|
||||
else if (CommandLineParser.CommandLineArgs.ContainsKey("uninstall"))
|
||||
{
|
||||
await Uninstall(null);
|
||||
}
|
||||
|
||||
if (CommandLineParser.CommandLineArgs.ContainsKey("quiet"))
|
||||
{
|
||||
App.Current.Shutdown();
|
||||
}
|
||||
|
||||
CheckParams();
|
||||
}
|
||||
|
||||
public InstallerSettings ReadInstallerSettings()
|
||||
@ -194,19 +221,16 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
var payloadSize = br.ReadInt32();
|
||||
peStream.Seek(-4 - payloadSize, SeekOrigin.End);
|
||||
var payloadBytes = br.ReadBytes(payloadSize);
|
||||
using (var settingsStream = new MemoryStream(payloadBytes))
|
||||
{
|
||||
settingsStream.Seek(0, SeekOrigin.Begin);
|
||||
var serializer = new DataContractJsonSerializer(typeof(InstallerSettings));
|
||||
var installerSettings = (InstallerSettings)serializer.ReadObject(settingsStream);
|
||||
return installerSettings;
|
||||
}
|
||||
var payloadJson = Encoding.UTF8.GetString(payloadBytes);
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var installerSettings = serializer.Deserialize<InstallerSettings>(payloadJson);
|
||||
return installerSettings;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
MessageBox.Show("There was an error reading the installer settings. Try re-downloading the installer.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBoxWrapper.Show("There was an error reading the installer settings. Try re-downloading the installer.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -218,7 +242,7 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
var result = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
if (!result)
|
||||
{
|
||||
MessageBox.Show("Elevated privileges are required. Please restart the installer using 'Run as administrator'.", "Elevation Required", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBoxWrapper.Show("Elevated privileges are required. Please restart the installer using 'Run as administrator'.", "Elevation Required", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -228,33 +252,66 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
var result = !string.IsNullOrWhiteSpace(OrganizationID) && !string.IsNullOrWhiteSpace(ServerUrl);
|
||||
if (!result)
|
||||
{
|
||||
MessageBox.Show("Required settings are missing. Try re-downloading the installer.", "Invalid Installer", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBoxWrapper.Show("Required settings are missing. Try re-downloading the installer.", "Invalid Installer", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Install(object param)
|
||||
private void CopyCommandLineArgs()
|
||||
{
|
||||
if (CommandLineParser.CommandLineArgs.TryGetValue("organization", out var orgName))
|
||||
{
|
||||
OrganizationName = orgName;
|
||||
}
|
||||
|
||||
if (CommandLineParser.CommandLineArgs.TryGetValue("organizationid", out var orgID))
|
||||
{
|
||||
OrganizationID = orgID;
|
||||
}
|
||||
|
||||
if (CommandLineParser.CommandLineArgs.TryGetValue("serverurl", out var serverUrl))
|
||||
{
|
||||
ServerUrl = serverUrl;
|
||||
}
|
||||
|
||||
if (CommandLineParser.CommandLineArgs.TryGetValue("devicegroup", out var deviceGroup))
|
||||
{
|
||||
DeviceGroup = deviceGroup;
|
||||
}
|
||||
|
||||
if (CommandLineParser.CommandLineArgs.TryGetValue("devicealias", out var deviceAlias))
|
||||
{
|
||||
DeviceAlias = deviceAlias;
|
||||
}
|
||||
|
||||
if (ServerUrl?.EndsWith("/") == true)
|
||||
{
|
||||
ServerUrl = ServerUrl.Substring(0, ServerUrl.LastIndexOf("/"));
|
||||
}
|
||||
}
|
||||
private async Task Install(object param)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsReadyState = false;
|
||||
if (!CheckParams())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Installer.Install())
|
||||
if (await Installer.Install(ServerUrl, OrganizationID, DeviceGroup, DeviceAlias))
|
||||
{
|
||||
IsServiceInstalled = true;
|
||||
Progress = 0;
|
||||
HeaderMessage = "Installation completed.";
|
||||
SubMessage = "Remotely has been installed. You can now close this window.";
|
||||
StatusMessage = "Remotely has been installed. You can now close this window.";
|
||||
}
|
||||
else
|
||||
{
|
||||
Progress = 0;
|
||||
HeaderMessage = "An error occurred during installation.";
|
||||
SubMessage = "There was an error during installation. Check the logs for details.";
|
||||
StatusMessage = "There was an error during installation. Check the logs for details.";
|
||||
}
|
||||
if (!CheckIsAdministrator())
|
||||
{
|
||||
@ -265,12 +322,20 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
|
||||
finally
|
||||
{
|
||||
IsReadyState = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task Uninstall(object param)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsReadyState = false;
|
||||
|
||||
if (!CheckParams())
|
||||
{
|
||||
return;
|
||||
@ -281,13 +346,13 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
IsServiceInstalled = false;
|
||||
Progress = 0;
|
||||
HeaderMessage = "Uninstall completed.";
|
||||
SubMessage = "Remotely has been uninstalled. You can now close this window.";
|
||||
StatusMessage = "Remotely has been uninstalled. You can now close this window.";
|
||||
}
|
||||
else
|
||||
{
|
||||
Progress = 0;
|
||||
HeaderMessage = "An error occurred during uninstall.";
|
||||
SubMessage = "There was an error during uninstall. Check the logs for details.";
|
||||
StatusMessage = "There was an error during uninstall. Check the logs for details.";
|
||||
}
|
||||
|
||||
}
|
||||
@ -295,6 +360,10 @@ namespace Remotely.Agent.Installer.Win.ViewModels
|
||||
{
|
||||
Logger.Write(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsReadyState = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,11 +23,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.PowerShell.Commands.Diagnostics" Version="6.2.4" />
|
||||
<PackageReference Include="Microsoft.PowerShell.Commands.Management" Version="6.2.4" />
|
||||
<PackageReference Include="Microsoft.PowerShell.Commands.Utility" Version="6.2.4" />
|
||||
|
||||
@ -32,10 +32,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.MixedReality.WebRTC" Version="1.0.2" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.MixedReality.WebRTC" Version="1.0.2" />
|
||||
<PackageReference Include="NAudio" Version="1.10.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.2" />
|
||||
<PackageReference Include="SharpDX" Version="4.2.0" />
|
||||
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
|
||||
<PackageReference Include="SharpDX.DXGI" Version="4.2.0" />
|
||||
|
||||
@ -63,20 +63,20 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.1">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" PrivateAssets="All" />
|
||||
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.1.2" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -7,16 +7,12 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Shared.Models
|
||||
{
|
||||
[DataContract]
|
||||
public class InstallerSettings
|
||||
{
|
||||
[DataMember]
|
||||
public string OrganizationID { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public string OrganizationName { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public string ServerUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="4.7.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="4.7.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user