using Remotely.Agent.Services; using Remotely.Shared.Services; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.ServiceProcess; using System.Threading.Tasks; using System.Diagnostics; using System.Threading; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Remotely.Agent { public class Program { public static bool IsDebug { get; set; } public static IServiceProvider Services { get; set; } public static void Main(string[] args) { try { BuildServices(); Task.Run(() => {_ = Init(); }); Thread.Sleep(Timeout.Infinite); } catch (Exception ex) { Logger.Write(ex); } } private static void BuildServices() { var serviceCollection = new ServiceCollection(); serviceCollection.AddLogging(builder => { builder.AddConsole().AddEventLog(); }); serviceCollection.AddSingleton(); serviceCollection.AddScoped(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddScoped(); serviceCollection.AddScoped(); serviceCollection.AddSingleton(); serviceCollection.AddScoped(); serviceCollection.AddScoped(); serviceCollection.AddScoped(); serviceCollection.AddScoped(); Services = serviceCollection.BuildServiceProvider(); } private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Logger.Write(e.ExceptionObject as Exception); if (OSUtils.IsWindows) { // Remove Secure Attention Sequence policy to allow app to simulate Ctrl + Alt + Del. var subkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", true); if (subkey.GetValue("SoftwareSASGeneration") != null) { subkey.DeleteValue("SoftwareSASGeneration"); } } } private static async Task HandleConnection() { while (true) { try { if (!Services.GetRequiredService().IsConnected) { var waitTime = new Random().Next(1000, 30000); Logger.Write($"Websocket closed. Reconnecting in {waitTime / 1000} seconds..."); await Task.Delay(waitTime); await Services.GetRequiredService().Connect(); await Services.GetRequiredService().CheckForUpdates(); } } catch (Exception ex) { Logger.Write(ex); } Thread.Sleep(1000); } } private static async Task Init() { try { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; #if DEBUG IsDebug = true; #endif SetWorkingDirectory(); if (!IsDebug && OSUtils.IsWindows) { _ = Task.Run(() => { ServiceBase.Run(new WindowsService()); }); } if (!IsDebug) { await Services.GetRequiredService().BeginChecking(); } await Services.GetRequiredService().Connect(); } finally { await HandleConnection(); } } private static void SetWorkingDirectory() { var assemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location; var assemblyDir = Path.GetDirectoryName(assemblyPath); Directory.SetCurrentDirectory(assemblyDir); } } }