// 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();
}
}
}