// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using EpicGames.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Horde.Agent { /// /// Entry point /// public static class Program { /// /// Name of the http client /// public const string HordeServerClientName = "HordeServer"; /// /// Path to the root application directory /// public static DirectoryReference AppDir { get; } = GetAppDir(); /// /// Path to the default data directory /// public static DirectoryReference DataDir { get; } = GetDataDir(); /// /// The launch arguments /// public static IReadOnlyList Args { get; private set; } = null!; /// /// The current application version /// public static string Version { get; } = GetVersion(); /// /// Entry point /// /// Command-line arguments /// Exit code public static async Task Main(string[] args) { Program.Args = args; IServiceCollection services = new ServiceCollection(); services.AddCommandsFromAssembly(Assembly.GetExecutingAssembly()); services.AddLogging(builder => builder.AddProvider(new Logging.HordeLoggerProvider())); // Enable unencrypted HTTP/2 for gRPC channel without TLS AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Prioritize agent execution time over any job its running. // We've seen file copying starving the agent communication to the Horde server, causing a disconnect. // Increasing the process priority is speculative fix to combat this. using (Process process = Process.GetCurrentProcess()) { process.PriorityClass = ProcessPriorityClass.High; } } // Execute all the commands IServiceProvider serviceProvider = services.BuildServiceProvider(); return await CommandHost.RunAsync(new CommandLineArguments(args), serviceProvider, typeof(Horde.Agent.Modes.Service.RunCommand)); } /// /// Gets the version of the current assembly /// /// static string GetVersion() { try { return FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion!; } catch { return "unknown"; } } /// /// Gets the application directory /// /// static DirectoryReference GetAppDir() { return new DirectoryReference(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!); } /// /// Gets the default data directory /// /// static DirectoryReference GetDataDir() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { DirectoryReference? programDataDir = DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.CommonApplicationData); if (programDataDir != null) { return DirectoryReference.Combine(programDataDir, "HordeAgent"); } } return GetAppDir(); } } }