using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using Artemis.Core; using Artemis.UI.Shared.Providers; using Avalonia.Platform; namespace Artemis.UI.Windows.Providers; public class AutoRunProvider : IAutoRunProvider { private readonly string _autorunName = $"Artemis 2 autorun {Environment.UserName}"; private readonly string _oldAutorunName = "Artemis 2 autorun"; private async Task IsAutoRunTaskCreated(string autorunName) { Process schtasks = new() { StartInfo = { WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = true, FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"), Arguments = $"/TN \"{autorunName}\"" } }; schtasks.Start(); await schtasks.WaitForExitAsync(); return schtasks.ExitCode == 0; } private async Task CreateAutoRunTask(TimeSpan autoRunDelay, string autorunName) { await using Stream taskFile = AssetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/autorun.xml")); XDocument document = await XDocument.LoadAsync(taskFile, LoadOptions.None, CancellationToken.None); XElement task = document.Descendants().First(); task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Date") .SetValue(DateTime.Now); task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Author") .SetValue(WindowsIdentity.GetCurrent().Name); task.Descendants().First(d => d.Name.LocalName == "Triggers").Descendants().First(d => d.Name.LocalName == "LogonTrigger").Descendants().First(d => d.Name.LocalName == "Delay") .SetValue(autoRunDelay); task.Descendants().First(d => d.Name.LocalName == "Triggers").Descendants().First(d => d.Name.LocalName == "LogonTrigger").Descendants().First(d => d.Name.LocalName == "UserId") .SetValue(WindowsIdentity.GetCurrent().Name); task.Descendants().First(d => d.Name.LocalName == "Principals").Descendants().First(d => d.Name.LocalName == "Principal").Descendants().First(d => d.Name.LocalName == "UserId") .SetValue(WindowsIdentity.GetCurrent().User!.Value); task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "WorkingDirectory") .SetValue(Constants.ApplicationFolder); task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "Command") .SetValue("\"" + Constants.ExecutablePath + "\""); string xmlPath = Path.GetTempFileName(); await using (Stream fileStream = new FileStream(xmlPath, FileMode.Create)) { await document.SaveAsync(fileStream, SaveOptions.None, CancellationToken.None); } Process schtasks = new() { StartInfo = { WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = true, Verb = "runas", FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"), Arguments = $"/Create /XML \"{xmlPath}\" /tn \"{autorunName}\" /F" } }; schtasks.Start(); await schtasks.WaitForExitAsync(); File.Delete(xmlPath); } private async Task RemoveAutoRunTask(string autorunName) { Process schtasks = new() { StartInfo = { WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = true, Verb = "runas", FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"), Arguments = $"/Delete /TN \"{autorunName}\" /f" } }; schtasks.Start(); await schtasks.WaitForExitAsync(); } /// public async Task EnableAutoRun(bool recreate, int autoRunDelay) { if (Constants.CurrentVersion == "local") return; await CleanupOldAutorun(); // Create or remove the task if necessary bool taskCreated = false; if (!recreate) taskCreated = await IsAutoRunTaskCreated(_autorunName); if (!taskCreated) await CreateAutoRunTask(TimeSpan.FromSeconds(autoRunDelay), _autorunName); } /// public async Task DisableAutoRun() { bool taskCreated = await IsAutoRunTaskCreated(_autorunName); if (taskCreated) await RemoveAutoRunTask(_autorunName); } private async Task CleanupOldAutorun() { bool taskCreated = await IsAutoRunTaskCreated(_oldAutorunName); if (taskCreated) await RemoveAutoRunTask(_oldAutorunName); } }