From 83e159ed33de1f0ddef2814ab8c0d0ba400fd5cd Mon Sep 17 00:00:00 2001 From: LAB02 Research Date: Wed, 21 Dec 2022 10:25:02 +0100 Subject: [PATCH] 2022.2.0 --- .../Functions/Extensions.cs | 25 +++ .../Functions/HelperFunctions.cs | 41 ++++- .../HASS.Agent.AutoImport.csproj | 2 +- .../Managers/HASSAgentManager.cs | 1 + .../Managers/SettingsManager.cs | 9 +- .../Managers/ShortcutManager.cs | 149 +++++++++++++++--- .../Models/AppSettings.cs | 2 +- 7 files changed, 198 insertions(+), 31 deletions(-) create mode 100644 src/HASS.Agent.AutoImport/Functions/Extensions.cs diff --git a/src/HASS.Agent.AutoImport/Functions/Extensions.cs b/src/HASS.Agent.AutoImport/Functions/Extensions.cs new file mode 100644 index 0000000..6f23749 --- /dev/null +++ b/src/HASS.Agent.AutoImport/Functions/Extensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HASS.Agent.AutoImport.Functions +{ + public static class Extensions + { + /// + /// Replaces all double backslashes into singles + /// + /// + /// + public static string RemoveBackslashEscaping(this string text) => text.Replace(@"\\", @"\"); + + /// + /// Replaces all single backslashes into doubles + /// + /// + /// + public static string AddBackslashEscaping(this string text) => text.Replace(@"\", @"\\"); + } +} diff --git a/src/HASS.Agent.AutoImport/Functions/HelperFunctions.cs b/src/HASS.Agent.AutoImport/Functions/HelperFunctions.cs index 33f3c2c..77bb72e 100644 --- a/src/HASS.Agent.AutoImport/Functions/HelperFunctions.cs +++ b/src/HASS.Agent.AutoImport/Functions/HelperFunctions.cs @@ -68,7 +68,7 @@ internal static bool IsProcessActiveUnderCurrentUser(string process) } catch (Exception ex) { - Log.Fatal(ex, "[PROCESS] [{process}] Error while determining if process is running: {msg}", process, ex.Message); + Log.Fatal(ex, "[PROCESS] [{process}] Error while determining if process is running: {err}", process, ex.Message); return false; } } @@ -110,9 +110,46 @@ internal static bool CloseProcess(string process) } catch (Exception ex) { - Log.Fatal(ex, "[PROCESS] [{process}] Error while closing process: {msg}", process, ex.Message); + Log.Fatal(ex, "[PROCESS] [{process}] Error while closing process: {err}", process, ex.Message); return false; } } + + /// + /// Attempts to parse the URL section of an .url file + /// + /// + /// + internal static (bool parsed, string url) ParseUrl(string urlFile) + { + try + { + if (!File.Exists(urlFile)) + { + Log.Error("[SHORTCUTS] Unable to parse, file not found"); + return (false, string.Empty); + } + + var lnkFile = File.ReadAllLines(urlFile); + + var parsed = false; + var url = string.Empty; + + foreach (var line in lnkFile) + { + if (!line.StartsWith("URL=")) continue; + + url = line.Split('=')[1].Trim(); + parsed = true; + } + + return (parsed, url); + } + catch (Exception ex) + { + Log.Fatal(ex, "[SHORTCUTS] Error while parsing: {err}", ex.Message); + return (false, string.Empty); + } + } } } diff --git a/src/HASS.Agent.AutoImport/HASS.Agent.AutoImport.csproj b/src/HASS.Agent.AutoImport/HASS.Agent.AutoImport.csproj index bc8487e..504254d 100644 --- a/src/HASS.Agent.AutoImport/HASS.Agent.AutoImport.csproj +++ b/src/HASS.Agent.AutoImport/HASS.Agent.AutoImport.csproj @@ -5,7 +5,7 @@ net6.0-windows10.0.17763.0 enable disable - 2022.1.0 + 2022.2.0 LAB02 Research LAB02 Research hassagent.ico diff --git a/src/HASS.Agent.AutoImport/Managers/HASSAgentManager.cs b/src/HASS.Agent.AutoImport/Managers/HASSAgentManager.cs index 8ac35d3..07c334e 100644 --- a/src/HASS.Agent.AutoImport/Managers/HASSAgentManager.cs +++ b/src/HASS.Agent.AutoImport/Managers/HASSAgentManager.cs @@ -274,6 +274,7 @@ internal static void Restart() // wait a bit Thread.Sleep(TimeSpan.FromSeconds(2)); } + else Log.Information("[HASS.Agent] Not currently running, no need to close"); // relaunch Log.Information("[HASS.Agent] Starting new instance .."); diff --git a/src/HASS.Agent.AutoImport/Managers/SettingsManager.cs b/src/HASS.Agent.AutoImport/Managers/SettingsManager.cs index d0214fb..8563727 100644 --- a/src/HASS.Agent.AutoImport/Managers/SettingsManager.cs +++ b/src/HASS.Agent.AutoImport/Managers/SettingsManager.cs @@ -43,7 +43,7 @@ internal static (bool success, string error) LoadSettings() } // attempt to parse - var settings = JsonConvert.DeserializeObject(settingsStr); + var settings = JsonConvert.DeserializeObject(settingsStr.AddBackslashEscaping()); if (settings == null) return (false, "unable to parse settings file"); // check if the ShortcutSourceFolder exists @@ -114,7 +114,7 @@ internal static (bool success, string error) LoadProcessedShortcuts() } // attempt to parse - var shortcuts = JsonConvert.DeserializeObject>(shortcutsStr); + var shortcuts = JsonConvert.DeserializeObject>(shortcutsStr.AddBackslashEscaping()); if (shortcuts == null) return (false, "unable to parse processedshortcuts file"); // done @@ -136,8 +136,11 @@ private static void SaveDefaultSettings() // create the settings dir if (!Directory.Exists(Variables.SettingsPath)) Directory.CreateDirectory(Variables.SettingsPath); + // serialize the settings + var serializedSettings = JsonConvert.SerializeObject(Variables.Settings, Formatting.Indented).RemoveBackslashEscaping(); + // write the config - File.WriteAllText(Variables.AppSettingsFile, JsonConvert.SerializeObject(Variables.Settings, Formatting.Indented)); + File.WriteAllText(Variables.AppSettingsFile, serializedSettings); } } } diff --git a/src/HASS.Agent.AutoImport/Managers/ShortcutManager.cs b/src/HASS.Agent.AutoImport/Managers/ShortcutManager.cs index d3369ce..f6b5fc5 100644 --- a/src/HASS.Agent.AutoImport/Managers/ShortcutManager.cs +++ b/src/HASS.Agent.AutoImport/Managers/ShortcutManager.cs @@ -31,25 +31,52 @@ internal static bool ProcessImport() // get the shortcuts var searchOption = Variables.Settings.ShortcutSearchRecusively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - var shortcuts = Directory.EnumerateFiles(Variables.Settings.ShortcutSourceFolder, "*.lnk", searchOption)?.ToArray(); + var (lnkSuccesful, lnkNewFiles) = ProcessLnks(searchOption); + var (urlSuccesful, urlNewFiles) = ProcessUrls(searchOption); - if (!shortcuts.Any()) + // new shortcuts? + if (lnkNewFiles || urlNewFiles) { - Log.Information("[SHORTCUTS] No shortcuts found, nothing to process"); - return true; + // yep, store them + var serializedShortcuts = JsonConvert.SerializeObject(Variables.ProcessedShortcuts, Formatting.Indented).RemoveBackslashEscaping(); + File.WriteAllText(Variables.ProcessedShortcutsFile, serializedShortcuts); + + // restart hass.agent + if (Variables.Settings.RestartHASSAgentOnNewItems) HASSAgentManager.Restart(); } + else Log.Information("[SHORTCUTS] No shortcuts found, nothing to process"); + + // done + return lnkSuccesful && urlSuccesful; + } + catch (Exception ex) + { + Log.Fatal(ex, "[SHORTCUTS] Importing failed: {err}", ex.Message); + return false; + } + } + + private static (bool succesful, bool newFiles) ProcessLnks(SearchOption searchOption) + { + var newFiles = 0; + + try + { + var shortcuts = Directory.EnumerateFiles(Variables.Settings.ShortcutSourceFolder, "*.lnk", searchOption)?.ToArray(); + if (!shortcuts.Any()) return (true, false); // iterate them - var newFiles = 0; foreach (var shortcutFile in shortcuts) { + var fileName = Path.GetFileName(shortcutFile); + var shortcut = Shortcut.ReadFromFile(shortcutFile); if (shortcut == null) { - Log.Warning("[SHORTCUTS] Shortcut parsing failed for: {file}", Path.GetFileName(shortcutFile)); + Log.Warning("[SHORTCUTS] Shortcut parsing failed for: {file}", fileName); continue; } - + if (Variables.ProcessedShortcuts.Any(x => x.LinkFile == shortcutFile)) { // already know it, skip @@ -57,13 +84,25 @@ internal static bool ProcessImport() } var name = Path.GetFileNameWithoutExtension(shortcutFile); - var target = shortcut.LinkTargetIDList.Path; - var args = shortcut.StringData.CommandLineArguments; - - Log.Information("[SHORTCUTS] New shortcut found, importing into HASS.Agent:"); + var target = shortcut.LinkTargetIDList?.Path ?? string.Empty; + var args = shortcut.StringData?.CommandLineArguments ?? string.Empty; + + if (string.IsNullOrWhiteSpace(target)) + { + Log.Warning("[SHORTCUTS] Shortcut contained empty or no target: {file}", fileName); + continue; + } + + Log.Information("[SHORTCUTS] New shortcut found, importing into HASS.Agent:\r\n"); + Log.Information("[SHORTCUTS] Type: {type}", ".lnk"); Log.Information("[SHORTCUTS] Name: {name}", name); - Log.Information("[SHORTCUTS] Target: {target}", target); - if (!string.IsNullOrWhiteSpace(args)) Log.Information("[SHORTCUTS] Arguments: {args}", args); + if (string.IsNullOrWhiteSpace(args)) Log.Information("[SHORTCUTS] Target: {target}\r\n", target); + else + { + Log.Information("[SHORTCUTS] Target: {target}", target); + Log.Information("[SHORTCUTS] Arguments: {args}\r\n", args); + + } var processedShortcut = new ProcessedShortcut { @@ -74,7 +113,7 @@ internal static bool ProcessImport() CommandGuid = Guid.NewGuid().ToString(), SensorGuid = Guid.NewGuid().ToString() }; - + var imported = HASSAgentManager.ProcessShortcut(processedShortcut); if (!imported) { @@ -88,23 +127,85 @@ internal static bool ProcessImport() Log.Information("[SHORTCUTS] Succesfully imported\r\n"); } - // new shortcuts? - if (newFiles > 0) + return (true, newFiles > 0); + } + catch (Exception ex) + { + return (false, newFiles > 0); + } + } + + private static (bool succesful, bool newFiles) ProcessUrls(SearchOption searchOption) + { + var newFiles = 0; + + try + { + var shortcuts = Directory.EnumerateFiles(Variables.Settings.ShortcutSourceFolder, "*.url", searchOption)?.ToArray(); + if (!shortcuts.Any()) return (true, false); + + // iterate them + foreach (var shortcutFile in shortcuts) { - // yep, store them - File.WriteAllText(Variables.ProcessedShortcutsFile, JsonConvert.SerializeObject(Variables.ProcessedShortcuts, Formatting.Indented)); + var fileName = Path.GetFileName(shortcutFile); - // restart hass.agent - if (Variables.Settings.RestartHASSAgentOnNewItems) HASSAgentManager.Restart(); + var (parsed, target) = HelperFunctions.ParseUrl(shortcutFile); + if (!parsed) + { + Log.Warning("[SHORTCUTS] Shortcut parsing failed for: {file}", fileName); + continue; + } + + if (string.IsNullOrEmpty(target)) + { + Log.Warning("[SHORTCUTS] Shortcut contained empty or no URL: {file}", fileName); + continue; + } + + if (Variables.ProcessedShortcuts.Any(x => x.LinkFile == shortcutFile)) + { + // already know it, skip + continue; + } + + var name = Path.GetFileNameWithoutExtension(shortcutFile); + + Log.Information("[SHORTCUTS] New shortcut found, importing into HASS.Agent:\r\n"); + Log.Information("[SHORTCUTS] Type: {type}", ".url"); + Log.Information("[SHORTCUTS] Name: {name}", name); + Log.Information("[SHORTCUTS] Target: {target}\r\n", target); + + // create the shortcut with the right command + var processedShortcut = new ProcessedShortcut + { + LinkFile = shortcutFile, + Name = name, + Target = $"start {target}", + CommandGuid = Guid.NewGuid().ToString(), + SensorGuid = Guid.NewGuid().ToString() + }; + + var imported = HASSAgentManager.ProcessShortcut(processedShortcut); + if (!imported) + { + Log.Error("[SHORTCUTS] Import failed\r\n"); + continue; + } + + // restore the target + processedShortcut.Target = target; + + newFiles++; + Variables.ProcessedShortcuts.Add(processedShortcut); + + Log.Information("[SHORTCUTS] Succesfully imported\r\n"); } - // done - return true; + return (true, newFiles > 0); } catch (Exception ex) { - Log.Fatal(ex, "[SHORTCUTS] Importing failed: {err}", ex.Message); - return false; + return (false, newFiles > 0); } } } diff --git a/src/HASS.Agent.AutoImport/Models/AppSettings.cs b/src/HASS.Agent.AutoImport/Models/AppSettings.cs index d386138..d572385 100644 --- a/src/HASS.Agent.AutoImport/Models/AppSettings.cs +++ b/src/HASS.Agent.AutoImport/Models/AppSettings.cs @@ -19,7 +19,7 @@ public AppSettings() public string ShortcutSourceFolder { get; set; } = string.Empty; public bool ShortcutSearchRecusively { get; set; } = false; public bool CreateCustomCommands { get; set; } = true; - public bool CreateProcessActiveSensors { get; set; } = true; + public bool CreateProcessActiveSensors { get; set; } = false; public bool RestartHASSAgentOnNewItems { get; set; } = true; } }