using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
namespace Artemis.Core
{
///
/// Provides a few general utilities for ease of use
///
public static class Utilities
{
///
/// Call this before even initializing the Core to make sure the folders required for operation are in place
///
public static void PrepareFirstLaunch()
{
CreateAccessibleDirectory(Constants.DataFolder);
CreateAccessibleDirectory(Path.Combine(Constants.DataFolder ,"plugins"));
CreateAccessibleDirectory(Path.Combine(Constants.DataFolder ,"user layouts"));
}
///
/// Attempts to gracefully shut down the application with a delayed kill to ensure the application shut down
///
/// This is required because not all SDKs shut down properly, it is too unpredictable to just assume we can
/// gracefully shut down
///
///
public static void Shutdown()
{
// Request a graceful shutdown, whatever UI we're running can pick this up
OnShutdownRequested();
}
///
/// Restarts the application
///
/// Whether the application should be restarted with elevated permissions
/// Delay in seconds before killing process and restarting
/// A list of extra arguments to pass to Artemis when restarting
public static void Restart(bool elevate, TimeSpan delay, params string[] extraArgs)
{
OnRestartRequested(new RestartEventArgs(elevate, delay, extraArgs.ToList()));
}
///
/// Opens the provided URL in the default web browser
///
/// The URL to open
/// The process created to open the URL
public static Process? OpenUrl(string url)
{
ProcessStartInfo processInfo = new()
{
FileName = url,
UseShellExecute = true
};
return Process.Start(processInfo);
}
///
/// Creates all directories and subdirectories in the specified path unless they already exist with permissions
/// allowing access by everyone.
///
/// The directory to create.
public static void CreateAccessibleDirectory(string path)
{
if (!Directory.Exists(path))
{
DirectoryInfo dataDirectory = Directory.CreateDirectory(path);
if (!OperatingSystem.IsWindows())
return;
// On Windows, ensure everyone has permission (important when running as admin)
DirectorySecurity security = dataDirectory.GetAccessControl();
SecurityIdentifier everyone = new(WellKnownSidType.WorldSid, null);
security.AddAccessRule(new FileSystemAccessRule(
everyone,
FileSystemRights.Modify | FileSystemRights.Synchronize,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, AccessControlType.Allow)
);
dataDirectory.SetAccessControl(security);
}
}
///
/// Gets the current application location
///
///
internal static string GetCurrentLocation()
{
return Process.GetCurrentProcess().MainModule!.FileName!;
}
private static void OnRestartRequested(RestartEventArgs e)
{
RestartRequested?.Invoke(null, e);
}
#region Events
///
/// Occurs when the core has requested an application shutdown
///
public static event EventHandler? ShutdownRequested;
///
/// Occurs when the core has requested an application restart
///
public static event EventHandler? RestartRequested;
private static void OnShutdownRequested()
{
ShutdownRequested?.Invoke(null, EventArgs.Empty);
}
#endregion
}
}