using Remotely.Agent.Installer.Win.Services; using Remotely.Shared.Models; using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Security.Principal; using System.ServiceProcess; using System.Threading.Tasks; using System.Web.Script.Serialization; using System.Windows; using System.Windows.Input; namespace Remotely.Agent.Installer.Win.ViewModels { public class MainWindowViewModel : ViewModelBase { private string headerMessage; private bool isReadyState = true; private bool isServiceInstalled; private string organizationID; private int progress; private string serverUrl; private string statusMessage; public MainWindowViewModel() { Installer = new InstallerService(); } public string HeaderMessage { get { return headerMessage; } set { headerMessage = value; FirePropertyChanged(nameof(HeaderMessage)); } } public string InstallButtonText => IsServiceMissing ? "Install" : "Reinstall"; 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 { return isServiceInstalled; } set { isServiceInstalled = value; FirePropertyChanged(nameof(IsServiceInstalled)); FirePropertyChanged(nameof(IsServiceMissing)); FirePropertyChanged(nameof(InstallButtonText)); } } public bool IsServiceMissing => !isServiceInstalled; public ICommand OpenLogsCommand { get { return new Executor(param => { var logPath = Path.Combine(Path.GetTempPath(), "Remotely_Installer.log"); if (File.Exists(logPath)) { Process.Start(logPath); } else { MessageBoxEx.Show("Log file doesn't exist.", "No Logs", MessageBoxButton.OK, MessageBoxImage.Information); } }); } } public string OrganizationID { get { return organizationID; } set { organizationID = value; FirePropertyChanged(nameof(OrganizationID)); } } public int Progress { get { return progress; } set { progress = value; FirePropertyChanged(nameof(Progress)); FirePropertyChanged(nameof(IsProgressVisible)); } } public string ServerUrl { get { return serverUrl; } set { serverUrl = value; FirePropertyChanged(nameof(ServerUrl)); } } public string StatusMessage { get { return statusMessage; } set { statusMessage = value; FirePropertyChanged(nameof(StatusMessage)); } } public ICommand UninstallCommand => new Executor(async (param) => { await Uninstall(param); }); private string DeviceAlias { get; set; } private string DeviceGroup { get; set; } private string DeviceUuid { 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 (IsServiceMissing) { HeaderMessage = "Install the Remotely service."; StatusMessage = "Installing the Remotely service will allow remote access by the above service provider."; } else { HeaderMessage = "Modify the Remotely installation."; StatusMessage = "Uninstalling the Remotely service will remove all remote acess to this device.\r\n\r\n" + "Reinstalling will retain the current settings and install the service again."; } CopyCommandLineArgs(); var fileName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location); for (var i = 0; i < fileName.Length; i++) { var guid = string.Join("", fileName.Skip(i).Take(36)); if (Guid.TryParse(guid, out _)) { OrganizationID = guid; } } AddExistingConnectionInfo(); 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(); } } private bool CheckIsAdministrator() { var identity = WindowsIdentity.GetCurrent(); var principal = new WindowsPrincipal(identity); var result = principal.IsInRole(WindowsBuiltInRole.Administrator); if (!result) { MessageBoxEx.Show("Elevated privileges are required. Please restart the installer using 'Run as administrator'.", "Elevation Required", MessageBoxButton.OK, MessageBoxImage.Warning); } return result; } private bool CheckParams() { var result = !string.IsNullOrWhiteSpace(OrganizationID) || !string.IsNullOrWhiteSpace(ServerUrl); if (!result) { Logger.Write("ServerUrl or OrganizationID param is missing. Unable to install."); MessageBoxEx.Show("Required settings are missing. Please enter a server URL and organization ID.", "Invalid Installer", MessageBoxButton.OK, MessageBoxImage.Error); } return result; } private void CopyCommandLineArgs() { 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 (CommandLineParser.CommandLineArgs.TryGetValue("deviceuuid", out var deviceUuid)) { DeviceUuid = deviceUuid; } if (ServerUrl?.EndsWith("/") == true) { ServerUrl = ServerUrl.Substring(0, ServerUrl.LastIndexOf("/")); } } private void AddExistingConnectionInfo() { try { var connectionInfoPath = Path.Combine( Path.GetPathRoot(Environment.SystemDirectory), "Program Files", "Remotely", "ConnectionInfo.json"); if (File.Exists(connectionInfoPath)) { var serializer = new JavaScriptSerializer(); var connectionInfo = serializer.Deserialize(File.ReadAllText(connectionInfoPath)); if (string.IsNullOrWhiteSpace(OrganizationID)) { OrganizationID = connectionInfo.OrganizationID; } if (string.IsNullOrWhiteSpace(ServerUrl)) { ServerUrl = connectionInfo.Host; } } } catch (Exception ex) { Logger.Write(ex); } } private async Task Install(object param) { try { IsReadyState = false; if (!CheckParams()) { return; } HeaderMessage = "Installing Remotely..."; if (await Installer.Install(ServerUrl, OrganizationID, DeviceGroup, DeviceAlias, DeviceUuid)) { IsServiceInstalled = true; Progress = 0; HeaderMessage = "Installation completed."; StatusMessage = "Remotely has been installed. You can now close this window."; } else { Progress = 0; HeaderMessage = "An error occurred during installation."; StatusMessage = "There was an error during installation. Check the logs for details."; } if (!CheckIsAdministrator()) { return; } } catch (Exception ex) { Logger.Write(ex); } finally { IsReadyState = true; } } private async Task Uninstall(object param) { try { IsReadyState = false; HeaderMessage = "Uninstalling Remotely..."; if (await Installer.Uninstall()) { IsServiceInstalled = false; Progress = 0; HeaderMessage = "Uninstall completed."; StatusMessage = "Remotely has been uninstalled. You can now close this window."; } else { Progress = 0; HeaderMessage = "An error occurred during uninstall."; StatusMessage = "There was an error during uninstall. Check the logs for details."; } } catch (Exception ex) { Logger.Write(ex); } finally { IsReadyState = true; } } } }