From 14d0d8704441b4c66d99fbec2f6ee75b49e96496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Fri, 26 Jul 2024 15:17:26 +0200 Subject: [PATCH 01/80] Fixed PWA Apps might fix issue #28 --- GoAwayEdge/App.xaml.cs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 6138abf..57b0361 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -13,6 +13,7 @@ using GoAwayEdge.Common; using System.Diagnostics; using System.IO; +using System.Linq; using System.Security.Principal; using System.Text; using System.Web; @@ -225,11 +226,12 @@ public void Application_Startup(object sender, StartupEventArgs e) Environment.Exit(0); } - + public static void RunParser(string[] args) { var argumentJoin = string.Join(" ", args); var isFile = false; + var isApp = false; var collectSingleArgument = false; var singleArgument = string.Empty; var p = new Process(); @@ -263,6 +265,13 @@ public static void RunParser(string[] args) collectSingleArgument = true; } + // Check for App + if (arg.Contains("--app-id")) + { + collectSingleArgument = true; + singleArgument = arg; + } + if (!args.Contains("--profile-directory") && !ContainsParsedData(args) && args.Length != 1) continue; // Start Edge (default browser on this system) #if DEBUG @@ -281,6 +290,9 @@ public static void RunParser(string[] args) if (File.Exists(singleArgument)) isFile = true; + if (singleArgument.Contains("--app-id")) + isApp = true; + // Open URL in default browser if (_url != null) { @@ -329,9 +341,21 @@ public static void RunParser(string[] args) p.StartInfo.FileName = FileConfiguration.NonIfeoPath; p.StartInfo.Arguments = $"--single-argument {singleArgument}"; #if DEBUG - var copilotMessageUi = new MessageUi("GoAwayEdge", + var messageUi = new MessageUi("GoAwayEdge", $"Opening '{singleArgument}' with Edge.", "OK", isMainThread: true); - copilotMessageUi.ShowDialog(); + messageUi.ShowDialog(); +#endif + p.Start(); + } + // Is App + else if (isApp) + { + p.StartInfo.FileName = FileConfiguration.NonIfeoPath; + p.StartInfo.Arguments = $"{singleArgument}"; +#if DEBUG + var messageUi = new MessageUi("GoAwayEdge", + $"Opening PWA Application with following arguments: '{singleArgument}'.", "OK", isMainThread: true); + messageUi.ShowDialog(); #endif p.Start(); } From a9852f6c486524e21384e586034e0264a9967862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Fri, 26 Jul 2024 23:35:03 +0200 Subject: [PATCH 02/80] Updated parsing engine --- GoAwayEdge/App.xaml.cs | 249 +----- GoAwayEdge/Common/Configuration.cs | 1 - GoAwayEdge/Common/Debugging/DebugMessage.cs | 17 + GoAwayEdge/Common/{ => Debugging}/Logging.cs | 4 +- .../{ => Installation}/InstallRoutine.cs | 2 + .../Common/{ => Installation}/Removal.cs | 781 +++++++++--------- .../Common/{ => Installation}/Updater.cs | 444 +++++----- GoAwayEdge/Common/Localization.cs | 6 +- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 143 ++++ GoAwayEdge/Common/Runtime/UrlParse.cs | 104 +++ GoAwayEdge/GoAwayEdge.csproj | 2 +- README.md | 2 +- TODO.md | 83 ++ 13 files changed, 977 insertions(+), 861 deletions(-) create mode 100644 GoAwayEdge/Common/Debugging/DebugMessage.cs rename GoAwayEdge/Common/{ => Debugging}/Logging.cs (96%) rename GoAwayEdge/Common/{ => Installation}/InstallRoutine.cs (99%) rename GoAwayEdge/Common/{ => Installation}/Removal.cs (96%) rename GoAwayEdge/Common/{ => Installation}/Updater.cs (97%) create mode 100644 GoAwayEdge/Common/Runtime/ArgumentParse.cs create mode 100644 GoAwayEdge/Common/Runtime/UrlParse.cs create mode 100644 TODO.md diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 57b0361..0d8a920 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -13,11 +13,12 @@ using GoAwayEdge.Common; using System.Diagnostics; using System.IO; -using System.Linq; using System.Security.Principal; using System.Text; using System.Web; using System.Windows; +using GoAwayEdge.Common.Runtime; +using GoAwayEdge.Common.Debugging; namespace GoAwayEdge { @@ -26,10 +27,14 @@ namespace GoAwayEdge /// public partial class App { + public static bool IsDebug = false; private static string? _url; - + public void Application_Startup(object sender, StartupEventArgs e) { +#if DEBUG + IsDebug = true; +#endif // Initialize the logging system Logging.Initialize(); @@ -222,145 +227,11 @@ public void Application_Startup(object sender, StartupEventArgs e) { // ignored } - RunParser(args); + ArgumentParse.Parse(args); Environment.Exit(0); } - public static void RunParser(string[] args) - { - var argumentJoin = string.Join(" ", args); - var isFile = false; - var isApp = false; - var collectSingleArgument = false; - var singleArgument = string.Empty; - var p = new Process(); - p.StartInfo.UseShellExecute = true; - p.StartInfo.RedirectStandardOutput = false; -#if DEBUG - var w = new MessageUi("GoAwayEdge", - $"The following args are redirected (CTRL+C to copy):\n\n{argumentJoin}", "OK", isMainThread: true); - w.ShowDialog(); -#endif - Console.WriteLine("Command line args:\n\n" + argumentJoin + "\n", ConsoleColor.Gray); - - // Filter command line args - foreach (var arg in args) - { - if (arg.Contains("microsoft-edge:")) - { - _url = arg; - } - - if (collectSingleArgument) - { - // Concatenate all remaining arguments into a single string - singleArgument += (singleArgument.Length > 0 ? " " : "") + arg; - continue; - } - - // Check for the single argument flag - if (arg == "--single-argument") - { - collectSingleArgument = true; - } - - // Check for App - if (arg.Contains("--app-id")) - { - collectSingleArgument = true; - singleArgument = arg; - } - - if (!args.Contains("--profile-directory") && !ContainsParsedData(args) && args.Length != 1) continue; // Start Edge (default browser on this system) - -#if DEBUG - var messageUi = new MessageUi("GoAwayEdge", - "Microsoft Edge will now start normally via IFEO application.", "OK", isMainThread: true); - messageUi.ShowDialog(); -#endif - var parsedArgs = args.Skip(2); - p.StartInfo.FileName = FileConfiguration.NonIfeoPath; - p.StartInfo.Arguments = string.Join(" ", parsedArgs); - p.Start(); - Environment.Exit(0); - } - - // Validate single argument - if (File.Exists(singleArgument)) - isFile = true; - - if (singleArgument.Contains("--app-id")) - isApp = true; - - // Open URL in default browser - if (_url != null) - { - // Windows Copilot - if (_url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=taskbar") - || _url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=taskbar")) - { - p.StartInfo.FileName = FileConfiguration.NonIfeoPath; - p.StartInfo.Arguments = _url; - Console.WriteLine($"Opening Windows Copilot (Taskbar) with following url:\n{_url}", ConsoleColor.Gray); -#if DEBUG - var copilotMessageUi = new MessageUi("GoAwayEdge", - $"Opening Windows Copilot (Taskbar) with following url:\n{_url}", "OK", isMainThread: true); - copilotMessageUi.ShowDialog(); -#endif - } - else if (_url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=hotkey") - || _url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=hotkey")) - { - p.StartInfo.FileName = FileConfiguration.NonIfeoPath; - p.StartInfo.Arguments = _url; - Console.WriteLine($"Opening Windows Copilot (Hotkey) with following url:\n{_url}", ConsoleColor.Gray); -#if DEBUG - var copilotMessageUi = new MessageUi("GoAwayEdge", - $"Opening Windows Copilot (Hotkey) with following url:\n{_url}", "OK", isMainThread: true); - copilotMessageUi.ShowDialog(); -#endif - } - else - { - var parsed = ParseUrl(_url); - Console.WriteLine("Opening URL in default browser:\n\n" + parsed + "\n", ConsoleColor.Gray); -#if DEBUG - var defaultUrlMessageUi = new MessageUi("GoAwayEdge", - "Opening URL in default browser:\n\n" + parsed + "\n", "OK", isMainThread: true); - defaultUrlMessageUi.ShowDialog(); -#endif - p.StartInfo.FileName = parsed; - p.StartInfo.Arguments = ""; - } - p.Start(); - } - // Is File - else if (isFile) - { - p.StartInfo.FileName = FileConfiguration.NonIfeoPath; - p.StartInfo.Arguments = $"--single-argument {singleArgument}"; -#if DEBUG - var messageUi = new MessageUi("GoAwayEdge", - $"Opening '{singleArgument}' with Edge.", "OK", isMainThread: true); - messageUi.ShowDialog(); -#endif - p.Start(); - } - // Is App - else if (isApp) - { - p.StartInfo.FileName = FileConfiguration.NonIfeoPath; - p.StartInfo.Arguments = $"{singleArgument}"; -#if DEBUG - var messageUi = new MessageUi("GoAwayEdge", - $"Opening PWA Application with following arguments: '{singleArgument}'.", "OK", isMainThread: true); - messageUi.ShowDialog(); -#endif - p.Start(); - } - } - private static string? ParseCustomSearchEngine(string argument) { var argParsed = argument.Remove(0, 6); @@ -390,110 +261,6 @@ private static SearchEngine ParseSearchEngine(string argument) _ => SearchEngine.Google // Fallback search engine }; } - - private static bool ContainsParsedData(IEnumerable args) - { - var contains = false; - var engineUrl = DefineEngine(Configuration.Search); - - foreach (var arg in args) - { - if (arg.Contains(engineUrl)) - contains = true; - } - return contains; - } - - private static string ParseUrl(string encodedUrl) - { - // Remove URI handler with url argument prefix - encodedUrl = encodedUrl[encodedUrl.IndexOf("http", StringComparison.Ordinal)..]; - - // Remove junk after search term - if (encodedUrl.Contains("https%3A%2F%2Fwww.bing.com%2Fsearch%3Fq%3D") && !encodedUrl.Contains("redirect")) - encodedUrl = encodedUrl.Substring(encodedUrl.IndexOf("http", StringComparison.Ordinal), encodedUrl.IndexOf("%26", StringComparison.Ordinal)); - - // Alternative url form - if (encodedUrl.Contains("https%3A%2F%2Fwww.bing.com%2Fsearch%3Fform%3D")) - { - encodedUrl = encodedUrl.Substring(encodedUrl.IndexOf("26q%3D", StringComparison.Ordinal) + 6, encodedUrl.Length - (encodedUrl.IndexOf("26q%3D", StringComparison.Ordinal) + 6)); - encodedUrl = "https://www.bing.com/search?q=" + encodedUrl; - } - - // Decode Url - encodedUrl = encodedUrl.Contains("redirect") ? DotSlash(encodedUrl) : DecodeUrlString(encodedUrl); - - // Replace Search Engine - encodedUrl = encodedUrl.Replace("https://www.bing.com/search?q=", DefineEngine(Configuration.Search)); - -#if DEBUG - var uriMessageUi = new MessageUi("GoAwayEdge", - "New Uri: " + encodedUrl, "OK", isMainThread: true); - uriMessageUi.ShowDialog(); -#endif - var uri = new Uri(encodedUrl); - return uri.ToString(); - } - - private static string DefineEngine(SearchEngine engine) - { - var customQueryUrl = string.Empty; - try - { - customQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); - } - catch - { - // ignore; not an valid object - } - - return engine switch - { - SearchEngine.Google => "https://www.google.com/search?q=", - SearchEngine.Bing => "https://www.bing.com/search?q=", - SearchEngine.DuckDuckGo => "https://duckduckgo.com/?q=", - SearchEngine.Yahoo => "https://search.yahoo.com/search?p=", - SearchEngine.Yandex => "https://yandex.com/search/?text=", - SearchEngine.Ecosia => "https://www.ecosia.org/search?q=", - SearchEngine.Ask => "https://www.ask.com/web?q=", - SearchEngine.Qwant => "https://qwant.com/?q=", - SearchEngine.Perplexity => "https://www.perplexity.ai/search?copilot=false&q=", - SearchEngine.Custom => customQueryUrl, - _ => "https://www.google.com/search?q=" - }; - } - - private static string DecodeUrlString(string url) - { - string newUrl; - while ((newUrl = Uri.UnescapeDataString(url)) != url) - url = newUrl; - return newUrl; - } - - private static string DotSlash(string url) - { - string newUrl; - while ((newUrl = Uri.UnescapeDataString(url)) != url) - url = newUrl; - - try // Decode base64 string from url - { - var uri = new Uri(url); - var query = HttpUtility.ParseQueryString(uri.Query).Get("url"); - if (query != null) - { - var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(query)); - return decoded; - } - } - catch - { - // ignored - } - - return url; - } private static bool IsAdministrator() { diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index dc814cc..1520807 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,5 +1,4 @@ using System.IO; -using System.Windows; using Microsoft.Win32; namespace GoAwayEdge.Common diff --git a/GoAwayEdge/Common/Debugging/DebugMessage.cs b/GoAwayEdge/Common/Debugging/DebugMessage.cs new file mode 100644 index 0000000..8c02d37 --- /dev/null +++ b/GoAwayEdge/Common/Debugging/DebugMessage.cs @@ -0,0 +1,17 @@ +namespace GoAwayEdge.Common.Debugging +{ + internal class DebugMessage + { + /// + /// Displays a debug message if the application is in debug mode. + /// + /// The title of the debug message. + /// The content of the debug message. + public static void DisplayDebugMessage(string title, string message) + { + if (!App.IsDebug) return; + var w = new MessageUi(title, message, "OK", isMainThread: true); + w.ShowDialog(); + } + } +} diff --git a/GoAwayEdge/Common/Logging.cs b/GoAwayEdge/Common/Debugging/Logging.cs similarity index 96% rename from GoAwayEdge/Common/Logging.cs rename to GoAwayEdge/Common/Debugging/Logging.cs index 24f0428..da523a8 100644 --- a/GoAwayEdge/Common/Logging.cs +++ b/GoAwayEdge/Common/Debugging/Logging.cs @@ -17,7 +17,7 @@ using System.IO; using System.Reflection; -namespace GoAwayEdge.Common +namespace GoAwayEdge.Common.Debugging { internal class Logging { @@ -49,7 +49,7 @@ public static void Initialize() public static void Log(string message, LogLevel level = LogLevel.INFO) { - if (string.IsNullOrEmpty(_logFile)) + if (string.IsNullOrEmpty(_logFile)) throw new Exception("Logging class not initialized!"); using var writer = new StreamWriter(_logFile, true); writer.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {level} - {message}"); diff --git a/GoAwayEdge/Common/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs similarity index 99% rename from GoAwayEdge/Common/InstallRoutine.cs rename to GoAwayEdge/Common/Installation/InstallRoutine.cs index c446a43..c715e35 100644 --- a/GoAwayEdge/Common/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -6,6 +6,8 @@ using System.Windows; using System.Runtime.InteropServices; using System.Reflection; +using GoAwayEdge.Common.Installation; +using GoAwayEdge.Common.Debugging; namespace GoAwayEdge.Common { diff --git a/GoAwayEdge/Common/Removal.cs b/GoAwayEdge/Common/Installation/Removal.cs similarity index 96% rename from GoAwayEdge/Common/Removal.cs rename to GoAwayEdge/Common/Installation/Removal.cs index 2ed7b80..b778fbb 100644 --- a/GoAwayEdge/Common/Removal.cs +++ b/GoAwayEdge/Common/Installation/Removal.cs @@ -1,390 +1,391 @@ -using System.Diagnostics; -using System.IO; -using Microsoft.Win32; - -namespace GoAwayEdge.Common -{ - public class Removal - { - /// - /// Removes Microsoft Edge completely from the system. - /// - /// - /// Result of the removal as boolean. - /// - public static bool RemoveMsEdge() - { - // - // Ok, this should be stable now. Current plan: - // - // 1. Remove Edge via edge setup (setup.exe --uninstall --system-level --verbose-logging --force-uninstall) - // 2. Prevent Edge from reinstalling - // 3. Recreate the URI protocol - // - // This way should left WebView2 etc in tact. - // - Logging.Log("Removing Microsoft Edge ..."); - - string edgeSetupPath; - string edgeNewestVersionPath; - if (!Directory.Exists(Path.GetDirectoryName(FileConfiguration.EdgePath))) - return false; - - var subDirectories = Directory.GetDirectories(Path.GetDirectoryName(FileConfiguration.EdgePath)!); - var validDirectories = subDirectories - .Where(dir => Version.TryParse(Path.GetFileName(dir), out _)) - .ToList(); - - if (validDirectories.Any()) - { - var sortedDirectories = validDirectories - .Select(dir => new - { - DirectoryPath = dir, - Version = new Version(Path.GetFileName(dir)) - }) - .OrderByDescending(x => x.Version); - - var newestDirectory = sortedDirectories.FirstOrDefault(); - edgeNewestVersionPath = newestDirectory!.DirectoryPath; - edgeSetupPath = Path.Combine(newestDirectory!.DirectoryPath, "Installer", "setup.exe"); - } - else - { - Logging.Log("Removal aborted: Edge was not found on this system.", Logging.LogLevel.WARNING); - return false; // Edge is already removed - } - - // Terminate processes - Logging.Log("Terminating Edge processes ..."); - KillProcess("MicrosoftEdge"); - KillProcess("chredge"); - KillProcess("msedge"); - KillProcess("MicrosoftEdgeUpdate"); - KillProcess("edge"); - - // Clean up registry - Logging.Log("Cleaning up registry ..."); - RemoveRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe"); - RemoveRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ie_to_edge_stub.exe"); - RemoveUserRegistryKey(@"Software\Classes\microsoft-edge"); - RemoveUserRegistryKey(@"Software\Classes\MSEdgeHTM"); - - // Write temporary URI handler into the registry - var status = Register.UriHandler(Register.UriType.microsoftEdge, - $"\"{FileConfiguration.EdgePath}\" \" --single-argument %1\""); - if (!status) - { - Logging.Log("Failed to register URI handler for Microsoft Edge.", Logging.LogLevel.ERROR); - return false; - } - - status = Register.UriHandler(Register.UriType.EdgeHTM, - $"\"{FileConfiguration.EdgePath}\" \" --single-argument %1\""); - if (!status) - { - Logging.Log("Failed to register URI handler for EdgeHTM.", Logging.LogLevel.ERROR); - return false; - } - - // Remove certain registry properties - try - { - string[] registryPaths = { "SOFTWARE\\Policies", "SOFTWARE", "SOFTWARE\\WOW6432Node" }; - string[] edgeProperties = - { - "InstallDefault", "Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062", - "Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" - }; - - foreach (var path in registryPaths) - { - using var key = Registry.LocalMachine.OpenSubKey($@"{path}\Microsoft\EdgeUpdate", true); - if (key == null) continue; - foreach (var prop in edgeProperties) - { - key.DeleteValue(prop, false); - } - } - - const string edgeUpdate = @"Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}"; - string[] onActions = { "on-os-upgrade", "on-logon", "on-logon-autolaunch", "on-logon-startup-boost" }; - string[] registryBases = { "SOFTWARE", "SOFTWARE\\Wow6432Node" }; - - foreach (var baseKey in registryBases) - { - foreach (var launch in onActions) - { - RemoveRegistryKey($@"HKLM\{baseKey}\{edgeUpdate}\Commands\{launch}"); - } - } - - registryPaths = new[] { "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE" }; - string[] nodes = { "", "\\Wow6432Node" }; - string[] removeWin32 = { "Microsoft Edge", "Microsoft Edge Update" }; - - foreach (var regPath in registryPaths) - { - foreach (var node in nodes) - { - foreach (var i in removeWin32) - { - var uninstallPath = $@"{regPath}\SOFTWARE{node}\Microsoft\Windows\CurrentVersion\Uninstall\{i}"; - - using (var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) - { - using var uninstallKey = key.OpenSubKey(uninstallPath, true); - uninstallKey?.DeleteValue("NoRemove", false); - } - var edgeUpdateDevKey = Registry.LocalMachine.CreateSubKey($@"SOFTWARE{node}\Microsoft\EdgeUpdateDev"); - edgeUpdateDevKey.SetValue("AllowUninstall", 1, RegistryValueKind.DWord); - } - } - } - } - catch - { - Logging.Log("Failed to remove certain registry properties.", Logging.LogLevel.ERROR); - return false; - } - - // Find and copy ie_to_edge_stub.exe - var ieToEdgeStubFile = Path.Combine(edgeNewestVersionPath, "BHO", "ie_to_edge_stub.exe"); - if (File.Exists(ieToEdgeStubFile)) - { - try - { - File.Copy(ieToEdgeStubFile, Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe"), true); - } - catch - { - Logging.Log("Failed to copy ie_to_edge_stub.exe.", Logging.LogLevel.ERROR); - return false; - } - } - else - { - Logging.Log("ie_to_edge_stub.exe not found.", Logging.LogLevel.ERROR); - return false; - } - - // AppX Removal - const string removeAppX = "MicrosoftEdge"; - const string storePath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore"; - string[] userSids = { "S-1-5-18" }; - var packageFullNameList = new List(); - - try - { - if (Registry.LocalMachine.OpenSubKey(storePath) != null) - { - var subKeyNames = Registry.LocalMachine.OpenSubKey(storePath)!.GetSubKeyNames(); - foreach (var subKeyName in subKeyNames) - { - if (!subKeyName.Contains("S-1-5-21")) continue; - userSids = userSids.Append(subKeyName).ToArray(); - - var userKey = Registry.LocalMachine.OpenSubKey($"{storePath}\\{subKeyName}", false); - if (userKey == null) continue; - var subkeyNames = userKey.GetSubKeyNames(); - foreach (var subkeyName in subkeyNames) - { - if (subkeyName.Contains(removeAppX) && !packageFullNameList.Contains(subkeyName)) - { - packageFullNameList.Add(subkeyName); - } - } - } - } - } - catch - { - Logging.Log("Failed to remove AppX packages.", Logging.LogLevel.ERROR); - return false; - } - - // Removing Edge (+ Updater) - var timeoutStopwatch = new Stopwatch(); - var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); - var edgeUpdatePath = Path.Combine(programFiles, "Microsoft", "EdgeUpdate", "MicrosoftEdgeUpdate.exe"); - - try - { - if (File.Exists(edgeUpdatePath)) - { - using (var proc = new Process()) // Remove Edge Updater - { - var psi = new ProcessStartInfo - { - FileName = edgeUpdatePath, - Arguments = "/uninstall", - }; - proc.StartInfo = psi; - proc.Start(); - proc.WaitForExit(); - - timeoutStopwatch.Start(); - while (timeoutStopwatch.Elapsed.TotalSeconds < 60 && - (IsProcessRunning("MicrosoftEdgeUpdate") || IsEdgeProcessRunning())) - { - Thread.Sleep(3000); - } - - timeoutStopwatch.Stop(); - if (timeoutStopwatch.Elapsed.TotalSeconds >= 60) - return false; // Timeout - if (proc.ExitCode != 0 && proc.ExitCode != 19) - return false; // Unknown error? - } - - using (var proc = new Process()) // Remove Edge via setup file - { - var psi = new ProcessStartInfo - { - FileName = edgeSetupPath, - Arguments = "--uninstall --msedge --system-level --verbose-logging --force-uninstall", - RedirectStandardOutput = true - }; - proc.StartInfo = psi; - proc.Start(); - proc.WaitForExit(); - - timeoutStopwatch.Start(); - while (timeoutStopwatch.Elapsed.TotalSeconds < 60 && - (IsProcessRunning("setup") || IsEdgeProcessRunning())) - { - Thread.Sleep(3000); - } - - timeoutStopwatch.Stop(); - if (timeoutStopwatch.Elapsed.TotalSeconds >= 60) - return false; // Timeout - if (proc.ExitCode != 0 && proc.ExitCode != 19) - return false; // Unknown error? - } - } - } - catch (Exception ex) - { - Logging.Log("Exception: " + ex, Logging.LogLevel.ERROR); - return false; - } - - // Prevent Edge from reinstalling - try - { - using var baseKey = Registry.LocalMachine; - using var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft", true) ?? - baseKey.CreateSubKey(@"SOFTWARE\Microsoft"); - using var edgeUpdate = key.CreateSubKey("EdgeUpdate"); - edgeUpdate.SetValue("DoNotUpdateToEdgeWithChromium", 1, RegistryValueKind.DWord); - } - catch (Exception ex) - { - Logging.Log("Failed to prevent Edge from reinstalling: " + ex, Logging.LogLevel.ERROR); - return false; - } - - // Register new URIs - status = Register.UriHandler(Register.UriType.microsoftEdge, - $"\"{Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe")}\" \"%1\""); - if (!status) - { - Logging.Log("Failed to register URI handler for Microsoft Edge.", Logging.LogLevel.ERROR); - return false; - } - - status = Register.UriHandler(Register.UriType.EdgeHTM, - $"\"{Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe")}\" \"%1\""); - if (!status) - { - Logging.Log("Failed to register URI handler for EdgeHTM.", Logging.LogLevel.ERROR); - return false; - } - - status = Register.ImageFileExecutionOption( - Register.IfeoType.ie_to_edge_stub, - Path.Combine(Configuration.InstallDir, "GoAwayEdge.exe"), - Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe")); - - if (!status) - { - Logging.Log("Failed to register Image File Execution Option for ie_to_edge_stub.", Logging.LogLevel.ERROR); - return false; - } - - // Set registry config - RegistryConfig.SetKey("NoEdgeInstalled", true); - - Logging.Log("Microsoft Edge has been removed successfully."); - return true; - } - - /// - /// Terminate the specific process. - /// - /// - /// Result of the termination as boolean. - /// - public static bool KillProcess(string processName) - { - try - { - foreach (var process in Process.GetProcessesByName(processName)) - { - process.Kill(); - } - - return true; - } - catch (Exception ex) - { - Logging.Log($"Failed to kill process {processName}: {ex}", Logging.LogLevel.ERROR); - return false; - } - } - - private static bool IsProcessRunning(string processName) - { - var processes = Process.GetProcessesByName(processName); - return processes.Length > 0; - } - - private static bool IsEdgeProcessRunning() - { - var processes = Process.GetProcesses(); - return processes.Any(process => process.ProcessName.StartsWith("MicrosoftEdge", StringComparison.OrdinalIgnoreCase) && process.MainModule != null && process.MainModule.FileName.Contains("\\Microsoft\\Edge")); - } - - private static void RemoveRegistryKey(string keyPath) - { - using var key = Registry.LocalMachine.OpenSubKey(keyPath, true); - if (key != null) - { - Registry.LocalMachine.DeleteSubKeyTree(keyPath, false); - } - } - - private static void RemoveUserRegistryKey(string keyPath) - { - try - { - var users = Registry.Users.GetSubKeyNames(); - foreach (var userSid in users) - { - using var userKey = Registry.Users.OpenSubKey(userSid); - using var key = userKey?.OpenSubKey(keyPath, true); - if (key != null) - { - userKey!.DeleteSubKeyTree(keyPath, false); - } - } - } - catch (Exception ex) - { - Logging.Log($"Exception while removing registry key: {ex}"); - Debug.WriteLine($"Exception while removing registry key: {ex.Message}"); - } - } - } -} +using System.Diagnostics; +using System.IO; +using GoAwayEdge.Common.Debugging; +using Microsoft.Win32; + +namespace GoAwayEdge.Common.Installation +{ + public class Removal + { + /// + /// Removes Microsoft Edge completely from the system. + /// + /// + /// Result of the removal as boolean. + /// + public static bool RemoveMsEdge() + { + // + // Ok, this should be stable now. Current plan: + // + // 1. Remove Edge via edge setup (setup.exe --uninstall --system-level --verbose-logging --force-uninstall) + // 2. Prevent Edge from reinstalling + // 3. Recreate the URI protocol + // + // This way should left WebView2 etc in tact. + // + Logging.Log("Removing Microsoft Edge ..."); + + string edgeSetupPath; + string edgeNewestVersionPath; + if (!Directory.Exists(Path.GetDirectoryName(FileConfiguration.EdgePath))) + return false; + + var subDirectories = Directory.GetDirectories(Path.GetDirectoryName(FileConfiguration.EdgePath)!); + var validDirectories = subDirectories + .Where(dir => Version.TryParse(Path.GetFileName(dir), out _)) + .ToList(); + + if (validDirectories.Any()) + { + var sortedDirectories = validDirectories + .Select(dir => new + { + DirectoryPath = dir, + Version = new Version(Path.GetFileName(dir)) + }) + .OrderByDescending(x => x.Version); + + var newestDirectory = sortedDirectories.FirstOrDefault(); + edgeNewestVersionPath = newestDirectory!.DirectoryPath; + edgeSetupPath = Path.Combine(newestDirectory!.DirectoryPath, "Installer", "setup.exe"); + } + else + { + Logging.Log("Removal aborted: Edge was not found on this system.", Logging.LogLevel.WARNING); + return false; // Edge is already removed + } + + // Terminate processes + Logging.Log("Terminating Edge processes ..."); + KillProcess("MicrosoftEdge"); + KillProcess("chredge"); + KillProcess("msedge"); + KillProcess("MicrosoftEdgeUpdate"); + KillProcess("edge"); + + // Clean up registry + Logging.Log("Cleaning up registry ..."); + RemoveRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe"); + RemoveRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ie_to_edge_stub.exe"); + RemoveUserRegistryKey(@"Software\Classes\microsoft-edge"); + RemoveUserRegistryKey(@"Software\Classes\MSEdgeHTM"); + + // Write temporary URI handler into the registry + var status = Register.UriHandler(Register.UriType.microsoftEdge, + $"\"{FileConfiguration.EdgePath}\" \" --single-argument %1\""); + if (!status) + { + Logging.Log("Failed to register URI handler for Microsoft Edge.", Logging.LogLevel.ERROR); + return false; + } + + status = Register.UriHandler(Register.UriType.EdgeHTM, + $"\"{FileConfiguration.EdgePath}\" \" --single-argument %1\""); + if (!status) + { + Logging.Log("Failed to register URI handler for EdgeHTM.", Logging.LogLevel.ERROR); + return false; + } + + // Remove certain registry properties + try + { + string[] registryPaths = { "SOFTWARE\\Policies", "SOFTWARE", "SOFTWARE\\WOW6432Node" }; + string[] edgeProperties = + { + "InstallDefault", "Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062", + "Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" + }; + + foreach (var path in registryPaths) + { + using var key = Registry.LocalMachine.OpenSubKey($@"{path}\Microsoft\EdgeUpdate", true); + if (key == null) continue; + foreach (var prop in edgeProperties) + { + key.DeleteValue(prop, false); + } + } + + const string edgeUpdate = @"Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}"; + string[] onActions = { "on-os-upgrade", "on-logon", "on-logon-autolaunch", "on-logon-startup-boost" }; + string[] registryBases = { "SOFTWARE", "SOFTWARE\\Wow6432Node" }; + + foreach (var baseKey in registryBases) + { + foreach (var launch in onActions) + { + RemoveRegistryKey($@"HKLM\{baseKey}\{edgeUpdate}\Commands\{launch}"); + } + } + + registryPaths = new[] { "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE" }; + string[] nodes = { "", "\\Wow6432Node" }; + string[] removeWin32 = { "Microsoft Edge", "Microsoft Edge Update" }; + + foreach (var regPath in registryPaths) + { + foreach (var node in nodes) + { + foreach (var i in removeWin32) + { + var uninstallPath = $@"{regPath}\SOFTWARE{node}\Microsoft\Windows\CurrentVersion\Uninstall\{i}"; + + using (var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) + { + using var uninstallKey = key.OpenSubKey(uninstallPath, true); + uninstallKey?.DeleteValue("NoRemove", false); + } + var edgeUpdateDevKey = Registry.LocalMachine.CreateSubKey($@"SOFTWARE{node}\Microsoft\EdgeUpdateDev"); + edgeUpdateDevKey.SetValue("AllowUninstall", 1, RegistryValueKind.DWord); + } + } + } + } + catch + { + Logging.Log("Failed to remove certain registry properties.", Logging.LogLevel.ERROR); + return false; + } + + // Find and copy ie_to_edge_stub.exe + var ieToEdgeStubFile = Path.Combine(edgeNewestVersionPath, "BHO", "ie_to_edge_stub.exe"); + if (File.Exists(ieToEdgeStubFile)) + { + try + { + File.Copy(ieToEdgeStubFile, Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe"), true); + } + catch + { + Logging.Log("Failed to copy ie_to_edge_stub.exe.", Logging.LogLevel.ERROR); + return false; + } + } + else + { + Logging.Log("ie_to_edge_stub.exe not found.", Logging.LogLevel.ERROR); + return false; + } + + // AppX Removal + const string removeAppX = "MicrosoftEdge"; + const string storePath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore"; + string[] userSids = { "S-1-5-18" }; + var packageFullNameList = new List(); + + try + { + if (Registry.LocalMachine.OpenSubKey(storePath) != null) + { + var subKeyNames = Registry.LocalMachine.OpenSubKey(storePath)!.GetSubKeyNames(); + foreach (var subKeyName in subKeyNames) + { + if (!subKeyName.Contains("S-1-5-21")) continue; + userSids = userSids.Append(subKeyName).ToArray(); + + var userKey = Registry.LocalMachine.OpenSubKey($"{storePath}\\{subKeyName}", false); + if (userKey == null) continue; + var subkeyNames = userKey.GetSubKeyNames(); + foreach (var subkeyName in subkeyNames) + { + if (subkeyName.Contains(removeAppX) && !packageFullNameList.Contains(subkeyName)) + { + packageFullNameList.Add(subkeyName); + } + } + } + } + } + catch + { + Logging.Log("Failed to remove AppX packages.", Logging.LogLevel.ERROR); + return false; + } + + // Removing Edge (+ Updater) + var timeoutStopwatch = new Stopwatch(); + var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); + var edgeUpdatePath = Path.Combine(programFiles, "Microsoft", "EdgeUpdate", "MicrosoftEdgeUpdate.exe"); + + try + { + if (File.Exists(edgeUpdatePath)) + { + using (var proc = new Process()) // Remove Edge Updater + { + var psi = new ProcessStartInfo + { + FileName = edgeUpdatePath, + Arguments = "/uninstall", + }; + proc.StartInfo = psi; + proc.Start(); + proc.WaitForExit(); + + timeoutStopwatch.Start(); + while (timeoutStopwatch.Elapsed.TotalSeconds < 60 && + (IsProcessRunning("MicrosoftEdgeUpdate") || IsEdgeProcessRunning())) + { + Thread.Sleep(3000); + } + + timeoutStopwatch.Stop(); + if (timeoutStopwatch.Elapsed.TotalSeconds >= 60) + return false; // Timeout + if (proc.ExitCode != 0 && proc.ExitCode != 19) + return false; // Unknown error? + } + + using (var proc = new Process()) // Remove Edge via setup file + { + var psi = new ProcessStartInfo + { + FileName = edgeSetupPath, + Arguments = "--uninstall --msedge --system-level --verbose-logging --force-uninstall", + RedirectStandardOutput = true + }; + proc.StartInfo = psi; + proc.Start(); + proc.WaitForExit(); + + timeoutStopwatch.Start(); + while (timeoutStopwatch.Elapsed.TotalSeconds < 60 && + (IsProcessRunning("setup") || IsEdgeProcessRunning())) + { + Thread.Sleep(3000); + } + + timeoutStopwatch.Stop(); + if (timeoutStopwatch.Elapsed.TotalSeconds >= 60) + return false; // Timeout + if (proc.ExitCode != 0 && proc.ExitCode != 19) + return false; // Unknown error? + } + } + } + catch (Exception ex) + { + Logging.Log("Exception: " + ex, Logging.LogLevel.ERROR); + return false; + } + + // Prevent Edge from reinstalling + try + { + using var baseKey = Registry.LocalMachine; + using var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft", true) ?? + baseKey.CreateSubKey(@"SOFTWARE\Microsoft"); + using var edgeUpdate = key.CreateSubKey("EdgeUpdate"); + edgeUpdate.SetValue("DoNotUpdateToEdgeWithChromium", 1, RegistryValueKind.DWord); + } + catch (Exception ex) + { + Logging.Log("Failed to prevent Edge from reinstalling: " + ex, Logging.LogLevel.ERROR); + return false; + } + + // Register new URIs + status = Register.UriHandler(Register.UriType.microsoftEdge, + $"\"{Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe")}\" \"%1\""); + if (!status) + { + Logging.Log("Failed to register URI handler for Microsoft Edge.", Logging.LogLevel.ERROR); + return false; + } + + status = Register.UriHandler(Register.UriType.EdgeHTM, + $"\"{Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe")}\" \"%1\""); + if (!status) + { + Logging.Log("Failed to register URI handler for EdgeHTM.", Logging.LogLevel.ERROR); + return false; + } + + status = Register.ImageFileExecutionOption( + Register.IfeoType.ie_to_edge_stub, + Path.Combine(Configuration.InstallDir, "GoAwayEdge.exe"), + Path.Combine(Configuration.InstallDir, "ie_to_edge_stub.exe")); + + if (!status) + { + Logging.Log("Failed to register Image File Execution Option for ie_to_edge_stub.", Logging.LogLevel.ERROR); + return false; + } + + // Set registry config + RegistryConfig.SetKey("NoEdgeInstalled", true); + + Logging.Log("Microsoft Edge has been removed successfully."); + return true; + } + + /// + /// Terminate the specific process. + /// + /// + /// Result of the termination as boolean. + /// + public static bool KillProcess(string processName) + { + try + { + foreach (var process in Process.GetProcessesByName(processName)) + { + process.Kill(); + } + + return true; + } + catch (Exception ex) + { + Logging.Log($"Failed to kill process {processName}: {ex}", Logging.LogLevel.ERROR); + return false; + } + } + + private static bool IsProcessRunning(string processName) + { + var processes = Process.GetProcessesByName(processName); + return processes.Length > 0; + } + + private static bool IsEdgeProcessRunning() + { + var processes = Process.GetProcesses(); + return processes.Any(process => process.ProcessName.StartsWith("MicrosoftEdge", StringComparison.OrdinalIgnoreCase) && process.MainModule != null && process.MainModule.FileName.Contains("\\Microsoft\\Edge")); + } + + private static void RemoveRegistryKey(string keyPath) + { + using var key = Registry.LocalMachine.OpenSubKey(keyPath, true); + if (key != null) + { + Registry.LocalMachine.DeleteSubKeyTree(keyPath, false); + } + } + + private static void RemoveUserRegistryKey(string keyPath) + { + try + { + var users = Registry.Users.GetSubKeyNames(); + foreach (var userSid in users) + { + using var userKey = Registry.Users.OpenSubKey(userSid); + using var key = userKey?.OpenSubKey(keyPath, true); + if (key != null) + { + userKey!.DeleteSubKeyTree(keyPath, false); + } + } + } + catch (Exception ex) + { + Logging.Log($"Exception while removing registry key: {ex}"); + System.Diagnostics.Debug.WriteLine($"Exception while removing registry key: {ex.Message}"); + } + } + } +} diff --git a/GoAwayEdge/Common/Updater.cs b/GoAwayEdge/Common/Installation/Updater.cs similarity index 97% rename from GoAwayEdge/Common/Updater.cs rename to GoAwayEdge/Common/Installation/Updater.cs index 7e117be..66bdc64 100644 --- a/GoAwayEdge/Common/Updater.cs +++ b/GoAwayEdge/Common/Installation/Updater.cs @@ -1,222 +1,222 @@ -using Microsoft.Toolkit.Uwp.Notifications; -using Microsoft.Win32; -using System.Diagnostics; -using System.IO; -using System.Net; -using System.Reflection; -using System.Security.Cryptography; -using Newtonsoft.Json; - -namespace GoAwayEdge.Common -{ - internal class Updater - { - public class GitHubRelease - { - public string tag_name { get; set; } - public List assets { get; set; } - } - - public class GitHubAsset - { - public string browser_download_url { get; set; } - public string name { get; set; } - } - - - /// - /// Validates if the installed IFEO-Binary is identical with the Edge-Binary. - /// - /// - /// Integer value if the Binary is identical, not identical or missing. - /// 0 : true (also reported if Edge is not installed) - /// 1 : false - /// 2 : missing - /// - public static int ValidateIfeoBinary() - { - if (Configuration.NoEdgeInstalled) return 0; - - var key = Registry.LocalMachine.OpenSubKey( - @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe\0"); - if (key == null) - { - Console.WriteLine("Registry key not found."); - return 2; - } - - var binaryPath = (string)key.GetValue("FilterFullPath")!; - if (string.IsNullOrEmpty(binaryPath)) - { - Console.WriteLine("FilterFullPath value not found."); - return 2; - } - - var edgeBinaryPath = Path.Combine(Path.GetDirectoryName(binaryPath)!, "msedge.exe"); - var ifeoBinaryPath = Path.Combine(Path.GetDirectoryName(binaryPath)!, "msedge_non_ifeo.exe"); - - if (File.Exists(ifeoBinaryPath)) - { - var edgeHash = CalculateMd5(edgeBinaryPath); - var ifeoHash = CalculateMd5(ifeoBinaryPath); -#if DEBUG - if (edgeHash != ifeoHash) - { - var messageUi = new MessageUi("GoAwayEdge", - $"The Edge Hash ({edgeHash}) and Ifeo Hash ({ifeoHash}) are not identical. Validation failed!", "OK", isMainThread: true); - messageUi.ShowDialog(); - } -#endif - return edgeHash != ifeoHash ? 1 : 0; - } - - Console.WriteLine($"Ifeo binary does not exist: {ifeoBinaryPath}"); - return 2; - } - - /// - /// Modifies the Ifeo binary. - /// - public static void ModifyIfeoBinary(ModifyAction action) - { - switch (action) - { - case ModifyAction.Update: - { - try - { - File.Copy(FileConfiguration.EdgePath, FileConfiguration.NonIfeoPath, true); - - var title = LocalizationManager.LocalizeValue("IfeoUpdateSuccessfulTitle"); - var description = LocalizationManager.LocalizeValue("IfeoUpdateSuccessfulDescription"); - new ToastContentBuilder() - .AddText(title) - .AddText(description) - .Show(); - } - catch (Exception ex) - { - var message = LocalizationManager.LocalizeValue("FailedUpdate", ex.Message); - var messageUi = new MessageUi("GoAwayEdge", message, "OK", isMainThread: true); - messageUi.ShowDialog(); - } - break; - } - case ModifyAction.Create: - { - try - { - File.Copy(FileConfiguration.EdgePath, FileConfiguration.NonIfeoPath, true); - - var title = LocalizationManager.LocalizeValue("IfeoCreateSuccessfulTitle"); - var description = LocalizationManager.LocalizeValue("IfeoCreateSuccessfulDescription"); - new ToastContentBuilder() - .AddText(title) - .AddText(description) - .Show(); - } - catch (Exception ex) - { - var message = LocalizationManager.LocalizeValue("FailedUpdate", ex.Message); - var messageUi = new MessageUi("GoAwayEdge", message, "OK", isMainThread: true); - messageUi.ShowDialog(); - } - break; - } - default: - throw new ArgumentOutOfRangeException(nameof(action), action, null); - } - } - - /// - /// Checks if a newer version of GoAwayEdge exists. - /// - /// - /// Boolean status of the existence of a newer version. - /// - public static string? CheckForAppUpdate() - { - const string url = "https://api.github.com/repos/valnoxy/GoAwayEdge/releases"; - - try - { - var appVersion = Assembly.GetExecutingAssembly().GetName().Version!; - var currentVersion = new Version(appVersion.Major, appVersion.Minor, appVersion.Build); - - using var client = new WebClient(); - client.Headers.Add("User-Agent", $"GoAwayEdge/{currentVersion} valnoxy.dev"); - var json = client.DownloadString(url); - - var releases = JsonConvert.DeserializeObject(json); - if (releases is { Length: > 0 }) - { - var tagName = Convert.ToString(releases[0].tag_name); - var tagVersion = tagName[1..]; - var latestVersion = new Version(tagVersion); - - if (currentVersion < latestVersion) - return latestVersion.ToString(); - } - return null; - } - catch (Exception ex) - { - Console.WriteLine(ex); - return null; - } - } - - /// - /// Download and run the new version of GoAwayEdge. - /// - public static bool UpdateClient() - { - const string url = "https://api.github.com/repos/valnoxy/GoAwayEdge/releases"; - - try - { - var appVersion = Assembly.GetExecutingAssembly().GetName().Version!; - var currentVersion = new Version(appVersion.Major, appVersion.Minor, appVersion.Build); - - using var client = new WebClient(); - client.Headers.Add("User-Agent", $"GoAwayEdge/{currentVersion} valnoxy.dev"); - var json = client.DownloadString(url); - - var releases = JsonConvert.DeserializeObject(json); - if (releases is { Length: > 0 }) - { - var assetUrl = string.Empty; - foreach (var asset in releases[0].assets.Where(asset => asset.name == "GoAwayEdge.exe")) - { - assetUrl = asset.browser_download_url; - } - - var tempFolder = Path.GetTempPath(); - if (string.IsNullOrEmpty(assetUrl)) - { - return false; - } - - if (File.Exists(Path.Combine(tempFolder, "GoAwayEdge.exe"))) - File.Delete(Path.Combine(tempFolder, "GoAwayEdge.exe")); - client.DownloadFile(assetUrl, Path.Combine(tempFolder, "GoAwayEdge.exe")); - Process.Start(Path.Combine(tempFolder, "GoAwayEdge.exe")); - return true; - } - } - catch - { - return false; - } - return false; - } - - private static string CalculateMd5(string filename) - { - using var md5 = MD5.Create(); - using var stream = File.OpenRead(filename); - var hash = md5.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } - } -} +using Microsoft.Toolkit.Uwp.Notifications; +using Microsoft.Win32; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Reflection; +using System.Security.Cryptography; +using Newtonsoft.Json; + +namespace GoAwayEdge.Common +{ + internal class Updater + { + public class GitHubRelease + { + public string tag_name { get; set; } + public List assets { get; set; } + } + + public class GitHubAsset + { + public string browser_download_url { get; set; } + public string name { get; set; } + } + + + /// + /// Validates if the installed IFEO-Binary is identical with the Edge-Binary. + /// + /// + /// Integer value if the Binary is identical, not identical or missing. + /// 0 : true (also reported if Edge is not installed) + /// 1 : false + /// 2 : missing + /// + public static int ValidateIfeoBinary() + { + if (Configuration.NoEdgeInstalled) return 0; + + var key = Registry.LocalMachine.OpenSubKey( + @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe\0"); + if (key == null) + { + Console.WriteLine("Registry key not found."); + return 2; + } + + var binaryPath = (string)key.GetValue("FilterFullPath")!; + if (string.IsNullOrEmpty(binaryPath)) + { + Console.WriteLine("FilterFullPath value not found."); + return 2; + } + + var edgeBinaryPath = Path.Combine(Path.GetDirectoryName(binaryPath)!, "msedge.exe"); + var ifeoBinaryPath = Path.Combine(Path.GetDirectoryName(binaryPath)!, "msedge_non_ifeo.exe"); + + if (File.Exists(ifeoBinaryPath)) + { + var edgeHash = CalculateMd5(edgeBinaryPath); + var ifeoHash = CalculateMd5(ifeoBinaryPath); +#if DEBUG + if (edgeHash != ifeoHash) + { + var messageUi = new MessageUi("GoAwayEdge", + $"The Edge Hash ({edgeHash}) and Ifeo Hash ({ifeoHash}) are not identical. Validation failed!", "OK", isMainThread: true); + messageUi.ShowDialog(); + } +#endif + return edgeHash != ifeoHash ? 1 : 0; + } + + Console.WriteLine($"Ifeo binary does not exist: {ifeoBinaryPath}"); + return 2; + } + + /// + /// Modifies the Ifeo binary. + /// + public static void ModifyIfeoBinary(ModifyAction action) + { + switch (action) + { + case ModifyAction.Update: + { + try + { + File.Copy(FileConfiguration.EdgePath, FileConfiguration.NonIfeoPath, true); + + var title = LocalizationManager.LocalizeValue("IfeoUpdateSuccessfulTitle"); + var description = LocalizationManager.LocalizeValue("IfeoUpdateSuccessfulDescription"); + new ToastContentBuilder() + .AddText(title) + .AddText(description) + .Show(); + } + catch (Exception ex) + { + var message = LocalizationManager.LocalizeValue("FailedUpdate", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", message, "OK", isMainThread: true); + messageUi.ShowDialog(); + } + break; + } + case ModifyAction.Create: + { + try + { + File.Copy(FileConfiguration.EdgePath, FileConfiguration.NonIfeoPath, true); + + var title = LocalizationManager.LocalizeValue("IfeoCreateSuccessfulTitle"); + var description = LocalizationManager.LocalizeValue("IfeoCreateSuccessfulDescription"); + new ToastContentBuilder() + .AddText(title) + .AddText(description) + .Show(); + } + catch (Exception ex) + { + var message = LocalizationManager.LocalizeValue("FailedUpdate", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", message, "OK", isMainThread: true); + messageUi.ShowDialog(); + } + break; + } + default: + throw new ArgumentOutOfRangeException(nameof(action), action, null); + } + } + + /// + /// Checks if a newer version of GoAwayEdge exists. + /// + /// + /// Boolean status of the existence of a newer version. + /// + public static string? CheckForAppUpdate() + { + const string url = "https://api.github.com/repos/valnoxy/GoAwayEdge/releases"; + + try + { + var appVersion = Assembly.GetExecutingAssembly().GetName().Version!; + var currentVersion = new Version(appVersion.Major, appVersion.Minor, appVersion.Build); + + using var client = new WebClient(); + client.Headers.Add("User-Agent", $"GoAwayEdge/{currentVersion} valnoxy.dev"); + var json = client.DownloadString(url); + + var releases = JsonConvert.DeserializeObject(json); + if (releases is { Length: > 0 }) + { + var tagName = Convert.ToString(releases[0].tag_name); + var tagVersion = tagName[1..]; + var latestVersion = new Version(tagVersion); + + if (currentVersion < latestVersion) + return latestVersion.ToString(); + } + return null; + } + catch (Exception ex) + { + Console.WriteLine(ex); + return null; + } + } + + /// + /// Download and run the new version of GoAwayEdge. + /// + public static bool UpdateClient() + { + const string url = "https://api.github.com/repos/valnoxy/GoAwayEdge/releases"; + + try + { + var appVersion = Assembly.GetExecutingAssembly().GetName().Version!; + var currentVersion = new Version(appVersion.Major, appVersion.Minor, appVersion.Build); + + using var client = new WebClient(); + client.Headers.Add("User-Agent", $"GoAwayEdge/{currentVersion} valnoxy.dev"); + var json = client.DownloadString(url); + + var releases = JsonConvert.DeserializeObject(json); + if (releases is { Length: > 0 }) + { + var assetUrl = string.Empty; + foreach (var asset in releases[0].assets.Where(asset => asset.name == "GoAwayEdge.exe")) + { + assetUrl = asset.browser_download_url; + } + + var tempFolder = Path.GetTempPath(); + if (string.IsNullOrEmpty(assetUrl)) + { + return false; + } + + if (File.Exists(Path.Combine(tempFolder, "GoAwayEdge.exe"))) + File.Delete(Path.Combine(tempFolder, "GoAwayEdge.exe")); + client.DownloadFile(assetUrl, Path.Combine(tempFolder, "GoAwayEdge.exe")); + Process.Start(Path.Combine(tempFolder, "GoAwayEdge.exe")); + return true; + } + } + catch + { + return false; + } + return false; + } + + private static string CalculateMd5(string filename) + { + using var md5 = MD5.Create(); + using var stream = File.OpenRead(filename); + var hash = md5.ComputeHash(stream); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); + } + } +} diff --git a/GoAwayEdge/Common/Localization.cs b/GoAwayEdge/Common/Localization.cs index 3c7b7ec..7271633 100644 --- a/GoAwayEdge/Common/Localization.cs +++ b/GoAwayEdge/Common/Localization.cs @@ -1,5 +1,5 @@ -using System.Diagnostics; -using System.Windows; +using System.Windows; +using GoAwayEdge.Common.Debugging; namespace GoAwayEdge.Common { @@ -11,7 +11,7 @@ public static void LoadLanguage() var language = Thread.CurrentThread.CurrentCulture.ToString(); var dict = new ResourceDictionary(); Logging.Log($"Trying to load language: " + language); - Debug.WriteLine("Trying to load language: " + language); + System.Diagnostics.Debug.WriteLine("Trying to load language: " + language); dict.Source = language switch { "en-US" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.xaml", UriKind.Relative), diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs new file mode 100644 index 0000000..5460cb0 --- /dev/null +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -0,0 +1,143 @@ +using System.Diagnostics; +using System.IO; +using GoAwayEdge.Common.Debugging; + +namespace GoAwayEdge.Common.Runtime +{ + public class ArgumentParse + { + private static string? _url; + + /// + /// Main method for parsing command line arguments and starting the appropriate process. + /// + /// The command line arguments. + public static void Parse(string[] args) + { + var quotedArgs = args.Select(arg => arg.Contains(" ") ? $"\"{arg}\"" : arg); + var argumentJoin = string.Join(" ", quotedArgs); + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"The following args are redirected (CTRL+C to copy):\n\n{argumentJoin}"); + + var (isFile, isApp, singleArgument) = ParseArguments(args); + if (_url != null) + { + HandleUrl(_url); + } + else if (isFile) + { + StartProcess(FileConfiguration.NonIfeoPath, $"--single-argument {singleArgument}", $"Opening '{singleArgument}' with Edge."); + } + else if (isApp) + { + StartProcess(FileConfiguration.NonIfeoPath, singleArgument, $"Opening PWA Application with following arguments: '{singleArgument}'."); + } + } + + /// + /// Parses the command line arguments to identify if a file path or app ID is present. + /// + /// The command line arguments. + /// A tuple with the values isFile, isApp, and singleArgument. + private static (bool isFile, bool isApp, string singleArgument) ParseArguments(string[] args) + { + bool isFile = false, isApp = false, collectSingleArgument = false; + var singleArgument = string.Empty; + + foreach (var arg in args) + { + if (arg.Contains("microsoft-edge:")) + { + _url = arg; + } + + if (collectSingleArgument) + { + singleArgument += (singleArgument.Length > 0 ? " " : "") + arg; + continue; + } + + if (arg == "--single-argument" || arg.Contains("--app-id")) + { + collectSingleArgument = true; + } + + if (arg.Contains("--app-id")) + { + singleArgument = arg; + } + } + + if (File.Exists(singleArgument)) + isFile = true; + + if (singleArgument.Contains("--app-id")) + isApp = true; + + return (isFile, isApp, singleArgument); + } + + /// + /// Handles processing and starting a process based on the given URL. + /// + /// The URL to be processed. + private static void HandleUrl(string url) + { + var p = new Process + { + StartInfo = new ProcessStartInfo + { + UseShellExecute = true, + RedirectStandardOutput = false, + FileName = FileConfiguration.NonIfeoPath, + Arguments = url + } + }; + + // Copilot Taskbar + if (url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=taskbar") || + url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=taskbar")) + { + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Taskbar) with following url:\n{url}"); + } + // Copilot Hotkey + else if (url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=hotkey") || + url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=hotkey")) + { + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Hotkey) with following url:\n{url}"); + } + // Default + else + { + var parsedUrl = UrlParse.Parse(url); + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening URL in default browser:\n\n{parsedUrl}"); + p.StartInfo.FileName = parsedUrl; + p.StartInfo.Arguments = string.Empty; + } + + p.Start(); + } + + /// + /// Starts a process with the given file name and arguments. + /// + /// The file name to start. + /// The arguments to pass to the process. + /// The debug message to display. + private static void StartProcess(string fileName, string arguments, string debugMessage) + { + var p = new Process + { + StartInfo = new ProcessStartInfo + { + UseShellExecute = true, + RedirectStandardOutput = false, + FileName = fileName, + Arguments = arguments + } + }; + + DebugMessage.DisplayDebugMessage("GoAwayEdge", debugMessage); + p.Start(); + } + } +} diff --git a/GoAwayEdge/Common/Runtime/UrlParse.cs b/GoAwayEdge/Common/Runtime/UrlParse.cs new file mode 100644 index 0000000..4a1bf5c --- /dev/null +++ b/GoAwayEdge/Common/Runtime/UrlParse.cs @@ -0,0 +1,104 @@ +using System.Text; +using System.Web; + +namespace GoAwayEdge.Common.Runtime +{ + public class UrlParse + { + /// + /// Parses the given encoded URL and returns the processed URL. + /// + /// The encoded URL to parse. + /// The parsed URL. + public static string Parse(string encodedUrl) + { + // Remove URI handler with url argument prefix + encodedUrl = encodedUrl[encodedUrl.IndexOf("http", StringComparison.Ordinal)..]; + + // Remove junk after search term + if (encodedUrl.Contains("https%3A%2F%2Fwww.bing.com%2Fsearch%3Fq%3D") && !encodedUrl.Contains("redirect")) + encodedUrl = encodedUrl.Substring(encodedUrl.IndexOf("http", StringComparison.Ordinal), encodedUrl.IndexOf("%26", StringComparison.Ordinal)); + + // Alternative url form + if (encodedUrl.Contains("https%3A%2F%2Fwww.bing.com%2Fsearch%3Fform%3D")) + { + encodedUrl = encodedUrl.Substring(encodedUrl.IndexOf("26q%3D", StringComparison.Ordinal) + 6, encodedUrl.Length - (encodedUrl.IndexOf("26q%3D", StringComparison.Ordinal) + 6)); + encodedUrl = "https://www.bing.com/search?q=" + encodedUrl; + } + + // Decode Url + encodedUrl = encodedUrl.Contains("redirect") ? DotSlash(encodedUrl) : DecodeUrlString(encodedUrl); + + // Replace Search Engine + encodedUrl = encodedUrl.Replace("https://www.bing.com/search?q=", DefineEngine(Configuration.Search)); + +#if DEBUG + var uriMessageUi = new MessageUi("GoAwayEdge", + "New Uri: " + encodedUrl, "OK", isMainThread: true); + uriMessageUi.ShowDialog(); +#endif + var uri = new Uri(encodedUrl); + return uri.ToString(); + } + + private static string DefineEngine(SearchEngine engine) + { + var customQueryUrl = string.Empty; + try + { + customQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); + } + catch + { + // ignore; not an valid object + } + + return engine switch + { + SearchEngine.Google => "https://www.google.com/search?q=", + SearchEngine.Bing => "https://www.bing.com/search?q=", + SearchEngine.DuckDuckGo => "https://duckduckgo.com/?q=", + SearchEngine.Yahoo => "https://search.yahoo.com/search?p=", + SearchEngine.Yandex => "https://yandex.com/search/?text=", + SearchEngine.Ecosia => "https://www.ecosia.org/search?q=", + SearchEngine.Ask => "https://www.ask.com/web?q=", + SearchEngine.Qwant => "https://qwant.com/?q=", + SearchEngine.Perplexity => "https://www.perplexity.ai/search?copilot=false&q=", + SearchEngine.Custom => customQueryUrl, + _ => "https://www.google.com/search?q=" + }; + } + + private static string DecodeUrlString(string url) + { + string newUrl; + while ((newUrl = Uri.UnescapeDataString(url)) != url) + url = newUrl; + return newUrl; + } + + private static string DotSlash(string url) + { + string newUrl; + while ((newUrl = Uri.UnescapeDataString(url)) != url) + url = newUrl; + + try // Decode base64 string from url + { + var uri = new Uri(url); + var query = HttpUtility.ParseQueryString(uri.Query).Get("url"); + if (query != null) + { + var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(query)); + return decoded; + } + } + catch + { + // ignored + } + + return url; + } + } +} diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index 38e432b..b5dfbb1 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -12,7 +12,7 @@ GoAwayEdge Exploitox valnoxy - 1.3.4.153 + 2.0.0.160 Copyright (c) 2018 - 2024 Exploitox. All rights reserved. https://github.com/valnoxy/GoAwayEdge https://github.com/valnoxy/GoAwayEdge diff --git a/README.md b/README.md index 75e430e..729cdef 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ · Discussions · - Help me translate + Help me translate

🎉 Version 1.3.4 is out. Check out the release notes diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..8a9ac5b --- /dev/null +++ b/TODO.md @@ -0,0 +1,83 @@ +
+ + +
+ + GoAwayEdge Banner + +
+ + [![Version][version-shield]][version-url] + [![Download Counter][downloads-shield]][downloads-url] + [![License][license-shield]][license-url] + [![Weblate][weblate-shield]][weblate-url] +
+ +[version-shield]: https://img.shields.io/github/v/release/valnoxy/GoAwayEdge?color=9565F6 +[version-url]: https://github.com/valnoxy/GoAwayEdge/releases + +[weblate-shield]: http://translate.valnoxy.dev/widget/goawayedge/svg-badge.svg +[weblate-url]: https://translate.valnoxy.dev/engage/goawayedge/ + +[downloads-shield]: https://img.shields.io/github/downloads/valnoxy/GoAwayEdge/total.svg?color=431D93 +[downloads-url]: https://github.com/valnoxy/GoAwayEdge/releases + +[license-shield]: https://img.shields.io/github/license/valnoxy/GoAwayEdge?color=9565F6 +[license-url]: https://img.shields.io/github/license/valnoxy/GoAwayEdge + +
+

GoAwayEdge

+

+

Don't like Microsoft Edge? Me neither. Redirect all Edge calls to your favorite browser!

+ Download now + · + Report Bug + · + Discussions + · + Help me translate +
+
+

+
+ +--- + +# TODO list for Version 2.0 + +## Features +- [ ] Settings Menu +- [ ] Change functionality of Copilot key / taskbar icon +- [ ] Change Weather service +- [ ] Silent App Updater + +## Quality of Life +- [ ] Redesigned parsing engine +- [ ] Redesigned logging system + +# Development Notes + +### Search Bar Arguments (search term: "hallo") +``` +"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument microsoft-edge:?url=https%3A%2F%2Fwww.bing.com%2Fsearch%3Fq%3Dhallo%26form%3DWSBEDG%26qs%3DAS%26cvid%3D12fe0e3529de48c0815fa6882e348e59%26pq%3DHallo%26cc%3DDE%26setlang%3Dde-DE%26nclid%3DF1C9E841B291A09001E0E245264AC67E%26ts%3D1722019735480%26nclidts%3D1722019735%26tsms%3D480%26wsso%3DModerate×tamp=1722019735480&source=WindowsSearchBox&campaign=addedgeprot&medium=AutoSuggest +``` + +### Copilot PWA Arguments +``` +"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --app-id=khiogjgiicnghciboipemonlmgelhblf --app-fallback-url=https://copilot.microsoft.com/?dpwa=1 --display-mode=standalone --windows-store-app --ip-proc-id=41940 --ip-binding --mojo-named-platform-channel-pipe=41940.41536.15380779445885585744 --ip-aumid=Microsoft.Copilot_8wekyb3d8bbwe!App +``` + +### Copilot Taskbar (with Size) +``` +"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument microsoft-edge:///?ux=copilot&tcp=1&source=taskbar&invocationx=1888&invocationy=1056 +``` + +### Copilot Hotkey (WIN+C & Copilot Key) +``` +"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument microsoft-edge:///?ux=copilot&tcp=1&source=hotkey +``` + +### PDF file +``` +"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument "C:\Users\jonas\Downloads\test.pdf" +``` \ No newline at end of file From fb10d4e24333f0f72bf85f12e8e28ee014a85ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 29 Jul 2024 21:06:15 +0200 Subject: [PATCH 03/80] Implementation of the Control Panel Window --- GoAwayEdge/App.xaml.cs | 28 +- GoAwayEdge/GoAwayEdge.csproj | 5 + GoAwayEdge/GoAwayEdge.csproj.user | 37 ++- .../ControlCenter/ControlCenter.xaml | 134 +++++++++ .../ControlCenter/ControlCenter.xaml.cs | 66 +++++ .../ControlCenter/Pages/HomeScreen.xaml | 15 + .../ControlCenter/Pages/HomeScreen.xaml.cs | 28 ++ GoAwayEdge/{ => UserInterface}/MessageUI.xaml | 152 +++++----- .../{ => UserInterface}/MessageUI.xaml.cs | 140 ++++----- .../{ => UserInterface/Setup}/Installer.xaml | 128 ++++---- .../Setup}/Installer.xaml.cs | 139 +++++---- .../Setup}/Pages/Installation.xaml | 45 ++- .../Setup}/Pages/Installation.xaml.cs | 79 +++-- .../Setup}/Pages/InstallationSuccess.xaml | 49 ++- .../Setup}/Pages/InstallationSuccess.xaml.cs | 73 +++-- .../Setup}/Pages/License.xaml | 45 ++- .../Setup}/Pages/License.xaml.cs | 98 +++--- .../Setup}/Pages/Settings.xaml | 219 +++++++------- .../Setup}/Pages/Settings.xaml.cs | 278 +++++++++--------- .../Setup}/Pages/Welcome.xaml | 109 ++++--- .../Setup}/Pages/Welcome.xaml.cs | 79 +++-- 21 files changed, 1098 insertions(+), 848 deletions(-) create mode 100644 GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml create mode 100644 GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs create mode 100644 GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml create mode 100644 GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs rename GoAwayEdge/{ => UserInterface}/MessageUI.xaml (97%) rename GoAwayEdge/{ => UserInterface}/MessageUI.xaml.cs (96%) rename GoAwayEdge/{ => UserInterface/Setup}/Installer.xaml (96%) rename GoAwayEdge/{ => UserInterface/Setup}/Installer.xaml.cs (92%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/Installation.xaml (89%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/Installation.xaml.cs (88%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/InstallationSuccess.xaml (89%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/InstallationSuccess.xaml.cs (93%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/License.xaml (89%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/License.xaml.cs (95%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/Settings.xaml (96%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/Settings.xaml.cs (97%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/Welcome.xaml (94%) rename GoAwayEdge/{ => UserInterface/Setup}/Pages/Welcome.xaml.cs (89%) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 0d8a920..b50dfba 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -1,21 +1,18 @@ /* - * Go away Edge - IFEO Method - * by valnoxy (valnoxy.dev) - * ---------------------------------- - * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe - * > UseFilter (DWORD) = 1 + * GoAwayEdge + * Copyright (c) 2018 - 2024 valnoxy. * - * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe\0 - * > Debugger (REG_SZ) = "Path\To\GoAwayEdge.exe" - * > FullFilterPath (REG_SZ) = C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe + * GoAwayEdge is licensed under MIT License (https://github.com/valnoxy/GoAwayEdge/blob/main/LICENSE). + * So you are allowed to use freely and modify the application. + * I will not be responsible for any outcome. + * Proceed with any action at your own risk. + * + * Source code: https://github.com/valnoxy/GoAwayEdge */ using GoAwayEdge.Common; using System.Diagnostics; -using System.IO; using System.Security.Principal; -using System.Text; -using System.Web; using System.Windows; using GoAwayEdge.Common.Runtime; using GoAwayEdge.Common.Debugging; @@ -61,7 +58,7 @@ public void Application_Startup(object sender, StartupEventArgs e) return; } - var installer = new Installer(); + var installer = new UserInterface.Setup.Installer(); installer.ShowDialog(); Environment.Exit(0); } @@ -69,6 +66,12 @@ public void Application_Startup(object sender, StartupEventArgs e) { if (args.Contains("-ToastActivated")) // Clicked on notification, ignore it. Environment.Exit(0); + if (args.Contains("--control-center")) + { + var controlCenter = new UserInterface.ControlCenter.ControlCenter(); + controlCenter.ShowDialog(); + Environment.Exit(0); + } if (args.Contains("-s")) // Silent Installation { foreach (var arg in args) @@ -104,7 +107,6 @@ public void Application_Startup(object sender, StartupEventArgs e) InstallRoutine.Install(null); Environment.Exit(0); } - if (args.Contains("-u")) { InstallRoutine.Uninstall(null); diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index b5dfbb1..a2173f2 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -60,4 +60,9 @@ + + + Code + + \ No newline at end of file diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 850a85e..2191a62 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -7,25 +7,28 @@ Code - + Code - + Code - + Code - + Code - + Code - + Code - + + Code + + Code @@ -33,10 +36,16 @@ Designer - + + Designer + + + Designer + + Designer - + Designer @@ -60,19 +69,19 @@ Designer - + Designer - + Designer - + Designer - + Designer - + Designer diff --git a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml new file mode 100644 index 0000000..ed301a5 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs new file mode 100644 index 0000000..a1e0709 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs @@ -0,0 +1,66 @@ +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Security.Principal; +using System.Windows; +using System.Windows.Threading; +using Wpf.Ui.Controls; + +namespace GoAwayEdge.UserInterface.ControlCenter +{ + /// + /// Interaktionslogik für ControlCenter.xaml + /// + public partial class ControlCenter + { + private readonly DispatcherTimer _timer = new() + { + Interval = TimeSpan.FromSeconds(1) + }; + + [RequiresAssemblyFiles()] + public ControlCenter() + { + InitializeComponent(); + +#if DEBUG + DebugString.Visibility = Visibility.Visible; +#else + DebugString.Visibility = Visibility.Collapsed; +#endif + + // Get version + var assembly = Assembly.GetExecutingAssembly(); + var fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + var version = fvi.FileVersion; + Version.Text = $"Version {version}"; + + // Get User + var accountToken = WindowsIdentity.GetCurrent().Token; + var windowsIdentity = new WindowsIdentity(accountToken); + UserName.Text = windowsIdentity.Name; + + // Time & Date + _timer.Tick += UpdateTimeAndDate_Tick!; + _timer.Start(); + + // Configuration.InitialEnvironment(); + } + + private void ControlCenter_OnLoaded(object? sender, EventArgs eventArgs) + { + RootNavigation.Navigate(typeof(Pages.HomeScreen)); + } + + private void UpdateTimeAndDate_Tick(object sender, EventArgs e) + { + Time.Text = DateTime.Now.ToShortTimeString(); + Date.Text = DateTime.Now.ToShortDateString(); + } + + private void ThemeSwitch_Click(object sender, RoutedEventArgs e) + { + WindowBackdropType = WindowBackdropType == WindowBackdropType.Mica ? WindowBackdropType.Tabbed : WindowBackdropType.Mica; + } + } +} diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml b/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml new file mode 100644 index 0000000..77eba60 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs b/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs new file mode 100644 index 0000000..9d86c9b --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace GoAwayEdge.UserInterface.ControlCenter.Pages +{ + /// + /// Interaktionslogik für HomeScreen.xaml + /// + public partial class HomeScreen : Page + { + public HomeScreen() + { + InitializeComponent(); + } + } +} diff --git a/GoAwayEdge/MessageUI.xaml b/GoAwayEdge/UserInterface/MessageUI.xaml similarity index 97% rename from GoAwayEdge/MessageUI.xaml rename to GoAwayEdge/UserInterface/MessageUI.xaml index def6000..cfd34be 100644 --- a/GoAwayEdge/MessageUI.xaml +++ b/GoAwayEdge/UserInterface/MessageUI.xaml @@ -1,77 +1,77 @@ - - - - - - - - - - - - - - - - - - Message.Title - - - - Message.Text - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Message.Title + + + + Message.Text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/MessageUI.xaml.cs b/GoAwayEdge/UserInterface/MessageUI.xaml.cs similarity index 96% rename from GoAwayEdge/MessageUI.xaml.cs rename to GoAwayEdge/UserInterface/MessageUI.xaml.cs index 6311e37..7edfac7 100644 --- a/GoAwayEdge/MessageUI.xaml.cs +++ b/GoAwayEdge/UserInterface/MessageUI.xaml.cs @@ -1,71 +1,71 @@ -// Copyright (c) 2024 valnoxy -// Copied from Dive: https://github.com/valnoxy/Dive/blob/main/Dive/Dive.UI/MessageUI.xaml.cs - -using System.Reflection; -using System.Windows; -using System.Windows.Input; - -namespace GoAwayEdge -{ - /// - /// Interaktionslogik für MessageUI.xaml - /// - public partial class MessageUi - { - public virtual string? Summary => _buttonPressed; - - private static string? _buttonPressed; - private static bool _mainThread; - - public MessageUi(string title, string message, string? btn1 = null, string? btn2 = null, string? btn3 = null, bool isMainThread = false) - { - InitializeComponent(); - - MessageTitle.Text = title; - MessageText.Text = message; - this.Btn1.Content = btn1; - this.Btn2.Content = btn2; - this.Btn3.Content = btn3; - - if (btn1 is null or "") - this.Btn1.Visibility = Visibility.Collapsed; - if (btn2 is null or "") - this.Btn2.Visibility = Visibility.Collapsed; - if (btn3 is null or "") - this.Btn3.Visibility = Visibility.Collapsed; - - VersionLbl.Content = $"Version {Assembly.GetExecutingAssembly().GetName().Version!}"; - - _mainThread = isMainThread; - } - - private void Btn1_OnClick(object sender, RoutedEventArgs e) - { - _buttonPressed = "Btn1"; - if (_mainThread) this.Hide(); - else this.Close(); - } - - private void Btn2_OnClick(object sender, RoutedEventArgs e) - { - _buttonPressed = "Btn2"; - if (_mainThread) this.Hide(); - else this.Close(); - } - - private void Btn3_OnClick(object sender, RoutedEventArgs e) - { - _buttonPressed = "Btn3"; - if (_mainThread) this.Hide(); - else this.Close(); - } - - private void WindowKeyDown(object sender, KeyEventArgs e) - { - if (e.Key != Key.C || Keyboard.Modifiers != ModifierKeys.Control) return; - - var clipboardString = $"{MessageTitle.Text}\n-----\n{MessageText.Text}"; - Clipboard.SetDataObject(clipboardString); - } - } +// Copyright (c) 2024 valnoxy +// Copied from Dive: https://github.com/valnoxy/Dive/blob/main/Dive/Dive.UI/MessageUI.xaml.cs + +using System.Reflection; +using System.Windows; +using System.Windows.Input; + +namespace GoAwayEdge +{ + /// + /// Interaktionslogik für MessageUI.xaml + /// + public partial class MessageUi + { + public virtual string? Summary => _buttonPressed; + + private static string? _buttonPressed; + private static bool _mainThread; + + public MessageUi(string title, string message, string? btn1 = null, string? btn2 = null, string? btn3 = null, bool isMainThread = false) + { + InitializeComponent(); + + MessageTitle.Text = title; + MessageText.Text = message; + this.Btn1.Content = btn1; + this.Btn2.Content = btn2; + this.Btn3.Content = btn3; + + if (btn1 is null or "") + this.Btn1.Visibility = Visibility.Collapsed; + if (btn2 is null or "") + this.Btn2.Visibility = Visibility.Collapsed; + if (btn3 is null or "") + this.Btn3.Visibility = Visibility.Collapsed; + + VersionLbl.Content = $"Version {Assembly.GetExecutingAssembly().GetName().Version!}"; + + _mainThread = isMainThread; + } + + private void Btn1_OnClick(object sender, RoutedEventArgs e) + { + _buttonPressed = "Btn1"; + if (_mainThread) this.Hide(); + else this.Close(); + } + + private void Btn2_OnClick(object sender, RoutedEventArgs e) + { + _buttonPressed = "Btn2"; + if (_mainThread) this.Hide(); + else this.Close(); + } + + private void Btn3_OnClick(object sender, RoutedEventArgs e) + { + _buttonPressed = "Btn3"; + if (_mainThread) this.Hide(); + else this.Close(); + } + + private void WindowKeyDown(object sender, KeyEventArgs e) + { + if (e.Key != Key.C || Keyboard.Modifiers != ModifierKeys.Control) return; + + var clipboardString = $"{MessageTitle.Text}\n-----\n{MessageText.Text}"; + Clipboard.SetDataObject(clipboardString); + } + } } \ No newline at end of file diff --git a/GoAwayEdge/Installer.xaml b/GoAwayEdge/UserInterface/Setup/Installer.xaml similarity index 96% rename from GoAwayEdge/Installer.xaml rename to GoAwayEdge/UserInterface/Setup/Installer.xaml index 2693cc3..d822743 100644 --- a/GoAwayEdge/Installer.xaml +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml @@ -1,65 +1,65 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/Installer.xaml.cs b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs similarity index 92% rename from GoAwayEdge/Installer.xaml.cs rename to GoAwayEdge/UserInterface/Setup/Installer.xaml.cs index 28c6e05..900d81a 100644 --- a/GoAwayEdge/Installer.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs @@ -1,70 +1,69 @@ -using System.Diagnostics; -using System.Reflection; -using System.Windows; -using GoAwayEdge.Common; -using GoAwayEdge.Pages; - -namespace GoAwayEdge -{ - /// - /// Interaktionslogik für Installer.xaml - /// - public partial class Installer - { - internal static Installer? ContentWindow; - public static License? LicensePage; - private static Welcome? _welcomePage; - private static Settings? _settingPage; - - public Installer() - { - InitializeComponent(); - - VersionLbl.Content = $"Version {Assembly.GetExecutingAssembly().GetName().Version!}"; - Configuration.InitialEnvironment(); - - _welcomePage = new Welcome(); - LicensePage = new License(); - FrameWindow.Content = _welcomePage; - ContentWindow = this; - } - - internal void NextBtn_OnClick(object sender, RoutedEventArgs e) - { - switch (FrameWindow.Content) - { - case InstallationSuccess: - Environment.Exit(0); - break; - case Settings: - NextBtn.IsEnabled = false; - BackBtn.IsEnabled = false; - FrameWindow.Content = new Installation(); - break; - case License: - NextBtn.IsEnabled = true; - BackBtn.IsEnabled = true; - _settingPage = new Settings(); - FrameWindow.Content = _settingPage; - break; - } - } - - private void BackBtn_OnClick(object sender, RoutedEventArgs e) - { - switch (FrameWindow.Content) - { - case Settings: - NextBtn.IsEnabled = true; - BackBtn.IsEnabled = true; - FrameWindow.Content = LicensePage; - break; - case License: - NextBtn.IsEnabled = false; - BackBtn.IsEnabled = false; - FrameWindow.Content = _welcomePage; - break; - } - } - } -} +using System.Reflection; +using System.Windows; +using GoAwayEdge.Common; +using GoAwayEdge.UserInterface.Setup.Pages; + +namespace GoAwayEdge.UserInterface.Setup +{ + /// + /// Interaktionslogik für Installer.xaml + /// + public partial class Installer + { + internal static Installer? ContentWindow; + public static License? LicensePage; + private static Welcome? _welcomePage; + private static Settings? _settingPage; + + public Installer() + { + InitializeComponent(); + + VersionLbl.Content = $"Version {Assembly.GetExecutingAssembly().GetName().Version!}"; + Configuration.InitialEnvironment(); + + _welcomePage = new Welcome(); + LicensePage = new License(); + FrameWindow.Content = _welcomePage; + ContentWindow = this; + } + + internal void NextBtn_OnClick(object sender, RoutedEventArgs e) + { + switch (FrameWindow.Content) + { + case InstallationSuccess: + Environment.Exit(0); + break; + case Settings: + NextBtn.IsEnabled = false; + BackBtn.IsEnabled = false; + FrameWindow.Content = new Installation(); + break; + case License: + NextBtn.IsEnabled = true; + BackBtn.IsEnabled = true; + _settingPage = new Settings(); + FrameWindow.Content = _settingPage; + break; + } + } + + private void BackBtn_OnClick(object sender, RoutedEventArgs e) + { + switch (FrameWindow.Content) + { + case Settings: + NextBtn.IsEnabled = true; + BackBtn.IsEnabled = true; + FrameWindow.Content = LicensePage; + break; + case License: + NextBtn.IsEnabled = false; + BackBtn.IsEnabled = false; + FrameWindow.Content = _welcomePage; + break; + } + } + } +} diff --git a/GoAwayEdge/Pages/Installation.xaml b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml similarity index 89% rename from GoAwayEdge/Pages/Installation.xaml rename to GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml index 37c9fd3..71e3b59 100644 --- a/GoAwayEdge/Pages/Installation.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml @@ -1,23 +1,22 @@ - - - - - - - - + + + + + + + + diff --git a/GoAwayEdge/Pages/Installation.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs similarity index 88% rename from GoAwayEdge/Pages/Installation.xaml.cs rename to GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs index 7562b33..5d2ccc3 100644 --- a/GoAwayEdge/Pages/Installation.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs @@ -1,40 +1,39 @@ -using System.ComponentModel; -using System.Windows.Controls; -using GoAwayEdge.Common; - -namespace GoAwayEdge.Pages -{ - /// - /// Interaktionslogik für Installation.xaml - /// - public partial class Installation : UserControl - { - public Installation() - { - InitializeComponent(); - - // Background worker for deployment - var applyBackgroundWorker = new BackgroundWorker(); - applyBackgroundWorker.WorkerReportsProgress = true; - applyBackgroundWorker.WorkerSupportsCancellation = true; - if (Configuration.Uninstall) - { - applyBackgroundWorker.DoWork += InstallRoutine.Uninstall; - } - else - { - applyBackgroundWorker.DoWork += InstallRoutine.Install; - } - applyBackgroundWorker.ProgressChanged += ApplyBackgroundWorker_ProgressChanged; - applyBackgroundWorker.RunWorkerAsync(); - } - - private static void ApplyBackgroundWorker_ProgressChanged(object? sender, ProgressChangedEventArgs e) - { - if (e.ProgressPercentage == 100) - { - Installer.ContentWindow?.FrameWindow.NavigationService.Navigate(new InstallationSuccess()); - } - } - } -} +using System.ComponentModel; +using GoAwayEdge.Common; + +namespace GoAwayEdge.UserInterface.Setup.Pages +{ + /// + /// Interaktionslogik für Installation.xaml + /// + public partial class Installation + { + public Installation() + { + InitializeComponent(); + + // Background worker for deployment + var applyBackgroundWorker = new BackgroundWorker(); + applyBackgroundWorker.WorkerReportsProgress = true; + applyBackgroundWorker.WorkerSupportsCancellation = true; + if (Configuration.Uninstall) + { + applyBackgroundWorker.DoWork += InstallRoutine.Uninstall; + } + else + { + applyBackgroundWorker.DoWork += InstallRoutine.Install; + } + applyBackgroundWorker.ProgressChanged += ApplyBackgroundWorker_ProgressChanged; + applyBackgroundWorker.RunWorkerAsync(); + } + + private static void ApplyBackgroundWorker_ProgressChanged(object? sender, ProgressChangedEventArgs e) + { + if (e.ProgressPercentage == 100) + { + Installer.ContentWindow?.FrameWindow.NavigationService.Navigate(new InstallationSuccess()); + } + } + } +} diff --git a/GoAwayEdge/Pages/InstallationSuccess.xaml b/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml similarity index 89% rename from GoAwayEdge/Pages/InstallationSuccess.xaml rename to GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml index 2c6f8c5..7c1f0ed 100644 --- a/GoAwayEdge/Pages/InstallationSuccess.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml @@ -1,25 +1,24 @@ - - - - - - - - + + + + + + + + diff --git a/GoAwayEdge/Pages/InstallationSuccess.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs similarity index 93% rename from GoAwayEdge/Pages/InstallationSuccess.xaml.cs rename to GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs index f2e03bf..5514679 100644 --- a/GoAwayEdge/Pages/InstallationSuccess.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs @@ -1,37 +1,36 @@ -using System.Windows; -using System.Windows.Media.Imaging; -using GoAwayEdge.Common; -using Wpf.Ui.Controls; - -namespace GoAwayEdge.Pages -{ - /// - /// Interaktionslogik für Installation.xaml - /// - public partial class InstallationSuccess - { - public InstallationSuccess() - { - InitializeComponent(); - - var exitResource = (string)Application.Current.MainWindow!.FindResource("Exit"); - Installer.ContentWindow!.NextBtn.IsEnabled = true; - Installer.ContentWindow!.NextBtn.Icon = new SymbolIcon(SymbolRegular.ArrowExit20); - Installer.ContentWindow!.NextBtn.Content = !string.IsNullOrEmpty(exitResource) - ? exitResource : "Exit"; - - if (Configuration.Uninstall) - { - Dispatcher.Invoke(() => - { - var titleResource = (string)Application.Current.MainWindow!.FindResource("UninstallFinishedTitle"); - var descriptionResource = (string)Application.Current.MainWindow!.FindResource("UninstallFinishedDescription"); - SetupTitle.Text = !string.IsNullOrEmpty(titleResource) - ? titleResource : "Uninstallation completed!"; - SetupDescription.Text = !string.IsNullOrEmpty(descriptionResource) - ? descriptionResource : "GoAwayEdge has been successfully removed from the system."; - }); - } - } - } -} +using System.Windows; +using GoAwayEdge.Common; +using Wpf.Ui.Controls; + +namespace GoAwayEdge.UserInterface.Setup.Pages +{ + /// + /// Interaktionslogik für Installation.xaml + /// + public partial class InstallationSuccess + { + public InstallationSuccess() + { + InitializeComponent(); + + var exitResource = (string)Application.Current.MainWindow!.FindResource("Exit"); + Installer.ContentWindow!.NextBtn.IsEnabled = true; + Installer.ContentWindow!.NextBtn.Icon = new SymbolIcon(SymbolRegular.ArrowExit20); + Installer.ContentWindow!.NextBtn.Content = !string.IsNullOrEmpty(exitResource) + ? exitResource : "Exit"; + + if (Configuration.Uninstall) + { + Dispatcher.Invoke(() => + { + var titleResource = (string)Application.Current.MainWindow!.FindResource("UninstallFinishedTitle"); + var descriptionResource = (string)Application.Current.MainWindow!.FindResource("UninstallFinishedDescription"); + SetupTitle.Text = !string.IsNullOrEmpty(titleResource) + ? titleResource : "Uninstallation completed!"; + SetupDescription.Text = !string.IsNullOrEmpty(descriptionResource) + ? descriptionResource : "GoAwayEdge has been successfully removed from the system."; + }); + } + } + } +} diff --git a/GoAwayEdge/Pages/License.xaml b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml similarity index 89% rename from GoAwayEdge/Pages/License.xaml rename to GoAwayEdge/UserInterface/Setup/Pages/License.xaml index 194fe6b..a655c33 100644 --- a/GoAwayEdge/Pages/License.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml @@ -1,23 +1,22 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/Pages/License.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs similarity index 95% rename from GoAwayEdge/Pages/License.xaml.cs rename to GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs index d2978c4..287cb80 100644 --- a/GoAwayEdge/Pages/License.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs @@ -1,49 +1,49 @@ -using System.Windows; - -namespace GoAwayEdge.Pages -{ - /// - /// Interaktionslogik für License.xaml - /// - public partial class License - { - public License() - { - InitializeComponent(); - - const string license = @"MIT License - -Copyright (c) 2023-2024 valnoxy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the ""Software""), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - "; - - LicenseBlock.Text = license; - } - - private void AcceptLicenseRb_Click(object sender, RoutedEventArgs e) - { - Installer.ContentWindow!.NextBtn.IsEnabled = true; - } - private void DeclineLicenseRb_Click(object sender, RoutedEventArgs e) - { - Installer.ContentWindow!.NextBtn.IsEnabled = false; - } - } -} +using System.Windows; + +namespace GoAwayEdge.UserInterface.Setup.Pages +{ + /// + /// Interaktionslogik für License.xaml + /// + public partial class License + { + public License() + { + InitializeComponent(); + + const string license = @"MIT License + +Copyright (c) 2023-2024 valnoxy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the ""Software""), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + "; + + LicenseBlock.Text = license; + } + + private void AcceptLicenseRb_Click(object sender, RoutedEventArgs e) + { + Installer.ContentWindow!.NextBtn.IsEnabled = true; + } + private void DeclineLicenseRb_Click(object sender, RoutedEventArgs e) + { + Installer.ContentWindow!.NextBtn.IsEnabled = false; + } + } +} diff --git a/GoAwayEdge/Pages/Settings.xaml b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml similarity index 96% rename from GoAwayEdge/Pages/Settings.xaml rename to GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml index 19ce9db..7759f75 100644 --- a/GoAwayEdge/Pages/Settings.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml @@ -1,110 +1,109 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs similarity index 97% rename from GoAwayEdge/Pages/Settings.xaml.cs rename to GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index 104a26a..7196493 100644 --- a/GoAwayEdge/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -1,139 +1,139 @@ -using System.Windows; -using System.Windows.Controls; -using GoAwayEdge.Common; - -namespace GoAwayEdge.Pages -{ - /// - /// Interaktionslogik für Settings.xaml - /// - public partial class Settings - { - public Settings() - { - InitializeComponent(); - - EdgeChannelBox.Items.Add("Edge Stable"); - EdgeChannelBox.Items.Add("Edge Beta"); - EdgeChannelBox.Items.Add("Edge Dev"); - EdgeChannelBox.Items.Add("Edge Canary"); - EdgeChannelBox.SelectedIndex = 0; - Configuration.Channel = EdgeChannel.Stable; - - SearchEngineBox.Items.Add("Google"); - SearchEngineBox.Items.Add("Bing"); - SearchEngineBox.Items.Add("DuckDuckGo"); - SearchEngineBox.Items.Add("Yahoo"); - SearchEngineBox.Items.Add("Yandex"); - SearchEngineBox.Items.Add("Ecosia"); - SearchEngineBox.Items.Add("Ask"); - SearchEngineBox.Items.Add("Qwant"); - SearchEngineBox.Items.Add("Perplexity"); - - try - { - Dispatcher.Invoke(() => - { - var resourceValue = (string)Application.Current.MainWindow!.FindResource("SettingsSearchEngineCustomItem"); - SearchEngineBox.Items.Add(!string.IsNullOrEmpty(resourceValue) ? resourceValue : "Custom"); - }); - } - catch - { - SearchEngineBox.Items.Add("Custom"); - } - - if (Configuration.NoEdgeInstalled) - { - MsEdgeRemoveStackPanel.IsEnabled = false; - EdgeStackPanel.IsEnabled = false; - } - - SearchEngineBox.SelectedIndex = 0; - Configuration.Search = SearchEngine.Google; - Configuration.Uninstall = false; - } - - private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) - { - Configuration.Channel = EdgeChannelBox.SelectedIndex switch - { - 0 => EdgeChannel.Stable, - 1 => EdgeChannel.Beta, - 2 => EdgeChannel.Dev, - 3 => EdgeChannel.Canary, - _ => EdgeChannel.Stable - }; - } - - private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) - { - switch (SearchEngineBox.SelectedIndex) - { - case 0: - Configuration.Search = SearchEngine.Google; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 1: - Configuration.Search = SearchEngine.Bing; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 2: - Configuration.Search = SearchEngine.DuckDuckGo; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 3: - Configuration.Search = SearchEngine.Yahoo; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 4: - Configuration.Search = SearchEngine.Yandex; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 5: - Configuration.Search = SearchEngine.Ecosia; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 6: - Configuration.Search = SearchEngine.Ask; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 7: - Configuration.Search = SearchEngine.Qwant; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 8: - Configuration.Search = SearchEngine.Perplexity; - CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; - break; - case 9: - Configuration.Search = SearchEngine.Custom; - CustomSearchPanel.Visibility = Visibility.Visible; - if (string.IsNullOrEmpty(Configuration.CustomQueryUrl)) - Installer.ContentWindow!.NextBtn.IsEnabled = false; - break; - } - } - - private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e) - { - Configuration.CustomQueryUrl = QueryUrlTextBox.Text; - Installer.ContentWindow!.NextBtn.IsEnabled = Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out var uriResult) - && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); - } - - private void MsEdgeUninstallSwitch_OnClickUninstallSwitch_OnClick(object sender, RoutedEventArgs e) - { - Configuration.UninstallEdge = MsEdgeUninstallSwitch.IsChecked!.Value; - } - } -} +using System.Windows; +using System.Windows.Controls; +using GoAwayEdge.Common; + +namespace GoAwayEdge.UserInterface.Setup.Pages +{ + /// + /// Interaktionslogik für Settings.xaml + /// + public partial class Settings + { + public Settings() + { + InitializeComponent(); + + EdgeChannelBox.Items.Add("Edge Stable"); + EdgeChannelBox.Items.Add("Edge Beta"); + EdgeChannelBox.Items.Add("Edge Dev"); + EdgeChannelBox.Items.Add("Edge Canary"); + EdgeChannelBox.SelectedIndex = 0; + Configuration.Channel = EdgeChannel.Stable; + + SearchEngineBox.Items.Add("Google"); + SearchEngineBox.Items.Add("Bing"); + SearchEngineBox.Items.Add("DuckDuckGo"); + SearchEngineBox.Items.Add("Yahoo"); + SearchEngineBox.Items.Add("Yandex"); + SearchEngineBox.Items.Add("Ecosia"); + SearchEngineBox.Items.Add("Ask"); + SearchEngineBox.Items.Add("Qwant"); + SearchEngineBox.Items.Add("Perplexity"); + + try + { + Dispatcher.Invoke(() => + { + var resourceValue = (string)Application.Current.MainWindow!.FindResource("SettingsSearchEngineCustomItem"); + SearchEngineBox.Items.Add(!string.IsNullOrEmpty(resourceValue) ? resourceValue : "Custom"); + }); + } + catch + { + SearchEngineBox.Items.Add("Custom"); + } + + if (Configuration.NoEdgeInstalled) + { + MsEdgeRemoveStackPanel.IsEnabled = false; + EdgeStackPanel.IsEnabled = false; + } + + SearchEngineBox.SelectedIndex = 0; + Configuration.Search = SearchEngine.Google; + Configuration.Uninstall = false; + } + + private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + Configuration.Channel = EdgeChannelBox.SelectedIndex switch + { + 0 => EdgeChannel.Stable, + 1 => EdgeChannel.Beta, + 2 => EdgeChannel.Dev, + 3 => EdgeChannel.Canary, + _ => EdgeChannel.Stable + }; + } + + private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + switch (SearchEngineBox.SelectedIndex) + { + case 0: + Configuration.Search = SearchEngine.Google; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 1: + Configuration.Search = SearchEngine.Bing; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 2: + Configuration.Search = SearchEngine.DuckDuckGo; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 3: + Configuration.Search = SearchEngine.Yahoo; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 4: + Configuration.Search = SearchEngine.Yandex; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 5: + Configuration.Search = SearchEngine.Ecosia; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 6: + Configuration.Search = SearchEngine.Ask; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 7: + Configuration.Search = SearchEngine.Qwant; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 8: + Configuration.Search = SearchEngine.Perplexity; + CustomSearchPanel.Visibility = Visibility.Collapsed; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + break; + case 9: + Configuration.Search = SearchEngine.Custom; + CustomSearchPanel.Visibility = Visibility.Visible; + if (string.IsNullOrEmpty(Configuration.CustomQueryUrl)) + Installer.ContentWindow!.NextBtn.IsEnabled = false; + break; + } + } + + private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + Configuration.CustomQueryUrl = QueryUrlTextBox.Text; + Installer.ContentWindow!.NextBtn.IsEnabled = Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); + } + + private void MsEdgeUninstallSwitch_OnClickUninstallSwitch_OnClick(object sender, RoutedEventArgs e) + { + Configuration.UninstallEdge = MsEdgeUninstallSwitch.IsChecked!.Value; + } + } +} diff --git a/GoAwayEdge/Pages/Welcome.xaml b/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml similarity index 94% rename from GoAwayEdge/Pages/Welcome.xaml rename to GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml index a7e8494..b09c5e5 100644 --- a/GoAwayEdge/Pages/Welcome.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml @@ -1,55 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/Pages/Welcome.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs similarity index 89% rename from GoAwayEdge/Pages/Welcome.xaml.cs rename to GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs index 05925ad..9107ea4 100644 --- a/GoAwayEdge/Pages/Welcome.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs @@ -1,40 +1,39 @@ -using System.IO; -using System.Windows; -using System.Windows.Controls; -using GoAwayEdge.Common; - -namespace GoAwayEdge.Pages -{ - /// - /// Interaktionslogik für Welcome.xaml - /// - public partial class Welcome : UserControl - { - public Welcome() - { - InitializeComponent(); - - if (!Path.Exists(Configuration.InstallDir)) - UninstallBtn.IsEnabled = false; - if (Path.GetDirectoryName(Environment.ProcessPath) != Configuration.InstallDir) return; - UninstallBtn.IsEnabled = false; - Dispatcher.Invoke(() => - { - var resourceValue = (string)Application.Current.MainWindow!.FindResource("SettingsUninstallUseInstaller"); - EdgeUninstallNote.Text = !string.IsNullOrEmpty(resourceValue) ? resourceValue : "Please use the Installer in order to uninstall GoAwayEdge."; - }); - } - - private void InstallBtn_Click(object sender, RoutedEventArgs e) - { - Installer.ContentWindow!.FrameWindow.Content = Installer.LicensePage; - Installer.ContentWindow!.BackBtn.IsEnabled = true; - } - - private void UninstallBtn_Click(object sender, RoutedEventArgs e) - { - Configuration.Uninstall = true; - Installer.ContentWindow!.FrameWindow.Content = new Installation(); - } - } -} +using System.IO; +using System.Windows; +using GoAwayEdge.Common; + +namespace GoAwayEdge.UserInterface.Setup.Pages +{ + /// + /// Interaktionslogik für Welcome.xaml + /// + public partial class Welcome + { + public Welcome() + { + InitializeComponent(); + + if (!Path.Exists(Configuration.InstallDir)) + UninstallBtn.IsEnabled = false; + if (Path.GetDirectoryName(Environment.ProcessPath) != Configuration.InstallDir) return; + UninstallBtn.IsEnabled = false; + Dispatcher.Invoke(() => + { + var resourceValue = (string)Application.Current.MainWindow!.FindResource("SettingsUninstallUseInstaller"); + EdgeUninstallNote.Text = !string.IsNullOrEmpty(resourceValue) ? resourceValue : "Please use the Installer in order to uninstall GoAwayEdge."; + }); + } + + private void InstallBtn_Click(object sender, RoutedEventArgs e) + { + Installer.ContentWindow!.FrameWindow.Content = Installer.LicensePage; + Installer.ContentWindow!.BackBtn.IsEnabled = true; + } + + private void UninstallBtn_Click(object sender, RoutedEventArgs e) + { + Configuration.Uninstall = true; + Installer.ContentWindow!.FrameWindow.Content = new Installation(); + } + } +} From 9ffd96f037f7615baf14043647232c88a9f27415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 29 Jul 2024 21:08:40 +0200 Subject: [PATCH 04/80] Fix Title bar icon --- GoAwayEdge/UserInterface/Setup/Installer.xaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GoAwayEdge/UserInterface/Setup/Installer.xaml b/GoAwayEdge/UserInterface/Setup/Installer.xaml index d822743..54d21d7 100644 --- a/GoAwayEdge/UserInterface/Setup/Installer.xaml +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml @@ -60,6 +60,10 @@ - + + + + + \ No newline at end of file From 416d9d5e1cf5b5791f05613a0222bee8bdf54bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 29 Jul 2024 22:44:06 +0200 Subject: [PATCH 05/80] Updated Tabs --- GoAwayEdge/App.xaml | 2 + GoAwayEdge/Assets/Copilot.xaml | 81 ++++++++++++++ GoAwayEdge/Assets/Edge.xaml | 78 +++++++++++++ GoAwayEdge/GoAwayEdge.csproj | 2 +- GoAwayEdge/GoAwayEdge.csproj.user | 12 ++ .../ControlCenter/ControlCenter.xaml | 8 +- .../ControlCenter/ControlCenter.xaml.cs | 4 +- .../ControlCenter/Pages/About.xaml | 105 ++++++++++++++++++ .../ControlCenter/Pages/About.xaml.cs | 74 ++++++++++++ 9 files changed, 359 insertions(+), 7 deletions(-) create mode 100644 GoAwayEdge/Assets/Copilot.xaml create mode 100644 GoAwayEdge/Assets/Edge.xaml create mode 100644 GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml create mode 100644 GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml.cs diff --git a/GoAwayEdge/App.xaml b/GoAwayEdge/App.xaml index b3f84da..b5ebbfb 100644 --- a/GoAwayEdge/App.xaml +++ b/GoAwayEdge/App.xaml @@ -11,6 +11,8 @@ + + diff --git a/GoAwayEdge/Assets/Copilot.xaml b/GoAwayEdge/Assets/Copilot.xaml new file mode 100644 index 0000000..118dade --- /dev/null +++ b/GoAwayEdge/Assets/Copilot.xaml @@ -0,0 +1,81 @@ + + F1 M48,48z M0,0z M21.676,19.303C21.676,19.303,22.49,16.048,26.367,15.904L38.144,15.904C38.144,15.904 34.745,15.617 34.075,11.5 33.405,7.383 31.634,5.755 29.144,5.707 26.655,5.659 25.506,8.292 25.218,9.202 24.931,10.112 21.676,19.303 21.676,19.303z + F1 M48,48z M0,0z M19.234,29.261L25.266,9.011C25.266,9.011,26.415,5.612,29.144,5.708L14.016,5.708C14.016,5.708 11.431,5.708 9.564,8.676 9.564,8.676 6.692,12.41 5.016,20.07 3.34,27.73 4.011,28.16 4.011,28.16 4.011,28.16 3.58,32.373 10.043,32.038L15.022,32.038C15.021,32.037,18.037,32.085,19.234,29.261z + F1 M48,48z M0,0z M28.887,6.707L31.358,6.303C30.762,5.945,30.048,5.759,29.308,5.719L29.109,5.708C29.105,5.708 29.102,5.708 29.098,5.707 29.082,5.707 29.067,5.709 29.05,5.709 28.875,5.708 28.71,5.724 28.548,5.748 28.479,5.758 28.412,5.771 28.346,5.785 28.241,5.808 28.14,5.837 28.041,5.869 27.589,6.018 27.193,6.255 26.855,6.546 26.738,6.648 26.63,6.755 26.526,6.866 25.765,7.677 25.344,8.699 25.186,9.2 25.147,9.325 25.047,9.616 24.912,10.008L22.694,17.452C22.78,17.36 22.892,17.273 22.991,17.183 23.047,17.132 23.099,17.08 23.159,17.031 23.247,16.959 23.339,16.892 23.436,16.823 23.602,16.705 23.777,16.592 23.973,16.49 23.998,16.477 24.016,16.46 24.042,16.447L26.173,9.293C26.174,9.296,27.066,6.787,28.887,6.707z + F1 M48,48z M0,0z M28.864,6.207L30.34,5.867C30.34,5.867 29.654,5.691 29.088,5.712 28.668,5.727 28.286,5.784 27.941,5.915 27.914,5.926 27.885,5.934 27.858,5.946 27.777,5.979 27.699,6.019 27.622,6.058 27.565,6.088 27.507,6.117 27.452,6.149 27.404,6.177 27.358,6.207 27.311,6.237 27.226,6.293 27.142,6.351 27.062,6.413 27.045,6.426 27.029,6.439 27.013,6.452 26.584,6.798 26.24,7.219 25.974,7.62 25.968,7.629 25.962,7.637 25.957,7.646 25.928,7.69 25.904,7.732 25.877,7.776 25.535,8.338 25.321,8.88 25.219,9.204 25.201,9.262 25.169,9.356 25.128,9.478L22.751,17.456C22.931,17.262,23.139,17.071,23.377,16.893L25.682,9.155C25.685,9.143,26.684,6.292,28.864,6.207z + F1 M48,48z M0,0z M26.474,28.607C26.474,28.607,25.66,31.862,21.783,32.006L10.006,32.006C10.006,32.006 13.405,32.293 14.075,36.41 14.745,40.527 16.516,42.155 19.006,42.203 21.496,42.251 22.644,39.618 22.932,38.708 23.219,37.799 26.474,28.607 26.474,28.607z + F1 M48,48z M0,0z M19.255,41.171L16.784,41.575C17.38,41.933,18.094,42.119,18.834,42.159L19.033,42.17C19.037,42.17 19.04,42.17 19.044,42.171 19.06,42.171 19.075,42.169 19.092,42.169 19.267,42.17 19.432,42.154 19.594,42.13 19.663,42.12 19.73,42.107 19.796,42.093 19.901,42.07 20.002,42.041 20.101,42.009 20.553,41.86 20.949,41.623 21.287,41.332 21.404,41.23 21.512,41.123 21.616,41.012 22.377,40.201 22.798,39.179 22.956,38.678 22.995,38.553 23.095,38.262 23.23,37.87L25.448,30.426C25.362,30.518 25.25,30.605 25.151,30.695 25.095,30.746 25.043,30.798 24.983,30.847 24.895,30.919 24.803,30.986 24.706,31.055 24.54,31.173 24.365,31.286 24.169,31.388 24.144,31.401 24.126,31.418 24.1,31.431L21.969,38.585C21.969,38.582,21.077,41.091,19.255,41.171z + F1 M48,48z M0,0z M19.278,41.671L17.802,42.011C17.802,42.011 18.488,42.187 19.054,42.166 19.474,42.151 19.856,42.094 20.201,41.963 20.228,41.952 20.257,41.944 20.284,41.932 20.365,41.899 20.443,41.859 20.52,41.82 20.577,41.79 20.635,41.761 20.69,41.729 20.738,41.701 20.784,41.671 20.831,41.641 20.916,41.585 21,41.527 21.08,41.465 21.097,41.452 21.113,41.439 21.129,41.426 21.558,41.08 21.902,40.659 22.168,40.258 22.174,40.249 22.18,40.241 22.185,40.232 22.214,40.188 22.238,40.146 22.265,40.102 22.607,39.54 22.821,38.998 22.923,38.674 22.941,38.616 22.973,38.522 23.014,38.4L25.391,30.422C25.211,30.616,25.003,30.807,24.765,30.985L22.46,38.723C22.457,38.736,21.458,41.586,19.278,41.671z + F1 M48,48z M0,0z M28.915,18.65L22.845,38.913C22.845,38.913,21.734,42.299,19.006,42.203L34.134,42.203C34.134,42.203 36.719,42.203 38.586,39.235 38.586,39.235 41.458,35.501 43.134,27.841 44.81,20.181 44.139,19.751 44.139,19.751 44.139,19.751 44.57,15.538 38.107,15.873L33.128,15.873C33.128,15.873,30.112,15.826,28.915,18.65z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/Assets/Edge.xaml b/GoAwayEdge/Assets/Edge.xaml new file mode 100644 index 0000000..69b56f2 --- /dev/null +++ b/GoAwayEdge/Assets/Edge.xaml @@ -0,0 +1,78 @@ + + F1 M256,256z M0,0z M235.7,195.5A93.7,93.7,0,0,1,225.1,200.2A101.9,101.9,0,0,1,189.2,206.6C141.9,206.6,100.7,174.1,100.7,132.3A31.5,31.5,0,0,1,117.1,105C74.3,106.8 63.3,151.4 63.3,177.5 63.3,251.5 131.4,258.9 146.1,258.9 154,258.9 165.9,256.6 173.1,254.3L174.4,253.9A128.3,128.3,0,0,0,241,201.1A4,4,0,0,0,235.7,195.5z + F1 M256,256z M0,0z M235.7,195.5A93.7,93.7,0,0,1,225.1,200.2A101.9,101.9,0,0,1,189.2,206.6C141.9,206.6,100.7,174.1,100.7,132.3A31.5,31.5,0,0,1,117.1,105C74.3,106.8 63.3,151.4 63.3,177.5 63.3,251.5 131.4,258.9 146.1,258.9 154,258.9 165.9,256.6 173.1,254.3L174.4,253.9A128.3,128.3,0,0,0,241,201.1A4,4,0,0,0,235.7,195.5z + F1 M256,256z M0,0z M110.3,246.3A79.2,79.2,0,0,1,87.6,225A80.7,80.7,0,0,1,117.1,105C120.3,103.5,125.6,100.9,132.7,101A32.4,32.4,0,0,1,158.4,114A31.9,31.9,0,0,1,164.7,132.7C164.7,132.5 189.2,53.1 84.7,53.1 40.8,53.1 4.69999999999999,94.7 4.69999999999999,131.3A130.2,130.2,0,0,0,16.8,187.3A128,128,0,0,0,173.2,254.3A75.5,75.5,0,0,1,110.4,246.3z + F1 M256,256z M0,0z M110.3,246.3A79.2,79.2,0,0,1,87.6,225A80.7,80.7,0,0,1,117.1,105C120.3,103.5,125.6,100.9,132.7,101A32.4,32.4,0,0,1,158.4,114A31.9,31.9,0,0,1,164.7,132.7C164.7,132.5 189.2,53.1 84.7,53.1 40.8,53.1 4.69999999999999,94.7 4.69999999999999,131.3A130.2,130.2,0,0,0,16.8,187.3A128,128,0,0,0,173.2,254.3A75.5,75.5,0,0,1,110.4,246.3z + F1 M256,256z M0,0z M157,153.8C156.1,154.8 153.6,156.3 153.6,159.4 153.6,162 155.3,164.6 158.4,166.7 172.7,176.7 199.8,175.3 199.9,175.3A59.6,59.6,0,0,0,230.2,167A61.4,61.4,0,0,0,260.6,114.1C260.9,91.7 252.6,76.8 249.3,70.2 228,28.8 182.3,5 132.6,5A128,128,0,0,0,4.59999999999999,131.2C5.09999999999999,94.7 41.4,65.2 84.6,65.2 88.1,65.2 108.1,65.5 126.6,75.2A72.6,72.6,0,0,1,157.5,104.5C163.6,115.1 164.7,128.6 164.7,134 164.7,139.4 162,147.3 156.9,153.9z + F1 M256,256z M0,0z M157,153.8C156.1,154.8 153.6,156.3 153.6,159.4 153.6,162 155.3,164.6 158.4,166.7 172.7,176.7 199.8,175.3 199.9,175.3A59.6,59.6,0,0,0,230.2,167A61.4,61.4,0,0,0,260.6,114.1C260.9,91.7 252.6,76.8 249.3,70.2 228,28.8 182.3,5 132.6,5A128,128,0,0,0,4.59999999999999,131.2C5.09999999999999,94.7 41.4,65.2 84.6,65.2 88.1,65.2 108.1,65.5 126.6,75.2A72.6,72.6,0,0,1,157.5,104.5C163.6,115.1 164.7,128.6 164.7,134 164.7,139.4 162,147.3 156.9,153.9z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index a2173f2..c7c98f5 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -13,7 +13,7 @@ Exploitox valnoxy 2.0.0.160 - Copyright (c) 2018 - 2024 Exploitox. All rights reserved. + Copyright © 2018 - 2024 Exploitox. All rights reserved. https://github.com/valnoxy/GoAwayEdge https://github.com/valnoxy/GoAwayEdge GoAwayEdge.App diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 2191a62..090ee6f 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -7,6 +7,9 @@ Code + + Code + Code @@ -36,6 +39,15 @@ Designer + + Designer + + + Designer + + + Designer + Designer diff --git a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml index ed301a5..0634084 100644 --- a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml +++ b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml @@ -34,14 +34,14 @@ - + - + - + @@ -53,7 +53,7 @@ - + diff --git a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs index a1e0709..65e01be 100644 --- a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Security.Principal; @@ -18,7 +18,7 @@ public partial class ControlCenter Interval = TimeSpan.FromSeconds(1) }; - [RequiresAssemblyFiles()] + [RequiresAssemblyFiles] public ControlCenter() { InitializeComponent(); diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml b/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml new file mode 100644 index 0000000..101977c --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml.cs b/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml.cs new file mode 100644 index 0000000..b1ba83f --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml.cs @@ -0,0 +1,74 @@ +using System.Diagnostics; +using System.Reflection; +using System.Windows; + +namespace GoAwayEdge.UserInterface.ControlCenter.Pages +{ + /// + /// Interaktionslogik für About.xaml + /// + public partial class About + { + public About() + { + InitializeComponent(); + + var version = Assembly.GetExecutingAssembly().GetName().Version!; + var product = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductName; + var copyright = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).LegalCopyright; + ValueVersion.Content = $"{product} v{version}"; + ValueCopyright.Content = copyright; + } + + private void Homepage_OnClick(object sender, RoutedEventArgs e) + { + try + { + Process.Start(new ProcessStartInfo { FileName = "https://valnoxy.dev", UseShellExecute = true }); + } + catch (System.ComponentModel.Win32Exception noBrowser) + { + if (noBrowser.ErrorCode == -2147467259) + MessageBox.Show(noBrowser.Message); + } + catch (Exception other) + { + MessageBox.Show(other.Message); + } + } + + private void Donate_OnClick(object sender, RoutedEventArgs e) + { + try + { + Process.Start(new ProcessStartInfo { FileName = "https://paypal.me/valnoxy", UseShellExecute = true }); + } + catch (System.ComponentModel.Win32Exception noBrowser) + { + if (noBrowser.ErrorCode == -2147467259) + MessageBox.Show(noBrowser.Message); + } + catch (Exception other) + { + MessageBox.Show(other.Message); + } + } + + private void SourceCode_OnClick(object sender, RoutedEventArgs e) + { + try + { + Process.Start(new ProcessStartInfo { FileName = "https://github.com/valnoxy/GoAwayEdge", UseShellExecute = true }); + } + catch (System.ComponentModel.Win32Exception noBrowser) + { + if (noBrowser.ErrorCode == -2147467259) + MessageBox.Show(noBrowser.Message); + } + catch (Exception other) + { + MessageBox.Show(other.Message); + } + } + } +} From ca9671e3582c1d7efdf02863e2cef9a3543c1a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 30 Jul 2024 00:25:47 +0200 Subject: [PATCH 06/80] Updated install logic for adding control panel --- GoAwayEdge/App.xaml | 1 + GoAwayEdge/App.xaml.cs | 4 +- GoAwayEdge/Assets/Settings.xaml | 232 ++++++++++++++++++ GoAwayEdge/Common/Configuration.cs | 1 + .../Common/Installation/InstallRoutine.cs | 8 + GoAwayEdge/Common/Installation/Shortcut.cs | 54 ++++ GoAwayEdge/GoAwayEdge.csproj | 4 +- GoAwayEdge/GoAwayEdge.csproj.user | 13 +- .../ResourceDictionary.de-DE.xaml | 2 + .../Localization/ResourceDictionary.xaml | 2 + .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../ControlCenter/Pages/HomeScreen.xaml | 15 -- .../ControlCenter/Pages/HomeScreen.xaml.cs | 28 --- .../ControlPanel.xaml} | 8 +- .../ControlPanel.xaml.cs} | 14 +- .../Pages/About.xaml | 4 +- .../Pages/About.xaml.cs | 14 +- .../ControlPanel/Pages/HomeScreen.xaml | 50 ++++ .../ControlPanel/Pages/HomeScreen.xaml.cs | 15 ++ .../UserInterface/Setup/Pages/Settings.xaml | 24 ++ .../Setup/Pages/Settings.xaml.cs | 7 + 21 files changed, 431 insertions(+), 71 deletions(-) create mode 100644 GoAwayEdge/Assets/Settings.xaml create mode 100644 GoAwayEdge/Common/Installation/Shortcut.cs delete mode 100644 GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml delete mode 100644 GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs rename GoAwayEdge/UserInterface/{ControlCenter/ControlCenter.xaml => ControlPanel/ControlPanel.xaml} (96%) rename GoAwayEdge/UserInterface/{ControlCenter/ControlCenter.xaml.cs => ControlPanel/ControlPanel.xaml.cs} (81%) rename GoAwayEdge/UserInterface/{ControlCenter => ControlPanel}/Pages/About.xaml (99%) rename GoAwayEdge/UserInterface/{ControlCenter => ControlPanel}/Pages/About.xaml.cs (80%) create mode 100644 GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml create mode 100644 GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs diff --git a/GoAwayEdge/App.xaml b/GoAwayEdge/App.xaml index b5ebbfb..633d9f4 100644 --- a/GoAwayEdge/App.xaml +++ b/GoAwayEdge/App.xaml @@ -13,6 +13,7 @@ + diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index b50dfba..831d61b 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -66,9 +66,9 @@ public void Application_Startup(object sender, StartupEventArgs e) { if (args.Contains("-ToastActivated")) // Clicked on notification, ignore it. Environment.Exit(0); - if (args.Contains("--control-center")) + if (args.Contains("--control-panel")) { - var controlCenter = new UserInterface.ControlCenter.ControlCenter(); + var controlCenter = new UserInterface.ControlPanel.ControlPanel(); controlCenter.ShowDialog(); Environment.Exit(0); } diff --git a/GoAwayEdge/Assets/Settings.xaml b/GoAwayEdge/Assets/Settings.xaml new file mode 100644 index 0000000..05842cb --- /dev/null +++ b/GoAwayEdge/Assets/Settings.xaml @@ -0,0 +1,232 @@ + + F1 M113,63z M0,0z M25.5356,39.6396C25.4618,40.1031 25.0981,40.4781 24.6525,40.7562 23.3702,41.3403 22.3648,41.8805 21.5388,42.3908 20.8075,42.8426 20.9283,44.0402 21.7332,44.3416 22.6738,44.6937 23.8423,45.0062 25.1432,45.3846 25.4929,45.4864 26.0051,45.8189 26.1675,46.2718 26.6682,47.6674 27.3086,49.1343 27.9883,50.4802 28.5159,51.525 29.5666,51.4248 29.8912,50.3003 30.3125,48.8405 30.59,47.2804 30.9286,45.7891 31.0001,45.3317 31.3036,44.9467 31.7234,44.7518 32.858,44.2249 33.9453,43.6485 34.8293,43.155 35.6549,42.6942 35.5561,41.4607 34.6674,41.1381 33.7183,40.7937 32.5412,40.4022 31.2752,40.0732 30.8297,39.9575 30.467,39.6584 30.2695,39.204 29.6042,37.6727 29.1507,36.364 28.471,35.0247 27.9414,33.9809 26.8233,34.1203 26.4987,35.2449 26.0837,36.6826 25.833,38.0982 25.5356,39.6396z + F1 M113,63z M0,0z M25.5356,39.6396C25.4618,40.1031 25.0981,40.4781 24.6525,40.7562 23.3702,41.3403 22.3648,41.8805 21.5388,42.3908 20.8075,42.8426 20.9283,44.0402 21.7332,44.3416 22.6738,44.6937 23.8423,45.0062 25.1432,45.3846 25.4929,45.4864 26.0051,45.8189 26.1675,46.2718 26.6682,47.6674 27.3086,49.1343 27.9883,50.4802 28.5159,51.525 29.5666,51.4248 29.8912,50.3003 30.3125,48.8405 30.59,47.2804 30.9286,45.7891 31.0001,45.3317 31.3036,44.9467 31.7234,44.7518 32.858,44.2249 33.9453,43.6485 34.8293,43.155 35.6549,42.6942 35.5561,41.4607 34.6674,41.1381 33.7183,40.7937 32.5412,40.4022 31.2752,40.0732 30.8297,39.9575 30.467,39.6584 30.2695,39.204 29.6042,37.6727 29.1507,36.364 28.471,35.0247 27.9414,33.9809 26.8233,34.1203 26.4987,35.2449 26.0837,36.6826 25.833,38.0982 25.5356,39.6396z + F1 M113,63z M0,0z M19.6873,36.5436C19.6636,36.6928 19.5465,36.8135 19.4031,36.903 18.9904,37.091 18.6668,37.2649 18.4009,37.4291 18.1656,37.5745 18.2044,37.96 18.4635,38.057 18.7662,38.1703 19.1423,38.2709 19.561,38.3927 19.6736,38.4254 19.8384,38.5325 19.8907,38.6782 20.0519,39.1274 20.258,39.5996 20.4768,40.0328 20.6466,40.369 20.9848,40.3368 21.0892,39.9749 21.2248,39.505 21.3141,39.0029 21.4231,38.5229 21.4462,38.3757 21.5438,38.2518 21.6789,38.189 22.0441,38.0194 22.394,37.8339 22.6786,37.6751 22.9443,37.5267 22.9125,37.1297 22.6265,37.0259 22.321,36.9151 21.9422,36.7891 21.5347,36.6832 21.3912,36.6459 21.2745,36.5497 21.211,36.4034 20.9969,35.9106 20.8509,35.4894 20.6321,35.0583 20.4616,34.7223 20.1018,34.7672 19.9973,35.1292 19.8638,35.5919 19.7831,36.0475 19.6873,36.5436z + F1 M113,63z M0,0z M19.6873,36.5436C19.6636,36.6928 19.5465,36.8135 19.4031,36.903 18.9904,37.091 18.6668,37.2649 18.4009,37.4291 18.1656,37.5745 18.2044,37.96 18.4635,38.057 18.7662,38.1703 19.1423,38.2709 19.561,38.3927 19.6736,38.4254 19.8384,38.5325 19.8907,38.6782 20.0519,39.1274 20.258,39.5996 20.4768,40.0328 20.6466,40.369 20.9848,40.3368 21.0892,39.9749 21.2248,39.505 21.3141,39.0029 21.4231,38.5229 21.4462,38.3757 21.5438,38.2518 21.6789,38.189 22.0441,38.0194 22.394,37.8339 22.6786,37.6751 22.9443,37.5267 22.9125,37.1297 22.6265,37.0259 22.321,36.9151 21.9422,36.7891 21.5347,36.6832 21.3912,36.6459 21.2745,36.5497 21.211,36.4034 20.9969,35.9106 20.8509,35.4894 20.6321,35.0583 20.4616,34.7223 20.1018,34.7672 19.9973,35.1292 19.8638,35.5919 19.7831,36.0475 19.6873,36.5436z + F1 M113,63z M0,0z M18.8707,46.4507C18.8376,46.6588 18.6743,46.8271 18.4744,46.9519 17.8988,47.214 17.4476,47.4565 17.0768,47.6855 16.7487,47.8882 16.8028,48.4257 17.1641,48.561 17.5862,48.7191 18.1107,48.8593 18.6945,49.0291 18.8515,49.0748 19.0814,49.2241 19.1543,49.4273 19.379,50.0537 19.6665,50.7121 19.9715,51.3161 20.2083,51.7851 20.6799,51.7401 20.8255,51.2354 21.0146,50.5802 21.1392,49.88 21.2911,49.2107 21.3232,49.0054 21.4594,48.8326 21.6479,48.7451 22.1571,48.5087 22.6451,48.25 23.0418,48.0285 23.4123,47.8217 23.368,47.268 22.9691,47.1233 22.5432,46.9687 22.0149,46.793 21.4467,46.6453 21.2467,46.5934 21.084,46.4591 20.9953,46.2552 20.6967,45.5679 20.4932,44.9806 20.1881,44.3795 19.9504,43.911 19.4486,43.9736 19.3029,44.4783 19.1167,45.1235 19.0041,45.7589 18.8707,46.4507z + F1 M113,63z M0,0z M85.5356,32.3089C85.4618,31.8454 85.0981,31.4704 84.6525,31.1923 83.3702,30.6082 82.3647,30.068 81.5388,29.5577 80.8075,29.1059 80.9283,27.9083 81.7332,27.6069 82.6738,27.2548 83.8423,26.9423 85.1432,26.5639 85.4929,26.4621 86.0051,26.1296 86.1675,25.6767 86.6682,24.2811 87.3086,22.8142 87.9883,21.4683 88.5159,20.4235 89.5666,20.5237 89.8912,21.6482 90.3125,23.108 90.59,24.6681 90.9286,26.1594 91.0001,26.6168 91.3036,27.0018 91.7234,27.1967 92.858,27.7236 93.9453,28.3 94.8293,28.7935 95.6549,29.2543 95.5561,30.4878 94.6674,30.8104 93.7183,31.1548 92.5412,31.5463 91.2752,31.8753 90.8297,31.991 90.467,32.2901 90.2695,32.7445 89.6042,34.2758 89.1507,35.5845 88.471,36.9238 87.9414,37.9676 86.8233,37.8282 86.4987,36.7036 86.0837,35.2659 85.833,33.8503 85.5356,32.3089z + F1 M113,63z M0,0z M85.5356,32.3089C85.4618,31.8454 85.0981,31.4704 84.6525,31.1923 83.3702,30.6082 82.3647,30.068 81.5388,29.5577 80.8075,29.1059 80.9283,27.9083 81.7332,27.6069 82.6738,27.2548 83.8423,26.9423 85.1432,26.5639 85.4929,26.4621 86.0051,26.1296 86.1675,25.6767 86.6682,24.2811 87.3086,22.8142 87.9883,21.4683 88.5159,20.4235 89.5666,20.5237 89.8912,21.6482 90.3125,23.108 90.59,24.6681 90.9286,26.1594 91.0001,26.6168 91.3036,27.0018 91.7234,27.1967 92.858,27.7236 93.9453,28.3 94.8293,28.7935 95.6549,29.2543 95.5561,30.4878 94.6674,30.8104 93.7183,31.1548 92.5412,31.5463 91.2752,31.8753 90.8297,31.991 90.467,32.2901 90.2695,32.7445 89.6042,34.2758 89.1507,35.5845 88.471,36.9238 87.9414,37.9676 86.8233,37.8282 86.4987,36.7036 86.0837,35.2659 85.833,33.8503 85.5356,32.3089z + F1 M113,63z M0,0z M79.6873,35.4049C79.6636,35.2557 79.5465,35.135 79.4031,35.0455 78.9904,34.8575 78.6668,34.6836 78.4009,34.5194 78.1656,34.374 78.2044,33.9885 78.4635,33.8915 78.7662,33.7782 79.1424,33.6776 79.561,33.5558 79.6736,33.5231 79.8384,33.416 79.8907,33.2703 80.0519,32.8211 80.258,32.349 80.4768,31.9157 80.6466,31.5795 80.9848,31.6117 81.0892,31.9736 81.2248,32.4435 81.3141,32.9456 81.4231,33.4256 81.4462,33.5728 81.5438,33.6967 81.6789,33.7595 82.0441,33.9291 82.394,34.1146 82.6786,34.2734 82.9443,34.4218 82.9125,34.8188 82.6265,34.9226 82.321,35.0334 81.9422,35.1594 81.5347,35.2653 81.3912,35.3026 81.2745,35.3988 81.211,35.5451 80.9969,36.0379 80.8509,36.4591 80.6321,36.8902 80.4616,37.2262 80.1018,37.1813 79.9973,36.8194 79.8638,36.3566 79.7831,35.901 79.6873,35.4049z + F1 M113,63z M0,0z M79.6873,35.4049C79.6636,35.2557 79.5465,35.135 79.4031,35.0455 78.9904,34.8575 78.6668,34.6836 78.4009,34.5194 78.1656,34.374 78.2044,33.9885 78.4635,33.8915 78.7662,33.7782 79.1424,33.6776 79.561,33.5558 79.6736,33.5231 79.8384,33.416 79.8907,33.2703 80.0519,32.8211 80.258,32.349 80.4768,31.9157 80.6466,31.5795 80.9848,31.6117 81.0892,31.9736 81.2248,32.4435 81.3141,32.9456 81.4231,33.4256 81.4462,33.5728 81.5438,33.6967 81.6789,33.7595 82.0441,33.9291 82.394,34.1146 82.6786,34.2734 82.9443,34.4218 82.9125,34.8188 82.6265,34.9226 82.321,35.0334 81.9422,35.1594 81.5347,35.2653 81.3912,35.3026 81.2745,35.3988 81.211,35.5451 80.9969,36.0379 80.8509,36.4591 80.6321,36.8902 80.4616,37.2262 80.1018,37.1813 79.9973,36.8194 79.8638,36.3566 79.7831,35.901 79.6873,35.4049z + F1 M113,63z M0,0z M78.8707,25.4978C78.8376,25.2897 78.6743,25.1214 78.4744,24.9966 77.8988,24.7345 77.4476,24.492 77.0768,24.263 76.7487,24.0603 76.8028,23.5228 77.1641,23.3875 77.5862,23.2294 78.1107,23.0892 78.6945,22.9194 78.8515,22.8737 79.0814,22.7244 79.1543,22.5212 79.379,21.8948 79.6665,21.2364 79.9715,20.6324 80.2083,20.1634 80.6799,20.2084 80.8255,20.7131 81.0146,21.3683 81.1392,22.0685 81.2911,22.7378 81.3232,22.9431 81.4594,23.1159 81.6479,23.2034 82.1571,23.4398 82.6451,23.6985 83.0418,23.92 83.4123,24.1268 83.368,24.6805 82.9691,24.8252 82.5432,24.9798 82.0149,25.1555 81.4467,25.3032 81.2467,25.3551 81.084,25.4894 80.9954,25.6933 80.6967,26.3806 80.4932,26.9679 80.1881,27.569 79.9504,28.0375 79.4486,27.9749 79.3029,27.4702 79.1167,26.825 79.0042,26.1896 78.8707,25.4978z + F1 M113,63z M0,0z M73.9718,30.9626C73.1149,29.8038,71.7888,29.14,70.3347,29.14L68.1805,29.14 66.5052,29.14 64.9512,24.1435C64.4006,22.2928,62.649,21,60.6932,21L60.4105,21 49.6361,21C46.0131,21,42.8799,23.331,41.8395,26.8016L38.1906,38.9642C37.7836,40.3221 38.0352,41.7533 38.8817,42.8907 39.7275,44.0273 41.0262,44.68 42.4433,44.68L45.8444,44.68C46.6162,44.9686,47.3717,45.4318,47.6559,47.1079L47.7684,47.7858C48.2242,50.5719 48.5254,52.4123 51.9753,52.8148 52.0041,52.8185 52.033,52.82 52.0604,52.82L63.019,52.82C66.6968,52.82,69.8781,50.4905,70.9348,47.0221L74.6467,34.8587C75.0574,33.5156,74.8109,32.0948,73.9718,30.9626z M60.4105,22.48L60.6932,22.48C62.0001,22.48,63.1678,23.3377,63.5363,24.5742L64.9556,29.14 63.3328,29.14C62.5173,29.14 61.7573,29.396 61.1357,29.8393 61.0825,29.8186 61.0321,29.7912 60.9722,29.7831 58.8972,29.5048 57.4261,29.8149 56.3923,30.3107L57.623,26.2081C57.9885,24.9916,59.1496,22.48,60.4105,22.48z M59.9858,31.1735C59.8896,31.3637,59.8052,31.5628,59.7416,31.7729L56.3805,42.7878C55.5739,43.1785 53.7424,43.2673 52.2365,43.2585 52.514,42.9025 52.7367,42.4977 52.8729,42.0426L55.6235,32.874C55.8899,32.4064,56.9525,30.9981,59.9858,31.1735z M42.4433,43.2C41.4991,43.2 40.6333,42.7649 40.0687,42.0071 39.5048,41.2494 39.3368,40.2955 39.6084,39.3897L43.2573,27.2264C44.1091,24.3877,46.6724,22.48,49.6361,22.48L57.8575,22.48C56.8371,23.7713,56.2947,25.4844,56.2051,25.7826L54.2449,32.3168C54.2005,32.4056 54.1753,32.467 54.1694,32.4833 54.1442,32.5477 54.142,32.6136 54.1361,32.6794L51.4543,41.6186C51.1709,42.5643,50.3155,43.2,49.3276,43.2L48.7555,43.2 42.4433,43.2z M52.087,51.337C49.8071,51.0581,49.6791,50.3003,49.2284,47.5468L49.1152,46.8608C48.9524,45.8995,48.6431,45.2032,48.2627,44.68L49.3276,44.68C49.3298,44.68,49.332,44.6793,49.3342,44.6793L50.371,44.6785C50.5708,44.6918 51.4033,44.7429 52.4415,44.7429 53.5219,44.7429 54.8198,44.6844 55.8655,44.4743L54.9094,47.6082C54.6149,48.5702,53.4656,51.3015,52.087,51.337z M73.2318,34.4273L69.5199,46.5907C68.6667,49.3864,65.9938,51.34,63.019,51.34L54.6489,51.34C55.6827,50.0502,56.2347,48.3386,56.325,48.0411L61.1565,32.2058C61.4421,31.2719,62.3368,30.62,63.3321,30.62L65.9605,30.62 68.1805,30.62 70.3347,30.62C71.3144,30.62 72.2069,31.0662 72.7826,31.8425 73.3398,32.5951 73.5026,33.5363 73.2318,34.4273z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + F1 M113,63z M0,0z M56.3169,13C48.5041,13 41.8579,17.6666 39.1304,24.9701 41.3568,22.5219 44.305,21.2154 47.7309,21.2154L47.7565,21.2154C53.0719,21.2236,58.6898,24.5841,60.5465,28.8643L60.5385,28.8643C61.2039,30.1624 61.0489,31.5017 60.8353,32.3478 60.5889,33.309 60.2192,33.7604 60.0796,33.9412L60.0042,34.039C59.733,34.3759 59.7752,34.8697 60.0956,35.1655 60.1531,35.2147 60.2436,35.2807 60.3668,35.3628L60.5802,35.4944C61.6236,36.1516 63.9815,36.8246 66.1175,36.8246 67.7524,36.8246 69.8878,36.5701 71.8924,34.5573 75.2607,31.189 73.9622,26.4894 73.4857,25.1257 72.6724,22.8172 69.2968,15.1443 59.8244,13.337 58.6743,13.1151 57.4917,13 56.3169,13z M47.7309,22.8585C43.4589,22.8585 40.0334,25.2499 38.0618,29.604 37.4127,37.1293 41.9718,43.8812 47.3939,46.9044 48.1743,47.3399 50.6551,48.5892 54.1138,49 51.0577,47.5541 48.7331,45.0317 47.6651,41.7538 45.8905,36.307 48.1172,30.4911 53.334,26.9421L53.342,26.9501C54.1307,26.4325 55.0919,26.1366 56.0778,26.1366 56.1928,26.1366 56.2997,26.1362 56.4148,26.1526 54.1062,24.1809 50.8373,22.8667 47.7565,22.8585L47.7309,22.8585z M51.1405,31.2134C48.8567,34.1463 48.1088,37.7865 49.2343,41.2451 50.7213,45.8129 55.0679,48.7044 60.3668,48.7208 64.4909,47.8007 68.0801,45.3926 71.0869,41.5067L71.1607,41.4088C71.3661,41.1048 71.3506,40.7015 71.1206,40.414 70.8823,40.1347 70.4882,40.0367 70.1514,40.1845L69.7567,40.3658C69.5924,40.4398 69.4448,40.4879 69.2641,40.5536 69.0751,40.6193 68.8615,40.7017 68.5821,40.8167 67.5224,41.2521 65.9454,41.4987 64.253,41.4987 62.8318,41.4987 61.4434,41.3186 60.3507,40.99 58.8062,40.53 54.0976,39.1082 51.6412,33.6861 51.3372,33.0124 51.1323,32.15 51.1405,31.2134z + F1 M113,63z M0,0z M57.6449,56.1063C57.7345,56.0167 58.8095,54.8521 60.5116,53.0605 63.0199,50.4626 73.9491,38.8167 74.1283,38.6376 74.9345,37.8313 78.7866,40.7876 82.0116,37.5626 84.072,35.5022 84.7887,32.9042 83.8929,29.7688L79.772,33.8897C79.772,33.8897 78.2491,33.8896 76.7262,32.4563 75.2929,30.9334 75.2929,29.4105 75.2929,29.4105L79.4137,25.3792C76.4574,24.4834 73.5908,25.2001 71.5304,27.2605 68.3949,30.3959 71.172,34.3376 70.3658,35.1438 70.1866,35.2334 54.8679,49.8355 54.6887,50.0146 53.1658,51.448 53.0762,51.5376 52.9866,51.5376 51.7324,52.8813 51.6429,55.0313 52.897,56.2855 54.1512,57.5396 56.3012,57.4501 57.6449,56.1063z M55.5845,52.2542C56.3012,52.2542 56.9283,52.8813 56.9283,53.598 56.9283,54.3146 56.3012,54.9417 55.5845,54.9417 54.8679,54.9417 54.2408,54.3146 54.2408,53.598 54.2408,52.8813 54.7783,52.2542 55.5845,52.2542z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 1520807..1b26536 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -32,6 +32,7 @@ internal class Configuration public static bool Uninstall { get; set; } public static bool UninstallEdge { get; set; } public static bool NoEdgeInstalled { get; set; } + public static bool InstallControlPanel { get; set; } public static string? CustomQueryUrl { get; set; } public static string InstallDir = Path.Combine( diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index c715e35..4655f31 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -190,6 +190,14 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) return; } + // Create Shortcut for Control Panel + if (Configuration.InstallControlPanel) + { + var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "Microsoft", "Windows", "Start Menu", "Programs", "GoAwayEdge.lnk"); + Shortcut.Create(Path.Combine(Configuration.InstallDir, "GoAwayEdge.exe"), "--control-panel", shortcutPath); + } + // Switch FrameWindow content to InstallationSuccess worker?.ReportProgress(100, ""); Logging.Log("Installation finished."); diff --git a/GoAwayEdge/Common/Installation/Shortcut.cs b/GoAwayEdge/Common/Installation/Shortcut.cs new file mode 100644 index 0000000..00bff8b --- /dev/null +++ b/GoAwayEdge/Common/Installation/Shortcut.cs @@ -0,0 +1,54 @@ +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Text; + +namespace GoAwayEdge.Common.Installation +{ + public class Shortcut + { + /// + /// Creates a shortcut (.lnk) for a given application. + /// + /// The file path of the application to which the shortcut points. + /// The arguments to pass to the application when it is started via the shortcut. + /// The file path where the shortcut will be saved. + public static void Create(string applicationPath, string arguments, string targetPath) + { + var link = (IShellLink)new ShellLink(); + link.SetPath(applicationPath); + link.SetArguments(arguments); + + var file = (IPersistFile)link; + file.Save(targetPath, false); + } + + [ComImport] + [Guid("00021401-0000-0000-C000-000000000046")] + internal class ShellLink; + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("000214F9-0000-0000-C000-000000000046")] + internal interface IShellLink + { + void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags); + void GetIDList(out IntPtr ppidl); + void SetIDList(IntPtr pidl); + void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); + void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); + void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); + void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); + void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); + void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); + void GetHotkey(out short pwHotkey); + void SetHotkey(short wHotkey); + void GetShowCmd(out int piShowCmd); + void SetShowCmd(int iShowCmd); + void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); + void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); + void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); + void Resolve(IntPtr hwnd, int fFlags); + void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); + } + } +} diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index c7c98f5..49966af 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -12,7 +12,7 @@ GoAwayEdge Exploitox valnoxy - 2.0.0.160 + 2.0.0.192 Copyright © 2018 - 2024 Exploitox. All rights reserved. https://github.com/valnoxy/GoAwayEdge https://github.com/valnoxy/GoAwayEdge @@ -61,7 +61,7 @@ - + Code diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 090ee6f..aef9ad6 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -7,10 +7,10 @@ Code - + Code - + Code @@ -45,16 +45,19 @@ Designer - + Designer - + + Designer + + Designer Designer - + Designer diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 48a0686..d3432ae 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -15,6 +15,8 @@ Deinstallieren Deinstalliere GoAwayEdge und wiederherstelle die Edge-Funktionalität. Bitte verwenden Sie den Installer, um GoAwayEdge zu deinstallieren. + Kontrollpanel installieren + Installiere das Kontrollpanel, um GoAwayEdge einfacher zu konfigurieren. Lizenz diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 73c8534..017a4ce 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -34,6 +34,8 @@ Please enter the query URL from the search engine. Remove Microsoft Edge (Stable) Remove Microsoft Edge completely from the system. + Install Control Panel + Install the Control Panel to configure GoAwayEdge more easily. Installation in progress ... diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index d3e0d3b..d7300da 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-07-22T16:41:59.8117684Z;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; + True|2024-07-29T22:22:22.2984409Z;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml b/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml deleted file mode 100644 index 77eba60..0000000 --- a/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs b/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs deleted file mode 100644 index 9d86c9b..0000000 --- a/GoAwayEdge/UserInterface/ControlCenter/Pages/HomeScreen.xaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace GoAwayEdge.UserInterface.ControlCenter.Pages -{ - /// - /// Interaktionslogik für HomeScreen.xaml - /// - public partial class HomeScreen : Page - { - public HomeScreen() - { - InitializeComponent(); - } - } -} diff --git a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml similarity index 96% rename from GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml rename to GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml index 0634084..521b5bb 100644 --- a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml @@ -1,14 +1,14 @@ - diff --git a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs similarity index 81% rename from GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs rename to GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs index 65e01be..b99b4c3 100644 --- a/GoAwayEdge/UserInterface/ControlCenter/ControlCenter.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs @@ -1,25 +1,25 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.IO; using System.Reflection; using System.Security.Principal; using System.Windows; using System.Windows.Threading; using Wpf.Ui.Controls; -namespace GoAwayEdge.UserInterface.ControlCenter +namespace GoAwayEdge.UserInterface.ControlPanel { /// - /// Interaktionslogik für ControlCenter.xaml + /// Interaktionslogik für ControlPanel.xaml /// - public partial class ControlCenter + public partial class ControlPanel { private readonly DispatcherTimer _timer = new() { Interval = TimeSpan.FromSeconds(1) }; - [RequiresAssemblyFiles] - public ControlCenter() + public ControlPanel() { InitializeComponent(); @@ -31,7 +31,9 @@ public ControlCenter() // Get version var assembly = Assembly.GetExecutingAssembly(); - var fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + var appDirectory = AppContext.BaseDirectory; + var assemblyPath = Path.Combine(appDirectory, $"{assembly.GetName().Name}.exe"); + var fvi = FileVersionInfo.GetVersionInfo(assemblyPath); var version = fvi.FileVersion; Version.Text = $"Version {version}"; diff --git a/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml similarity index 99% rename from GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml rename to GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml index 101977c..0ad487d 100644 --- a/GoAwayEdge/UserInterface/ControlCenter/Pages/About.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml @@ -1,9 +1,9 @@ - /// Interaktionslogik für About.xaml @@ -13,11 +14,12 @@ public About() { InitializeComponent(); - var version = Assembly.GetExecutingAssembly().GetName().Version!; - var product = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductName; - var copyright = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).LegalCopyright; - ValueVersion.Content = $"{product} v{version}"; - ValueCopyright.Content = copyright; + var assembly = Assembly.GetExecutingAssembly(); + var appDirectory = AppContext.BaseDirectory; + var assemblyPath = Path.Combine(appDirectory, $"{assembly.GetName().Name}.exe"); + var fvi = FileVersionInfo.GetVersionInfo(assemblyPath); + ValueVersion.Content = $"{fvi.ProductName} v{fvi.FileVersion}"; + ValueCopyright.Content = fvi.LegalCopyright; } private void Homepage_OnClick(object sender, RoutedEventArgs e) diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml new file mode 100644 index 0000000..2f1b591 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs new file mode 100644 index 0000000..18245bd --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace GoAwayEdge.UserInterface.ControlPanel.Pages +{ + /// + /// Interaktionslogik für HomeScreen.xaml + /// + public partial class HomeScreen : Page + { + public HomeScreen() + { + InitializeComponent(); + } + } +} diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml index 7759f75..261de2e 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml @@ -104,6 +104,30 @@ + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index 7196493..90a8a69 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -52,6 +52,8 @@ public Settings() SearchEngineBox.SelectedIndex = 0; Configuration.Search = SearchEngine.Google; Configuration.Uninstall = false; + Configuration.InstallControlPanel = true; + ControlPanelSwitch.IsChecked = true; } private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) @@ -135,5 +137,10 @@ private void MsEdgeUninstallSwitch_OnClickUninstallSwitch_OnClick(object sender, { Configuration.UninstallEdge = MsEdgeUninstallSwitch.IsChecked!.Value; } + + private void ControlPanelSwitch_OnClick(object sender, RoutedEventArgs e) + { + Configuration.InstallControlPanel = ControlPanelSwitch.IsChecked!.Value; + } } } From cdce7a9d554bfacb926ec2b228a5daaec694b05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 31 Jul 2024 00:13:31 +0200 Subject: [PATCH 07/80] little clean up & some improvements --- GoAwayEdge/App.xaml | 1 - GoAwayEdge/App.xaml.cs | 1 + GoAwayEdge/Common/Debugging/Logging.cs | 5 ++++- GoAwayEdge/Common/Installation/InstallRoutine.cs | 9 +++++++++ GoAwayEdge/Common/Installation/Updater.cs | 8 ++++---- GoAwayEdge/Common/Localization.cs | 13 +++++++++++-- 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/GoAwayEdge/App.xaml b/GoAwayEdge/App.xaml index 633d9f4..8bcb9eb 100644 --- a/GoAwayEdge/App.xaml +++ b/GoAwayEdge/App.xaml @@ -10,7 +10,6 @@ - diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 831d61b..5c29a7a 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -16,6 +16,7 @@ using System.Windows; using GoAwayEdge.Common.Runtime; using GoAwayEdge.Common.Debugging; +using GoAwayEdge.Common.Installation; namespace GoAwayEdge { diff --git a/GoAwayEdge/Common/Debugging/Logging.cs b/GoAwayEdge/Common/Debugging/Logging.cs index da523a8..74e2fa8 100644 --- a/GoAwayEdge/Common/Debugging/Logging.cs +++ b/GoAwayEdge/Common/Debugging/Logging.cs @@ -52,7 +52,10 @@ public static void Log(string message, LogLevel level = LogLevel.INFO) if (string.IsNullOrEmpty(_logFile)) throw new Exception("Logging class not initialized!"); using var writer = new StreamWriter(_logFile, true); - writer.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {level} - {message}"); + + var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {level} - {message}"; + writer.WriteLine(logMessage); + System.Diagnostics.Debug.WriteLine(logMessage); } private static void DeleteOldLogFiles() diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index 4655f31..d1d8a3c 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -150,6 +150,10 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) { ts.RootFolder.DeleteTask("valnoxy\\GoAwayEdge\\GoAwayEdge IFEO Validation"); } + catch (FileNotFoundException) + { + Logging.Log("Old Task not found, skipping ..."); + } catch (Exception ex) { Logging.Log("Failed to delete old task: " + ex, Logging.LogLevel.ERROR); @@ -332,6 +336,11 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) Logging.Log("Failed to remove uninstall data: " + ex, Logging.LogLevel.ERROR); } + // Remove Control Panel shortcut if exists + var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "Microsoft", "Windows", "Start Menu", "Programs", "GoAwayEdge.lnk"); + if (File.Exists(shortcutPath)) File.Delete(shortcutPath); + // Switch FrameWindow content to InstallationSuccess worker?.ReportProgress(100, ""); Logging.Log("Uninstallation finished."); diff --git a/GoAwayEdge/Common/Installation/Updater.cs b/GoAwayEdge/Common/Installation/Updater.cs index 66bdc64..3fc89f5 100644 --- a/GoAwayEdge/Common/Installation/Updater.cs +++ b/GoAwayEdge/Common/Installation/Updater.cs @@ -1,13 +1,13 @@ -using Microsoft.Toolkit.Uwp.Notifications; -using Microsoft.Win32; -using System.Diagnostics; +using System.Diagnostics; using System.IO; using System.Net; using System.Reflection; using System.Security.Cryptography; +using Microsoft.Toolkit.Uwp.Notifications; +using Microsoft.Win32; using Newtonsoft.Json; -namespace GoAwayEdge.Common +namespace GoAwayEdge.Common.Installation { internal class Updater { diff --git a/GoAwayEdge/Common/Localization.cs b/GoAwayEdge/Common/Localization.cs index 7271633..89b5a43 100644 --- a/GoAwayEdge/Common/Localization.cs +++ b/GoAwayEdge/Common/Localization.cs @@ -8,10 +8,12 @@ internal class LocalizationManager public static void LoadLanguage() { // Set current language model + const string overrideLanguage = "duh"; + var language = Thread.CurrentThread.CurrentCulture.ToString(); var dict = new ResourceDictionary(); - Logging.Log($"Trying to load language: " + language); - System.Diagnostics.Debug.WriteLine("Trying to load language: " + language); + if (!string.IsNullOrEmpty(overrideLanguage)) language = overrideLanguage; + Logging.Log("Trying to load language: " + language); dict.Source = language switch { "en-US" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.xaml", UriKind.Relative), @@ -35,6 +37,13 @@ public static void LoadLanguage() messageUi.ShowDialog(); Environment.Exit(1); } + + if (dict.Source == + new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.xaml", UriKind.Relative) && + language != "en-US") + { + Logging.Log($"No localization file found for language {language}, falling back to English ...", Logging.LogLevel.WARNING); + } } public static string LocalizeValue(string value) From c5dd1bddf89b870393d9cb45eab290d2ca392234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 31 Jul 2024 00:31:33 +0200 Subject: [PATCH 08/80] [Weblate] Translation updated --- .../ResourceDictionary.de-DE.xaml | 127 ++++++++---------- .../ResourceDictionary.es-ES.xaml | 125 ++++++++--------- .../ResourceDictionary.fr-FR.xaml | 125 ++++++++--------- .../ResourceDictionary.it-IT.xaml | 125 ++++++++--------- .../ResourceDictionary.ko-KR.xaml | 125 ++++++++--------- .../ResourceDictionary.pl-PL.xaml | 125 ++++++++--------- 6 files changed, 354 insertions(+), 398 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index d3432ae..e23dfd4 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -1,68 +1,59 @@ - - - GoAwayEdge-Installationsprogramm - Weiter - Zurück - Beenden - Ja - Nein - - - Willkommen - Das Installationsprogramm führt alle notwendigen Schritte durch, um GoAwayEdge auf Ihrem System zu installieren. Nach der Installation werden alle Edge-Aufrufe an Ihren Browser weitergeleitet. Bitte wählen Sie die gewünschte Option, um fortzufahren. - Installieren - Installiere und konfiguriere GoAwayEdge auf Ihrem System. - Deinstallieren - Deinstalliere GoAwayEdge und wiederherstelle die Edge-Funktionalität. - Bitte verwenden Sie den Installer, um GoAwayEdge zu deinstallieren. - Kontrollpanel installieren - Installiere das Kontrollpanel, um GoAwayEdge einfacher zu konfigurieren. - - - Lizenz - Bitte lesen Sie die folgende Lizenz. Sie müssen die Lizenzbedingungen akzeptieren, bevor Sie mit der Installation fortfahren können. - Ich akzeptiere diese Lizenz. - Ich lehne diese Lizenz ab. - - - Einstellungen - Edge Channel - Wählen Sie den installierten Microsoft Edge Channel aus. - Suchmaschine - Wählen Sie Ihre bevorzugte Suchmaschine. - Benutzerdefiniert - Benutzerdefinierte Suchmaschine - Bitte geben Sie die Anfrage-URL der Suchmaschine ein. - Microsoft Edge (Stabil) entfernen - Entferne Microsoft Edge vollständig von Ihrem System. - - - Installation läuft ... - Bitte warten Sie, bis die Installation abgeschlossen ist. - - - Installation abgeschlossen! - Öffnen Sie das Installationsprogramm, wenn Sie GoAwayEdge erneut anpassen möchten. - Deinstallation abgeschlossen! - GoAwayEdge wurde erfolgreich vom System entfernt. - Über PayPal spenden - - - Initialisierung fehlgeschlagen: {0} - Installation fehlgeschlagen: {0} - Deinstallation fehlgeschlagen: {0} - Aktualisierung fehlgeschlagen: {0} - Installation fehlgeschlagen! Bitte versuchen Sie es erneut. - Die Entfernung von Microsoft Edge ist fehlgeschlagen! Bitte versuchen Sie es erneut. - "Image File Execution Option" für '{0}' konnte nicht registriert werden. Bitte versuchen Sie es erneut. - Eine neue Version von GoAwayEdge (v{0}) ist verfügbar. Dieses Update enthält neue Funktionen, behebt Fehler und gewährleistet die Funktionalität dieser Anwendung. - Microsoft Edge wurde aktualisiert und GoAwayEdge muss die alternative Startdatei aktualisieren, um die Edge-Funktionalität zu gewährleisten. - Die alternative Startdatei von Edge fehlt und muss kopiert werden, um die Edge-Funktionalität zu gewährleisten. Jetzt kopieren? - Update installieren - Erinnere mich später - Aktualisierung erfolgreich - Die alternative Startdatei von Edge wurde erfolgreich aktualisiert. - Erstellung erfolgreich - Die alternative Startdatei von Edge wurde erfolgreich erstellt. - - + + GoAwayEdge-Installationsprogramm + Weiter + Zurück + Beenden + Ja + Nein + + Willkommen + Das Installationsprogramm führt alle notwendigen Schritte durch, um GoAwayEdge auf Ihrem System zu installieren. Nach der Installation werden alle Edge-Aufrufe an Ihren Browser weitergeleitet. Bitte wählen Sie die gewünschte Option, um fortzufahren. + Installieren + Installiere und konfiguriere GoAwayEdge auf Ihrem System. + Deinstallieren + Deinstalliere GoAwayEdge und wiederherstelle die Edge-Funktionalität. + Bitte verwenden Sie den Installer, um GoAwayEdge zu deinstallieren. + + Lizenz + Bitte lesen Sie die folgende Lizenz. Sie müssen die Lizenzbedingungen akzeptieren, bevor Sie mit der Installation fortfahren können. + Ich akzeptiere diese Lizenz. + Ich lehne diese Lizenz ab. + + Einstellungen + Edge Channel + Wählen Sie den installierten Microsoft Edge Channel aus. + Suchmaschine + Wählen Sie Ihre bevorzugte Suchmaschine. + Benutzerdefiniert + Benutzerdefinierte Suchmaschine + Bitte geben Sie die Anfrage-URL der Suchmaschine ein. + Microsoft Edge (Stabil) entfernen + Entferne Microsoft Edge vollständig von Ihrem System. + + Installation läuft ... + Bitte warten Sie, bis die Installation abgeschlossen ist. + + Installation abgeschlossen! + Öffnen Sie das Installationsprogramm, wenn Sie GoAwayEdge erneut anpassen möchten. + Deinstallation abgeschlossen! + GoAwayEdge wurde erfolgreich vom System entfernt. + Über PayPal spenden + + Initialisierung fehlgeschlagen: {0} + Installation fehlgeschlagen: {0} + Deinstallation fehlgeschlagen: {0} + Aktualisierung fehlgeschlagen: {0} + Installation fehlgeschlagen! Bitte versuchen Sie es erneut. + Die Entfernung von Microsoft Edge ist fehlgeschlagen! Bitte versuchen Sie es erneut. + "Image File Execution Option" für '{0}' konnte nicht registriert werden. Bitte versuchen Sie es erneut. + Eine neue Version von GoAwayEdge (v{0}) ist verfügbar. Dieses Update enthält neue Funktionen, behebt Fehler und gewährleistet die Funktionalität dieser Anwendung. + Microsoft Edge wurde aktualisiert und GoAwayEdge muss die alternative Startdatei aktualisieren, um die Edge-Funktionalität zu gewährleisten. + Die alternative Startdatei von Edge fehlt und muss kopiert werden, um die Edge-Funktionalität zu gewährleisten. Jetzt kopieren? + Update installieren + Erinnere mich später + Aktualisierung erfolgreich + Die alternative Startdatei von Edge wurde erfolgreich aktualisiert. + Erstellung erfolgreich + Die alternative Startdatei von Edge wurde erfolgreich erstellt. + Version überspringen + diff --git a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml index 4bfbbc7..c4bf41c 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml @@ -1,66 +1,59 @@ - - - Instalador de GoAwayEdge - Siguiente - Volver - Salida - - No - - - Bienvenido - El instalador realizará todos los pasos necesarios para instalar GoAwayEdge en tu sistema. Tras la instalación, todas las llamadas a Edge serán redirigidas a tu navegador. Por favor, selecciona la opción deseada para continuar. - Instale - Instale y configure GoAwayEdge en su sistema. - Desinstalar - Desinstala GoAwayEdge y restaura la funcionalidad de Edge. - Por favor, utilice el Instalador para desinstalar GoAwayEdge. - - - Licencia - Por favor, lea la siguiente Licencia. Debe aceptar los términos de la licencia antes de continuar con la instalación. - Aceptar licencia. - Rechazar licencia. - - - Ajustes - Canal Edge - Seleccione el canal Microsoft Edge instalado. - Motor de búsqueda - Seleccione su motor de búsqueda favorito. - Personalizar - Motor de búsqueda personalizado - Introduzca la URL de consulta del motor de búsqueda. - Eliminar Microsoft Edge (Estable) - Elimine Microsoft Edge completamente del sistema. - - - Instalación en curso ... - Espere a que finalice la instalación. - - - Instalación finalizada. - Simplemente abre este Instalador, si quieres personalizar GoAwayEdge de nuevo. - Desinstalación completada. - GoAwayEdge ha sido eliminado con éxito del sistema. - Donar a través de PayPal - - - Error de inicialización: {0} - Error de instalación: {0} - Error de desinstalación: {0} - Actualización fallida: {0} - Error de instalación. Por favor, inténtelo de nuevo. - La eliminación de Microsoft Edge ha fallado. Por favor, inténtalo de nuevo. - Error al registrar la opción de ejecución de archivos de imagen para '{0}'. Por favor, inténtelo de nuevo. - Una nueva versión de GoAwayEdge (v{0}) está disponible. Esta actualización incluye nuevas características, corrección de errores y garantiza la funcionalidad de esta aplicación. - Microsoft Edge ha sido actualizado y GoAwayEdge necesita actualizar el archivo no-IFEO para asegurar la funcionalidad de Edge. - Falta la versión de Edge que no es IEFO y debe copiarse para garantizar la funcionalidad de Edge. ¿Copiar ahora? - Instalar actualización - Recuérdamelo más tarde - Actualización satisfactoria - La versión no IEFO de Edge se ha actualizado correctamente. - Creación con éxito - La versión no IEFO de Edge se ha creado correctamente. - - + + Instalador de GoAwayEdge + Siguiente + Volver + Salida + + No + + Bienvenido + El instalador realizará todos los pasos necesarios para instalar GoAwayEdge en tu sistema. Tras la instalación, todas las llamadas a Edge serán redirigidas a tu navegador. Por favor, selecciona la opción deseada para continuar. + Instale + Instale y configure GoAwayEdge en su sistema. + Desinstalar + Desinstala GoAwayEdge y restaura la funcionalidad de Edge. + Por favor, utilice el Instalador para desinstalar GoAwayEdge. + + Licencia + Por favor, lea la siguiente Licencia. Debe aceptar los términos de la licencia antes de continuar con la instalación. + Aceptar licencia. + Rechazar licencia. + + Ajustes + Canal Edge + Seleccione el canal Microsoft Edge instalado. + Motor de búsqueda + Seleccione su motor de búsqueda favorito. + Personalizar + Motor de búsqueda personalizado + Introduzca la URL de consulta del motor de búsqueda. + Eliminar Microsoft Edge (Estable) + Elimine Microsoft Edge completamente del sistema. + + Instalación en curso ... + Espere a que finalice la instalación. + + Instalación finalizada. + Simplemente abre este Instalador, si quieres personalizar GoAwayEdge de nuevo. + Desinstalación completada. + GoAwayEdge ha sido eliminado con éxito del sistema. + Donar a través de PayPal + + Error de inicialización: {0} + Error de instalación: {0} + Error de desinstalación: {0} + Actualización fallida: {0} + Error de instalación. Por favor, inténtelo de nuevo. + La eliminación de Microsoft Edge ha fallado. Por favor, inténtalo de nuevo. + Error al registrar la opción de ejecución de archivos de imagen para '{0}'. Por favor, inténtelo de nuevo. + Una nueva versión de GoAwayEdge (v{0}) está disponible. Esta actualización incluye nuevas características, corrección de errores y garantiza la funcionalidad de esta aplicación. + Microsoft Edge ha sido actualizado y GoAwayEdge necesita actualizar el archivo no-IFEO para asegurar la funcionalidad de Edge. + Falta la versión de Edge que no es IEFO y debe copiarse para garantizar la funcionalidad de Edge. ¿Copiar ahora? + Instalar actualización + Recuérdamelo más tarde + Actualización satisfactoria + La versión no IEFO de Edge se ha actualizado correctamente. + Creación con éxito + La versión no IEFO de Edge se ha creado correctamente. + Saltar esta versión + diff --git a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml index 52df41c..53a5a4b 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml @@ -1,66 +1,59 @@ - - - Installateur GoAwayEdge - Suivant - Retour - Sortie - Oui - Non - - - Bienvenue - Le programme d'installation effectuera toutes les étapes nécessaires pour installer GoAwayEdge sur votre système. Après l'installation, tous les appels Edge seront redirigés vers votre navigateur. Veuillez sélectionner l'option souhaitée pour continuer. - Installer - Installez et configurez GoAwayEdge sur votre système. - Désinstaller - Désinstallez GoAwayEdge et rétablissez les fonctionnalités de Edge. - Veuillez utiliser le programme d'installation pour désinstaller GoAwayEdge. - - - Licence - Veuillez lire la licence suivante. Vous devez accepter les termes de la licence avant de poursuivre l'installation. - J'accepte cette licence. - Je refuse cette licence. - - - Paramètres - Canal de dérivation - Sélectionnez le canal Microsoft Edge installé. - Moteur de recherche - Sélectionnez votre moteur de recherche préféré. - Sur mesure - Moteur de recherche personnalisé - Veuillez saisir l'URL de la requête du moteur de recherche. - Supprimer Microsoft Edge (Stable) - Supprimer complètement Microsoft Edge du système. - - - Installation en cours ... - Veuillez patienter jusqu'à la fin de l'installation. - - - Installation terminée ! - Ouvrez simplement ce programme d'installation si vous souhaitez personnaliser GoAwayEdge à nouveau. - Désinstallation terminée ! - GoAwayEdge a été supprimé avec succès du système. - Faire un don via PayPal - - - Échec de l'initialisation : {0} - L'installation a échoué : {0} - La désinstallation a échoué : {0} - Échec de la mise à jour : {0} - L'installation a échoué ! Veuillez réessayer. - La suppression de Microsoft Edge a échoué ! Veuillez réessayer. - Échec de l'enregistrement de l'option d'exécution du fichier image pour '{0}'. Veuillez réessayer. - Une nouvelle version de GoAwayEdge (v{0}) est disponible. Cette mise à jour inclut de nouvelles fonctionnalités, des corrections de bugs et assure la fonctionnalité de cette application. - Microsoft Edge a été mis à jour et GoAwayEdge doit mettre à jour le fichier non-IFEO pour assurer la fonctionnalité de Edge. - La version non-IEFO d'Edge est manquante et doit être copiée pour assurer la fonctionnalité d'Edge. Copier maintenant ? - Installer la mise à jour - Rappelez-moi plus tard - Mise à jour réussie - La version non IFO de Edge a été mise à jour avec succès. - Création réussie - La version non-IEFO de Edge a été créée avec succès. - - + + Installateur GoAwayEdge + Suivant + Retour + Sortie + Oui + Non + + Bienvenue + Le programme d'installation effectuera toutes les étapes nécessaires pour installer GoAwayEdge sur votre système. Après l'installation, tous les appels Edge seront redirigés vers votre navigateur. Veuillez sélectionner l'option souhaitée pour continuer. + Installer + Installez et configurez GoAwayEdge sur votre système. + Désinstaller + Désinstallez GoAwayEdge et rétablissez les fonctionnalités de Edge. + Veuillez utiliser le programme d'installation pour désinstaller GoAwayEdge. + + Licence + Veuillez lire la licence suivante. Vous devez accepter les termes de la licence avant de poursuivre l'installation. + J'accepte cette licence. + Je refuse cette licence. + + Paramètres + Canal de dérivation + Sélectionnez le canal Microsoft Edge installé. + Moteur de recherche + Sélectionnez votre moteur de recherche préféré. + Sur mesure + Moteur de recherche personnalisé + Veuillez saisir l'URL de la requête du moteur de recherche. + Supprimer Microsoft Edge (Stable) + Supprimer complètement Microsoft Edge du système. + + Installation en cours ... + Veuillez patienter jusqu'à la fin de l'installation. + + Installation terminée ! + Ouvrez simplement ce programme d'installation si vous souhaitez personnaliser GoAwayEdge à nouveau. + Désinstallation terminée ! + GoAwayEdge a été supprimé avec succès du système. + Faire un don via PayPal + + Échec de l'initialisation : {0} + L'installation a échoué : {0} + La désinstallation a échoué : {0} + Échec de la mise à jour : {0} + L'installation a échoué ! Veuillez réessayer. + La suppression de Microsoft Edge a échoué ! Veuillez réessayer. + Échec de l'enregistrement de l'option d'exécution du fichier image pour '{0}'. Veuillez réessayer. + Une nouvelle version de GoAwayEdge (v{0}) est disponible. Cette mise à jour inclut de nouvelles fonctionnalités, des corrections de bugs et assure la fonctionnalité de cette application. + Microsoft Edge a été mis à jour et GoAwayEdge doit mettre à jour le fichier non-IFEO pour assurer la fonctionnalité de Edge. + La version non-IEFO d'Edge est manquante et doit être copiée pour assurer la fonctionnalité d'Edge. Copier maintenant ? + Installer la mise à jour + Rappelez-moi plus tard + Mise à jour réussie + La version non IFO de Edge a été mise à jour avec succès. + Création réussie + La version non-IEFO de Edge a été créée avec succès. + Sauter cette version + diff --git a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml index 4d965f5..c09164e 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml @@ -1,66 +1,59 @@ - - - Installatore GoAwayEdge - Avanti - Indietro - Uscita - - No - - - Benvenuti - Il programma di installazione eseguirà tutte le operazioni necessarie per installare GoAwayEdge sul sistema. Dopo l'installazione, tutte le chiamate a Edge verranno reindirizzate al browser. Selezionare l'opzione desiderata per continuare. - Installare - Installare e configurare GoAwayEdge sul sistema. - Disinstallare - Disinstallare GoAwayEdge e ripristinare la funzionalità di Edge. - Utilizzare il programma di installazione per disinstallare GoAwayEdge. - - - Licenza - Leggere la seguente licenza. È necessario accettare i termini della licenza prima di continuare l'installazione. - Accetto questa licenza. - Rifiuto questa licenza. - - - Impostazioni - Canale dei bordi - Selezionare il canale Microsoft Edge installato. - Motore di ricerca - Selezionate il vostro motore di ricerca preferito. - Personalizzato - Motore di ricerca personalizzato - Inserire l'URL della query dal motore di ricerca. - Rimuovere Microsoft Edge (Stabile) - Rimuovere completamente Microsoft Edge dal sistema. - - - Installazione in corso ... - Attendere il completamento dell'installazione. - - - Installazione completata! - È sufficiente aprire questo programma di installazione per personalizzare nuovamente GoAwayEdge. - Disinstallazione completata! - GoAwayEdge è stato rimosso con successo dal sistema. - Donazione tramite PayPal - - - Inizializzazione fallita: {0} - Installazione fallita: {0} - Disinstallazione fallita: {0} - Aggiornamento fallito: {0} - Installazione fallita! Riprovare. - La rimozione di Microsoft Edge non è riuscita! Riprovare. - Impossibile registrare l'opzione di esecuzione del file immagine per '{0}'. Riprovare. - È disponibile una nuova versione di GoAwayEdge (v{0}). Questo aggiornamento include nuove caratteristiche, correzioni di bug e garantisce la funzionalità di questa applicazione. - Microsoft Edge è stato aggiornato e GoAwayEdge deve aggiornare il file non-IFEO per garantire la funzionalità di Edge. - La versione non IFO di Edge è mancante e deve essere copiata per garantire la funzionalità di Edge. Copiare ora? - Installare l'aggiornamento - Ricordami più tardi - Aggiornamento riuscito - La versione non IFO di Edge è stata aggiornata con successo. - Creazione riuscita - La versione non IFO di Edge è stata creata con successo. - - + + Installatore GoAwayEdge + Avanti + Indietro + Uscita + + No + + Benvenuti + Il programma di installazione eseguirà tutte le operazioni necessarie per installare GoAwayEdge sul sistema. Dopo l'installazione, tutte le chiamate a Edge verranno reindirizzate al browser. Selezionare l'opzione desiderata per continuare. + Installare + Installare e configurare GoAwayEdge sul sistema. + Disinstallare + Disinstallare GoAwayEdge e ripristinare la funzionalità di Edge. + Utilizzare il programma di installazione per disinstallare GoAwayEdge. + + Licenza + Leggere la seguente licenza. È necessario accettare i termini della licenza prima di continuare l'installazione. + Accetto questa licenza. + Rifiuto questa licenza. + + Impostazioni + Canale dei bordi + Selezionare il canale Microsoft Edge installato. + Motore di ricerca + Selezionate il vostro motore di ricerca preferito. + Personalizzato + Motore di ricerca personalizzato + Inserire l'URL della query dal motore di ricerca. + Rimuovere Microsoft Edge (Stabile) + Rimuovere completamente Microsoft Edge dal sistema. + + Installazione in corso ... + Attendere il completamento dell'installazione. + + Installazione completata! + È sufficiente aprire questo programma di installazione per personalizzare nuovamente GoAwayEdge. + Disinstallazione completata! + GoAwayEdge è stato rimosso con successo dal sistema. + Donazione tramite PayPal + + Inizializzazione fallita: {0} + Installazione fallita: {0} + Disinstallazione fallita: {0} + Aggiornamento fallito: {0} + Installazione fallita! Riprovare. + La rimozione di Microsoft Edge non è riuscita! Riprovare. + Impossibile registrare l'opzione di esecuzione del file immagine per '{0}'. Riprovare. + È disponibile una nuova versione di GoAwayEdge (v{0}). Questo aggiornamento include nuove caratteristiche, correzioni di bug e garantisce la funzionalità di questa applicazione. + Microsoft Edge è stato aggiornato e GoAwayEdge deve aggiornare il file non-IFEO per garantire la funzionalità di Edge. + La versione non IFO di Edge è mancante e deve essere copiata per garantire la funzionalità di Edge. Copiare ora? + Installare l'aggiornamento + Ricordami più tardi + Aggiornamento riuscito + La versione non IFO di Edge è stata aggiornata con successo. + Creazione riuscita + La versione non IFO di Edge è stata creata con successo. + Salta questa versione + diff --git a/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml b/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml index 3a835c7..e86f0bd 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml @@ -1,66 +1,59 @@ - - - GoAwayEdge 설치 관리자 - 다음 - 뒤로 - 종료 - - 아니요 - - - 환영 - 설치 관리자가 시스템에 GoAwayEdge를 설치하는 데 필요한 모든 단계를 수행합니다. 설치가 완료되면 모든 Edge 호출이 브라우저로 리디렉션됩니다. 계속하려면 원하는 옵션을 선택하세요. - 설치 - 시스템에 GoAwayEdge를 설치하고 구성합니다. - 설치 제거 - GoAwayEdge를 제거하고 Edge 기능을 복원합니다. - GoAwayEdge를 제거하려면 설치 관리자를 사용하세요. - - - 라이선스 - 다음 라이센스를 읽어 보십시오. 설치를 계속하기 전에 라이선스 조건에 동의해야 합니다. - 이 라이선스에 동의합니다. - 이 라이선스를 거부합니다. - - - 설정 - Edge 채널 - 설치된 Microsoft Edge 채널을 선택합니다. - 검색 엔진 - 선호하는 검색 엔진을 선택합니다. - 사용자 지정 - 사용자 지정 검색 엔진 - 검색 엔진에서 쿼리 URL을 입력하세요. - Microsoft Edge 제거(안정) - 시스템에서 Microsoft Edge를 완전히 제거합니다. - - - 설치 진행 중 ... - 설치가 완료될 때까지 기다려주세요. - - - 설치 완료! - GoAwayEdge를 다시 사용자 지정하려면 이 설치 관리자를 열기만 하면 됩니다. - 제거 완료! - GoAwayEdge가 시스템에서 성공적으로 제거되었습니다. - PayPal로 기부하기 - - - 초기화 실패: {0} - 설치 실패: {0} - 제거 실패: {0} - 업데이트 실패: {0} - 설치에 실패했습니다! 다시 시도하세요. - Microsoft Edge를 제거하지 못했습니다! 다시 시도하세요. - '{0}'에 대한 이미지 파일 실행 옵션을 등록하지 못했습니다. 다시 시도해 주세요. - GoAwayEdge의 새 버전(v{0}) 을 사용할 수 있습니다. 이 업데이트에는 새로운 기능과 버그 수정이 포함되어 있으며 이 애플리케이션의 기능을 보장합니다. - Microsoft Edge가 업데이트되었으며 GoAwayEdge는 비IFEO 파일을 업데이트하여 Edge 기능을 보장해야 합니다. - 비 IEFO 버전의 Edge가 누락되었으므로 Edge 기능을 보장하려면 복사해야 합니다. 지금 복사하시겠습니까? - 업데이트 설치 - 나중에 알림 - 업데이트 성공 - Edge의 대체 시작 파일이 성공적으로 업데이트되었습니다. - 생성 성공 - Edge의 대체 시작 파일이 성공적으로 생성되었습니다. - - + + GoAwayEdge 설치 관리자 + 다음 + 뒤로 + 종료 + + 아니요 + + 환영 + 설치 관리자가 시스템에 GoAwayEdge를 설치하는 데 필요한 모든 단계를 수행합니다. 설치가 완료되면 모든 Edge 호출이 브라우저로 리디렉션됩니다. 계속하려면 원하는 옵션을 선택하세요. + 설치 + 시스템에 GoAwayEdge를 설치하고 구성합니다. + 설치 제거 + GoAwayEdge를 제거하고 Edge 기능을 복원합니다. + GoAwayEdge를 제거하려면 설치 관리자를 사용하세요. + + 라이선스 + 다음 라이센스를 읽어 보십시오. 설치를 계속하기 전에 라이선스 조건에 동의해야 합니다. + 이 라이선스에 동의합니다. + 이 라이선스를 거부합니다. + + 설정 + Edge 채널 + 설치된 Microsoft Edge 채널을 선택합니다. + 검색 엔진 + 선호하는 검색 엔진을 선택합니다. + 사용자 지정 + 사용자 지정 검색 엔진 + 검색 엔진에서 쿼리 URL을 입력하세요. + Microsoft Edge 제거(안정) + 시스템에서 Microsoft Edge를 완전히 제거합니다. + + 설치 진행 중 ... + 설치가 완료될 때까지 기다려주세요. + + 설치 완료! + GoAwayEdge를 다시 사용자 지정하려면 이 설치 관리자를 열기만 하면 됩니다. + 제거 완료! + GoAwayEdge가 시스템에서 성공적으로 제거되었습니다. + PayPal로 기부하기 + + 초기화 실패: {0} + 설치 실패: {0} + 제거 실패: {0} + 업데이트 실패: {0} + 설치에 실패했습니다! 다시 시도하세요. + Microsoft Edge를 제거하지 못했습니다! 다시 시도하세요. + '{0}'에 대한 이미지 파일 실행 옵션을 등록하지 못했습니다. 다시 시도해 주세요. + GoAwayEdge의 새 버전(v{0}) 을 사용할 수 있습니다. 이 업데이트에는 새로운 기능과 버그 수정이 포함되어 있으며 이 애플리케이션의 기능을 보장합니다. + Microsoft Edge가 업데이트되었으며 GoAwayEdge는 비IFEO 파일을 업데이트하여 Edge 기능을 보장해야 합니다. + 비 IEFO 버전의 Edge가 누락되었으므로 Edge 기능을 보장하려면 복사해야 합니다. 지금 복사하시겠습니까? + 업데이트 설치 + 나중에 알림 + 업데이트 성공 + Edge의 대체 시작 파일이 성공적으로 업데이트되었습니다. + 생성 성공 + Edge의 대체 시작 파일이 성공적으로 생성되었습니다. + 이 버전 건너뛰기 + diff --git a/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml b/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml index fbf0549..2983743 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml @@ -1,66 +1,59 @@ - - - GoAwayEdge Installer - Następny - Powrót - Wyjście - Tak - Nie - - - Witamy - Instalator wykona wszystkie niezbędne kroki, aby zainstalować GoAwayEdge w systemie. Po instalacji wszystkie połączenia Edge zostaną przekierowane do przeglądarki. Wybierz żądaną opcję, aby kontynuować. - Instalacja - Zainstaluj i skonfiguruj GoAwayEdge w swoim systemie. - Odinstaluj - Odinstaluj GoAwayEdge i przywróć funkcjonalność Edge. - Użyj Instalatora, aby odinstalować GoAwayEdge. - - - Licencja - Prosimy o zapoznanie się z poniższą licencją. Przed kontynuowaniem instalacji należy zaakceptować warunki licencji. - Akceptuję tę licencję. - Odrzucam tę licencję. - - - Ustawienia - Kanał krawędziowy - Wybierz zainstalowany kanał Microsoft Edge. - Wyszukiwarka - Wybierz swoją ulubioną wyszukiwarkę. - Niestandardowe - Niestandardowa wyszukiwarka - Wprowadź adres URL zapytania z wyszukiwarki. - Usuń Microsoft Edge (stabilny) - Całkowicie usuń Microsoft Edge z systemu. - - - Instalacja w toku ... - Poczekaj na zakończenie instalacji. - - - Instalacja zakończona! - Po prostu otwórz ten instalator, jeśli chcesz ponownie dostosować GoAwayEdge. - Dezinstalacja zakończona! - GoAwayEdge został pomyślnie usunięty z systemu. - Przekaż darowiznę przez PayPal - - - Inicjalizacja nie powiodła się: {0} - Instalacja nie powiodła się: {0} - Deinstalacja nie powiodła się: {0} - Aktualizacja nie powiodła się: {0} - Instalacja nie powiodła się! Spróbuj ponownie. - Usunięcie Microsoft Edge nie powiodło się! Spróbuj ponownie. - Nie udało się zarejestrować opcji wykonania pliku obrazu dla '{0}'. Spróbuj ponownie. - Dostępna jest nowa wersja GoAwayEdge (v{0}). Ta aktualizacja zawiera nowe funkcje, poprawki błędów i zapewnia funkcjonalność tej aplikacji. - Microsoft Edge został zaktualizowany i GoAwayEdge musi zaktualizować plik non-IFEO, aby zapewnić jego funkcjonalność. - Brakuje wersji Edge innej niż IEFO i należy ją skopiować, aby zapewnić funkcjonalność Edge. Skopiować teraz? - Zainstaluj aktualizację - Przypomnij mi później - Aktualizacja zakończona sukcesem - Wersja Edge inna niż IEFO została pomyślnie zaktualizowana. - Tworzenie zakończone sukcesem - Wersja Edge bez IFO została pomyślnie utworzona. - - + + GoAwayEdge Installer + Następny + Powrót + Wyjście + Tak + Nie + + Witamy + Instalator wykona wszystkie niezbędne kroki, aby zainstalować GoAwayEdge w systemie. Po instalacji wszystkie połączenia Edge zostaną przekierowane do przeglądarki. Wybierz żądaną opcję, aby kontynuować. + Instalacja + Zainstaluj i skonfiguruj GoAwayEdge w swoim systemie. + Odinstaluj + Odinstaluj GoAwayEdge i przywróć funkcjonalność Edge. + Użyj Instalatora, aby odinstalować GoAwayEdge. + + Licencja + Prosimy o zapoznanie się z poniższą licencją. Przed kontynuowaniem instalacji należy zaakceptować warunki licencji. + Akceptuję tę licencję. + Odrzucam tę licencję. + + Ustawienia + Kanał krawędziowy + Wybierz zainstalowany kanał Microsoft Edge. + Wyszukiwarka + Wybierz swoją ulubioną wyszukiwarkę. + Niestandardowe + Niestandardowa wyszukiwarka + Wprowadź adres URL zapytania z wyszukiwarki. + Usuń Microsoft Edge (stabilny) + Całkowicie usuń Microsoft Edge z systemu. + + Instalacja w toku ... + Poczekaj na zakończenie instalacji. + + Instalacja zakończona! + Po prostu otwórz ten instalator, jeśli chcesz ponownie dostosować GoAwayEdge. + Dezinstalacja zakończona! + GoAwayEdge został pomyślnie usunięty z systemu. + Przekaż darowiznę przez PayPal + + Inicjalizacja nie powiodła się: {0} + Instalacja nie powiodła się: {0} + Deinstalacja nie powiodła się: {0} + Aktualizacja nie powiodła się: {0} + Instalacja nie powiodła się! Spróbuj ponownie. + Usunięcie Microsoft Edge nie powiodło się! Spróbuj ponownie. + Nie udało się zarejestrować opcji wykonania pliku obrazu dla '{0}'. Spróbuj ponownie. + Dostępna jest nowa wersja GoAwayEdge (v{0}). Ta aktualizacja zawiera nowe funkcje, poprawki błędów i zapewnia funkcjonalność tej aplikacji. + Microsoft Edge został zaktualizowany i GoAwayEdge musi zaktualizować plik non-IFEO, aby zapewnić jego funkcjonalność. + Brakuje wersji Edge innej niż IEFO i należy ją skopiować, aby zapewnić funkcjonalność Edge. Skopiować teraz? + Zainstaluj aktualizację + Przypomnij mi później + Aktualizacja zakończona sukcesem + Wersja Edge inna niż IEFO została pomyślnie zaktualizowana. + Tworzenie zakończone sukcesem + Wersja Edge bez IFO została pomyślnie utworzona. + Pomiń tę wersję + From 52396ba4135041fc2e9d09b1453b15f35220cbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 31 Jul 2024 00:33:26 +0200 Subject: [PATCH 09/80] Added ResourceDictionary (pt-BR) to LocalizationManager --- GoAwayEdge/Common/Localization.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GoAwayEdge/Common/Localization.cs b/GoAwayEdge/Common/Localization.cs index 89b5a43..28154ca 100644 --- a/GoAwayEdge/Common/Localization.cs +++ b/GoAwayEdge/Common/Localization.cs @@ -8,7 +8,7 @@ internal class LocalizationManager public static void LoadLanguage() { // Set current language model - const string overrideLanguage = "duh"; + const string overrideLanguage = ""; var language = Thread.CurrentThread.CurrentCulture.ToString(); var dict = new ResourceDictionary(); @@ -23,6 +23,7 @@ public static void LoadLanguage() "it-IT" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.it-IT.xaml", UriKind.Relative), "pl-PL" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.pl-PL.xaml", UriKind.Relative), "ko-KR" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.ko-KR.xaml", UriKind.Relative), + "pt-BR" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.pt-BR.xaml", UriKind.Relative), _ => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.xaml", UriKind.Relative) }; try From 86a8d16e2b87f45b4c013e3eb7a806ad97e3425f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 1 Aug 2024 23:32:45 +0200 Subject: [PATCH 10/80] edge settings page --- GoAwayEdge/App.xaml.cs | 10 ++- .../Common/Installation/InstallRoutine.cs | 1 + GoAwayEdge/GoAwayEdge.csproj.user | 6 ++ .../ControlPanel/ControlPanel.xaml | 2 +- .../ControlPanel/ControlPanel.xaml.cs | 2 + .../ControlPanel/Pages/EdgeSettings.xaml | 88 +++++++++++++++++++ .../ControlPanel/Pages/EdgeSettings.xaml.cs | 15 ++++ .../ControlPanel/Pages/HomeScreen.xaml | 2 +- .../ControlPanel/Pages/HomeScreen.xaml.cs | 9 +- 9 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml create mode 100644 GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 5c29a7a..da7a177 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -26,7 +26,6 @@ namespace GoAwayEdge public partial class App { public static bool IsDebug = false; - private static string? _url; public void Application_Startup(object sender, StartupEventArgs e) { @@ -65,10 +64,19 @@ public void Application_Startup(object sender, StartupEventArgs e) } else if (args.Length > 0) { + if (args.Contains("--debug")) + IsDebug = true; if (args.Contains("-ToastActivated")) // Clicked on notification, ignore it. Environment.Exit(0); if (args.Contains("--control-panel")) { + // Check if user allowed opening the control panel + if (RegistryConfig.GetKey("ControlPanelIsInstalled") != "True") + { + Logging.Log("Control Panel is not allowed on this system, exiting ...", Logging.LogLevel.ERROR); + Environment.Exit(0); + return; + } var controlCenter = new UserInterface.ControlPanel.ControlPanel(); controlCenter.ShowDialog(); Environment.Exit(0); diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index d1d8a3c..b40c846 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -200,6 +200,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Microsoft", "Windows", "Start Menu", "Programs", "GoAwayEdge.lnk"); Shortcut.Create(Path.Combine(Configuration.InstallDir, "GoAwayEdge.exe"), "--control-panel", shortcutPath); + RegistryConfig.SetKey("ControlPanelIsInstalled", true); } // Switch FrameWindow content to InstallationSuccess diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index aef9ad6..83a95aa 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -10,6 +10,9 @@ Code + + Code + Code @@ -51,6 +54,9 @@ Designer + + Designer + Designer diff --git a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml index 521b5bb..8de6e9d 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml @@ -34,7 +34,7 @@ - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs index b99b4c3..c44d009 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml.cs @@ -1,3 +1,4 @@ +using GoAwayEdge.UserInterface.ControlPanel.Pages; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -18,6 +19,7 @@ public partial class ControlPanel { Interval = TimeSpan.FromSeconds(1) }; + public static ControlPanel? ContentWindow; public ControlPanel() { diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml new file mode 100644 index 0000000..ea10420 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs new file mode 100644 index 0000000..970dbd0 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace GoAwayEdge.UserInterface.ControlPanel.Pages +{ + /// + /// Interaktionslogik für EdgeSettings.xaml + /// + public partial class EdgeSettings : Page + { + public EdgeSettings() + { + InitializeComponent(); + } + } +} diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml index 2f1b591..ac80f15 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml @@ -18,7 +18,7 @@ HorizontalAlignment="Center" Margin="0,0,0,15"/> - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs index 18245bd..c473456 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs @@ -1,15 +1,20 @@ -using System.Windows.Controls; +using System.Windows; namespace GoAwayEdge.UserInterface.ControlPanel.Pages { /// /// Interaktionslogik für HomeScreen.xaml /// - public partial class HomeScreen : Page + public partial class HomeScreen { public HomeScreen() { InitializeComponent(); } + + private void EdgeSettings_OnClick(object sender, RoutedEventArgs e) + { + (Application.Current.MainWindow as ControlPanel)?.RootNavigation.Navigate(typeof(EdgeSettings)); + } } } From 80e3a16677026137f6564a79ea2328126aa2b0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sun, 4 Aug 2024 15:33:31 +0200 Subject: [PATCH 11/80] Added Power options --- GoAwayEdge/App.xaml.cs | 36 +---- GoAwayEdge/Common/Configuration.cs | 61 +++++++- .../Common/Installation/InstallRoutine.cs | 3 + GoAwayEdge/Common/Runtime/ArgumentParse.cs | 34 ++++ .../Localization/ResourceDictionary.xaml | 16 ++ .../ControlPanel/ControlPanel.xaml | 8 +- .../ControlPanel/Pages/EdgeSettings.xaml | 28 +++- .../ControlPanel/Pages/EdgeSettings.xaml.cs | 147 +++++++++++++++++- .../ControlPanel/Pages/HomeScreen.xaml | 22 ++- .../Setup/Pages/Settings.xaml.cs | 34 +--- 10 files changed, 314 insertions(+), 75 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index da7a177..acd75e2 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -77,6 +77,8 @@ public void Application_Startup(object sender, StartupEventArgs e) Environment.Exit(0); return; } + + Configuration.InitialEnvironment(); var controlCenter = new UserInterface.ControlPanel.ControlPanel(); controlCenter.ShowDialog(); Environment.Exit(0); @@ -86,7 +88,7 @@ public void Application_Startup(object sender, StartupEventArgs e) foreach (var arg in args) { if (arg.StartsWith("-se:")) - Configuration.Search = ParseSearchEngine(arg); + Configuration.Search = ArgumentParse.ParseSearchEngine(arg); if (arg.Contains("--url:")) { Configuration.CustomQueryUrl = ParseCustomSearchEngine(arg); @@ -230,15 +232,6 @@ public void Application_Startup(object sender, StartupEventArgs e) } Configuration.InitialEnvironment(); - try - { - Configuration.Search = ParseSearchEngine(RegistryConfig.GetKey("SearchEngine")); - } - catch - { - // ignored - } - ArgumentParse.Parse(args); Environment.Exit(0); } @@ -250,29 +243,6 @@ public void Application_Startup(object sender, StartupEventArgs e) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); return result ? argParsed : null; } - - private static SearchEngine ParseSearchEngine(string argument) - { - var arg = argument; - if (argument.StartsWith("-se:")) - arg = argument.Remove(0, 4); - - return arg.ToLower() switch - { - "google" => SearchEngine.Google, - "bing" => SearchEngine.Bing, - "duckduckgo" => SearchEngine.DuckDuckGo, - "yahoo" => SearchEngine.Yahoo, - "yandex" => SearchEngine.Yandex, - "ecosia" => SearchEngine.Ecosia, - "ask" => SearchEngine.Ask, - "qwant" => SearchEngine.Qwant, - "perplexity" => SearchEngine.Perplexity, - "custom" => SearchEngine.Custom, - _ => SearchEngine.Google // Fallback search engine - }; - } - private static bool IsAdministrator() { var identity = WindowsIdentity.GetCurrent(); diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 1b26536..250f958 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,9 +1,10 @@ using System.IO; +using System.Windows; using Microsoft.Win32; namespace GoAwayEdge.Common { - internal enum SearchEngine + public enum SearchEngine { Google, Bing, @@ -17,7 +18,7 @@ internal enum SearchEngine Custom } - internal enum EdgeChannel + public enum EdgeChannel { Stable, Beta, @@ -60,6 +61,20 @@ public static bool InitialEnvironment() FileConfiguration.EdgePath = RegistryConfig.GetKey("EdgeFilePath"); FileConfiguration.NonIfeoPath = RegistryConfig.GetKey("EdgeNonIEFOFilePath"); + + try + { + Channel = Runtime.ArgumentParse.ParseEdgeChannel(RegistryConfig.GetKey("Stable")); + Search = Runtime.ArgumentParse.ParseSearchEngine(RegistryConfig.GetKey("SearchEngine")); + if (Search == SearchEngine.Custom) + { + CustomQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); + } + } + catch + { + // ignored + } return true; } catch (Exception ex) @@ -70,6 +85,46 @@ public static bool InitialEnvironment() return false; } } + + /// + /// Get a list of all available Edge Channels. + /// + /// + /// List of Edge Channels. + /// + public static List GetEdgeChannels() + { + var list = (from edgeChannel in (EdgeChannel[])Enum.GetValues(typeof(EdgeChannel)) + select edgeChannel.ToString()).ToList(); + return list; + } + + + /// + /// Get a list of all available Search Engines. + /// + /// + /// List of Search Engines. + /// + public static List GetSearchEngines() + { + var list = (from searchEngine in (SearchEngine[])Enum.GetValues(typeof(SearchEngine)) + where searchEngine != SearchEngine.Custom + select searchEngine.ToString()).ToList(); + + try + { + var resourceValue = + (string)Application.Current.MainWindow!.FindResource("SettingsSearchEngineCustomItem"); + list.Add(!string.IsNullOrEmpty(resourceValue) ? resourceValue : "Custom"); + } + catch + { + list.Add("Custom"); + } + + return list; + } } internal enum ModifyAction @@ -95,6 +150,8 @@ public class RegistryConfig /// /// Create a Key in the Registry /// + /// Name of key + /// Value of key /// Type of value /// Use the Uninstall Registry key instead. public static void SetKey(string option, object value, RegistryValueKind valueKind = RegistryValueKind.String, bool isUninstall = false) diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index b40c846..afee731 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -203,6 +203,9 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) RegistryConfig.SetKey("ControlPanelIsInstalled", true); } + // Set enable flag + RegistryConfig.SetKey("Enabled", true); + // Switch FrameWindow content to InstallationSuccess worker?.ReportProgress(100, ""); Logging.Log("Installation finished."); diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 5460cb0..63ad0a6 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -139,5 +139,39 @@ private static void StartProcess(string fileName, string arguments, string debug DebugMessage.DisplayDebugMessage("GoAwayEdge", debugMessage); p.Start(); } + + public static EdgeChannel ParseEdgeChannel(string argument) + { + return argument.ToLower() switch + { + "stable" => EdgeChannel.Stable, + "beta" => EdgeChannel.Beta, + "dev" => EdgeChannel.Dev, + "canary" => EdgeChannel.Canary, + _ => EdgeChannel.Stable // Fallback channel + }; + } + + public static SearchEngine ParseSearchEngine(string argument) + { + var arg = argument; + if (argument.StartsWith("-se:")) + arg = argument.Remove(0, 4); + + return arg.ToLower() switch + { + "google" => SearchEngine.Google, + "bing" => SearchEngine.Bing, + "duckduckgo" => SearchEngine.DuckDuckGo, + "yahoo" => SearchEngine.Yahoo, + "yandex" => SearchEngine.Yandex, + "ecosia" => SearchEngine.Ecosia, + "ask" => SearchEngine.Ask, + "qwant" => SearchEngine.Qwant, + "perplexity" => SearchEngine.Perplexity, + "custom" => SearchEngine.Custom, + _ => SearchEngine.Google // Fallback search engine + }; + } } } diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 017a4ce..83a4505 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -48,6 +48,18 @@ GoAwayEdge has been successfully removed from the system. Donate via PayPal + + GoAwayEdge Control Panel + Welcome to GoAwayEdge + Microsoft Edge + Windows Copilot + Manage Search Engines and more. + Manage Hotkeys and more. + Enable/Disable GoAwayEdge + Deactivate the forwarding of search queries to other browsers. + Enable GoAwayEdge + Disable GoAwayEdge + Initialization failed: {0} Installation failed: {0} @@ -66,5 +78,9 @@ The alternative startup file of Edge has been successfully updated. Creation successful The alternative startup file of Edge has been successfully created. + GoAwayEdge was successfully enabled on this system. + GoAwayEdge was successfully disabled on this system. + Could not enable GoAwayEdge on this system: {0} + Could not disable GoAwayEdge on this system: {0} \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml index 8de6e9d..f4d06f8 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:GoAwayEdge" mc:Ignorable="d" - Title="GoAwayEdge Control Panel" Height="620" Width="800" + Title="{DynamicResource ControlPanelTitle}" Height="620" Width="800" MinHeight="620" MinWidth="800" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:pages="clr-namespace:GoAwayEdge.UserInterface.ControlPanel.Pages" @@ -118,7 +118,7 @@ @@ -127,8 +127,8 @@ - + - \ No newline at end of file + \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml index ea10420..cf4fdc1 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml @@ -30,7 +30,7 @@ Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{DynamicResource SettingsEdgeChannelDescription}" /> - + @@ -54,7 +54,7 @@ Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{DynamicResource SettingsSearchEngineDescription}" /> - + @@ -83,6 +83,30 @@ + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs index 970dbd0..2594cd2 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs @@ -1,15 +1,158 @@ -using System.Windows.Controls; +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using GoAwayEdge.Common; namespace GoAwayEdge.UserInterface.ControlPanel.Pages { /// /// Interaktionslogik für EdgeSettings.xaml /// - public partial class EdgeSettings : Page + public partial class EdgeSettings { + private bool _appIsEnabled; + public EdgeSettings() { InitializeComponent(); + + foreach (var edgeChannels in Configuration.GetEdgeChannels()) + { + EdgeChannelBox.Items.Add(edgeChannels); + } + EdgeChannelBox.SelectedItem = Configuration.Channel.ToString(); + + foreach (var searchEngine in Configuration.GetSearchEngines()) + { + SearchEngineBox.Items.Add(searchEngine); + } + + SearchEngineBox.SelectedItem = Configuration.Search.ToString(); + if (Configuration.CustomQueryUrl != null) QueryUrlTextBox.Text = Configuration.CustomQueryUrl; + + if (RegistryConfig.GetKey("Enabled") == "True") + { + _appIsEnabled = true; + PowerToggle.Content = "Disable GoAwayEdge"; + } + else + { + _appIsEnabled = false; + PowerToggle.Content = "Enable GoAwayEdge"; + } + } + + private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + switch (SearchEngineBox.SelectedIndex) + { + case 0: + Configuration.Search = SearchEngine.Google; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 1: + Configuration.Search = SearchEngine.Bing; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 2: + Configuration.Search = SearchEngine.DuckDuckGo; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 3: + Configuration.Search = SearchEngine.Yahoo; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 4: + Configuration.Search = SearchEngine.Yandex; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 5: + Configuration.Search = SearchEngine.Ecosia; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 6: + Configuration.Search = SearchEngine.Ask; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 7: + Configuration.Search = SearchEngine.Qwant; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 8: + Configuration.Search = SearchEngine.Perplexity; + CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + break; + case 9: + Configuration.Search = SearchEngine.Custom; + CustomSearchPanel.Visibility = System.Windows.Visibility.Visible; + if (string.IsNullOrEmpty(Configuration.CustomQueryUrl)) + Debug.WriteLine("placeholder"); + break; + } + } + + private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + Configuration.Channel = EdgeChannelBox.SelectedIndex switch + { + 0 => EdgeChannel.Stable, + 1 => EdgeChannel.Beta, + 2 => EdgeChannel.Dev, + 3 => EdgeChannel.Canary, + _ => EdgeChannel.Stable + }; + } + + private void PowerToggle_OnClick(object sender, RoutedEventArgs e) + { + if (_appIsEnabled) + { + try + { + RegistryConfig.SetKey("Enabled", "False"); + _appIsEnabled = false; + PowerToggle.Content = LocalizationManager.LocalizeValue("ControlPanelEdgePowerEnable"); + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("MessageGoAwayEdgeDisabled"); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + } + catch (Exception ex) + { + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("FailedSetAppDisabled", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + } + } + else + { + try + { + RegistryConfig.SetKey("Enabled", "True"); + _appIsEnabled = true; + PowerToggle.Content = LocalizationManager.LocalizeValue("ControlPanelEdgePowerDisable"); + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("MessageGoAwayEdgeEnabled"); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + } + catch (Exception ex) + { + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("FailedSetAppEnabled", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + } + } } } } diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml index ac80f15..f0881f2 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml @@ -12,7 +12,7 @@ @@ -26,8 +26,14 @@ - - + + @@ -40,8 +46,14 @@ - - + + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index 90a8a69..00f57c7 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -13,35 +13,17 @@ public Settings() { InitializeComponent(); - EdgeChannelBox.Items.Add("Edge Stable"); - EdgeChannelBox.Items.Add("Edge Beta"); - EdgeChannelBox.Items.Add("Edge Dev"); - EdgeChannelBox.Items.Add("Edge Canary"); - EdgeChannelBox.SelectedIndex = 0; - Configuration.Channel = EdgeChannel.Stable; - - SearchEngineBox.Items.Add("Google"); - SearchEngineBox.Items.Add("Bing"); - SearchEngineBox.Items.Add("DuckDuckGo"); - SearchEngineBox.Items.Add("Yahoo"); - SearchEngineBox.Items.Add("Yandex"); - SearchEngineBox.Items.Add("Ecosia"); - SearchEngineBox.Items.Add("Ask"); - SearchEngineBox.Items.Add("Qwant"); - SearchEngineBox.Items.Add("Perplexity"); - - try + foreach (var edgeChannels in Configuration.GetEdgeChannels()) { - Dispatcher.Invoke(() => - { - var resourceValue = (string)Application.Current.MainWindow!.FindResource("SettingsSearchEngineCustomItem"); - SearchEngineBox.Items.Add(!string.IsNullOrEmpty(resourceValue) ? resourceValue : "Custom"); - }); + EdgeChannelBox.Items.Add(edgeChannels); } - catch + EdgeChannelBox.SelectedItem = Configuration.Channel.ToString(); + + foreach (var searchEngine in Configuration.GetSearchEngines()) { - SearchEngineBox.Items.Add("Custom"); + SearchEngineBox.Items.Add(searchEngine); } + SearchEngineBox.SelectedItem = Configuration.Search.ToString(); if (Configuration.NoEdgeInstalled) { @@ -49,8 +31,6 @@ public Settings() EdgeStackPanel.IsEnabled = false; } - SearchEngineBox.SelectedIndex = 0; - Configuration.Search = SearchEngine.Google; Configuration.Uninstall = false; Configuration.InstallControlPanel = true; ControlPanelSwitch.IsChecked = true; From ae3ae479e46677d658ad45b6406960da5f6a54af Mon Sep 17 00:00:00 2001 From: Fernanda Bari Date: Tue, 30 Jul 2024 23:14:21 +0000 Subject: [PATCH 12/80] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (53 of 53 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pt_BR/ --- .../Localization/ResourceDictionary.pt-BR.xaml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml index a89736b..d9fce4f 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml @@ -1,14 +1,10 @@ - - + Instalador GoAwayEdge Avançar Voltar Sair Sim Não - Boas-vindas O instalador realizará todos os passos necessários para instalar o GoAwayEdge em seu sistema. Após a instalação, todas as chamadas do Edge serão redirecionadas para o seu navegador. Selecione a opção desejada para continuar. @@ -17,13 +13,11 @@ Desinstalar Desinstale o GoAwayEdge e restaure a funcionalidade do Edge. Por favor, utilize o Instalador para desinstalar o GoAwayEdge. - Licença Por favor, leia a seguinte Licença. Você deve aceitar os termos da licença antes de continuar com a instalação. Aceito esta licença. Recuso esta licença. - Configurações Canal do Edge @@ -35,18 +29,15 @@ Por favor, insira a URL de consulta do mecanismo de busca. Remover o Microsoft Edge (Estável) Remova completamente o Microsoft Edge do sistema. - Instalação em progresso... Aguarde até que a instalação seja concluída. - Instalação concluída! Simplesmente abra este Instalador, se desejar personalizar o GoAwayEdge novamente. Desinstalação concluída! O GoAwayEdge foi removido com sucesso do sistema. Doe via PayPal - Inicialização falhou: {0} Instalação falhou: {0} @@ -65,5 +56,6 @@ O arquivo de inicialização alternativo do Edge foi atualizado com sucesso. Criação bem-sucedida O arquivo de inicialização alternativo do Edge foi criado com sucesso. - + Instalar Painel de Controle + Instalar o Painel de Controle para configurar o GoAwayEdge mais facilmente. From d39ac6964dff71443a8cf3d889b9fd2008873a16 Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 15:31:39 +0000 Subject: [PATCH 13/80] Added translation using Weblate (Danish) --- GoAwayEdge/Localization/ResourceDictionary.da.xaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 GoAwayEdge/Localization/ResourceDictionary.da.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.da.xaml b/GoAwayEdge/Localization/ResourceDictionary.da.xaml new file mode 100644 index 0000000..8e1d2a0 --- /dev/null +++ b/GoAwayEdge/Localization/ResourceDictionary.da.xaml @@ -0,0 +1,5 @@ + + \ No newline at end of file From 76de269d81f23cce27732bb1695ed544009e6a37 Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 15:31:39 +0000 Subject: [PATCH 14/80] Added translation using Weblate (Japanese) --- GoAwayEdge/Localization/ResourceDictionary.ja.xaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 GoAwayEdge/Localization/ResourceDictionary.ja.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.ja.xaml b/GoAwayEdge/Localization/ResourceDictionary.ja.xaml new file mode 100644 index 0000000..8e1d2a0 --- /dev/null +++ b/GoAwayEdge/Localization/ResourceDictionary.ja.xaml @@ -0,0 +1,5 @@ + + \ No newline at end of file From b619d8214299afe436dc57b5baaa1219ebf68ff2 Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 15:31:39 +0000 Subject: [PATCH 15/80] Added translation using Weblate (Dutch) --- GoAwayEdge/Localization/ResourceDictionary.nl.xaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 GoAwayEdge/Localization/ResourceDictionary.nl.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.nl.xaml b/GoAwayEdge/Localization/ResourceDictionary.nl.xaml new file mode 100644 index 0000000..8e1d2a0 --- /dev/null +++ b/GoAwayEdge/Localization/ResourceDictionary.nl.xaml @@ -0,0 +1,5 @@ + + \ No newline at end of file From 9ff04ed831830c467089b198d7eff84311190faf Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 15:31:40 +0000 Subject: [PATCH 16/80] Added translation using Weblate (Portuguese) --- GoAwayEdge/Localization/ResourceDictionary.pt.xaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 GoAwayEdge/Localization/ResourceDictionary.pt.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt.xaml new file mode 100644 index 0000000..8e1d2a0 --- /dev/null +++ b/GoAwayEdge/Localization/ResourceDictionary.pt.xaml @@ -0,0 +1,5 @@ + + \ No newline at end of file From 18ea7a299039c6a134c7540101ee24e2c9e39542 Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 15:31:40 +0000 Subject: [PATCH 17/80] Added translation using Weblate (Romanian) --- GoAwayEdge/Localization/ResourceDictionary.ro.xaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 GoAwayEdge/Localization/ResourceDictionary.ro.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.ro.xaml b/GoAwayEdge/Localization/ResourceDictionary.ro.xaml new file mode 100644 index 0000000..8e1d2a0 --- /dev/null +++ b/GoAwayEdge/Localization/ResourceDictionary.ro.xaml @@ -0,0 +1,5 @@ + + \ No newline at end of file From 6b79ab3b55301685c3ea060b299c7f17e30af52a Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 16:16:38 +0000 Subject: [PATCH 18/80] Translated using Weblate (German) Currently translated at 100.0% (67 of 67 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/de/ --- .../Localization/ResourceDictionary.de-DE.xaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index e23dfd4..69475d2 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -56,4 +56,20 @@ Erstellung erfolgreich Die alternative Startdatei von Edge wurde erfolgreich erstellt. Version überspringen + GoAwayEdge Kontrollpanel + Microsoft Edge + Windows Copilot + Verwalte Suchmaschinen und mehr. + Verwalte Hotkeys und mehr. + Aktiviere/Deaktiviere GoAwayEdge + Aktiviere GoAwayEdge + Deaktiviere GoAwaEdge + GoAwayEdge wurde auf diesem System erfolgreich deaktiviert. + GoAwayEdge konnte auf diesem System nicht aktiviert werden: {0} + Installiere das Kontrollpanel, um GoAwayEdge einfacher zu konfigurieren. + Kontrollpanel installieren + Willkommen bei GoAwayEdge + Deaktiviere die Weiterleitung von Suchanfragen an anderen Browsern. + GoAwayEdge wurde auf diesem System erfolgreich aktiviert. + GoAwayEdge konnte auf diesem System nicht deaktiviert werden: {0} From 1bb09a3a74d0864166218e607c718f1626e7f946 Mon Sep 17 00:00:00 2001 From: valnoxy Date: Sun, 4 Aug 2024 16:25:56 +0000 Subject: [PATCH 19/80] Translated using Weblate (Danish) Currently translated at 100.0% (67 of 67 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/da/ --- .../Localization/ResourceDictionary.da.xaml | 74 +++++++++++++++++-- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.da.xaml b/GoAwayEdge/Localization/ResourceDictionary.da.xaml index 8e1d2a0..76ce337 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.da.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.da.xaml @@ -1,5 +1,69 @@ - - \ No newline at end of file + + Næste + Tilbage + Udgang + Ja + Nej + Velkommen + Installer + Installer og konfigurer GoAwayEdge på dit system. + Afinstaller + Afinstaller GoAwayEdge, og gendan Edge-funktionaliteten. + Brug venligst installationsprogrammet til at afinstallere GoAwayEdge. + Licens + Jeg accepterer denne licens. + Jeg afviser denne licens. + Indstillinger + Kantkanal + Vælg den installerede Microsoft Edge Channel. + Søgemaskine + Vælg din foretrukne søgemaskine. + Brugerdefineret + Brugerdefineret søgemaskine + Indtast venligst forespørgsels-URL'en fra søgemaskinen. + Fjern Microsoft Edge (Stabil) + Installer kontrolpanel + Installer kontrolpanelet for at gøre det nemmere at konfigurere GoAwayEdge. + Installation i gang ... + Vent venligst, indtil installationen er færdig. + Installationen er færdig! + Afinstallation gennemført! + GoAwayEdge er blevet fjernet fra systemet. + Donér via PayPal + GoAwayEdge kontrolpanel + Windows Copilot + Administrer søgemaskiner og meget mere. + Administrer genvejstaster og meget mere. + Aktiver/deaktiver GoAwayEdge + Aktivér GoAwayEdge + Deaktiver GoAwayEdge + Initialisering mislykkedes: {0} + Installationen mislykkedes: {0} + Afinstallation mislykkedes: {0} + Opdatering mislykkedes: {0} + Fjernelsen af Microsoft Edge mislykkedes! Prøv venligst igen. + Kunne ikke registrere Image File Execution Option for '{0}'. Prøv venligst igen. + Microsoft Edge er blevet opdateret, og GoAwayEdge skal opdatere den alternative opstartsfil for at sikre Edge-funktionalitet. + Den alternative opstartsfil til Edge mangler og skal kopieres for at sikre, at Edge fungerer. Kopier nu? + Installer opdatering + Mind mig om det senere + Opdatering vellykket + Oprettelse vellykket + Den alternative opstartsfil for Edge er blevet oprettet. + GoAwayEdge blev aktiveret på dette system. + GoAwayEdge blev deaktiveret på dette system. + GoAwayEdge kunne ikke aktiveres på dette system: {0} + GoAwayEdge-installatør + Installationsprogrammet udfører alle de nødvendige trin for at installere GoAwayEdge på dit system. Efter installationen vil alle Edge-opkald blive omdirigeret til din browser. Vælg den ønskede mulighed for at fortsætte. + Læs venligst den følgende licens. Du skal acceptere licensbetingelserne, før du fortsætter med installationen. + Fjern Microsoft Edge helt fra systemet. + Du skal blot åbne dette installationsprogram, hvis du vil tilpasse GoAwayEdge igen. + Velkommen til GoAwayEdge + Microsoft Edge + Deaktiver videresendelse af søgeforespørgsler til andre browsere. + Installationen mislykkedes! Prøv venligst igen. + En ny version af GoAwayEdge (v{0}) er tilgængelig. Denne opdatering indeholder nye funktioner, fejlrettelser og sikrer applikationens funktionalitet. + Spring denne version over + Den alternative opstartsfil for Edge er blevet opdateret. + Kunne ikke deaktivere GoAwayEdge på dette system: {0} + From 657143a0e513bb1f658bf77e0b5d2cbbdba5aea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sun, 4 Aug 2024 18:29:20 +0200 Subject: [PATCH 20/80] added disable function --- GoAwayEdge/App.xaml.cs | 298 +++++++++++---------- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 9 +- 2 files changed, 162 insertions(+), 145 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index acd75e2..24a6d6c 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -39,63 +39,14 @@ public void Application_Startup(object sender, StartupEventArgs e) LocalizationManager.LoadLanguage(); string[] args = e.Args; - if (args.Length == 0) // Opens Installer + switch (args.Length) { - if (IsAdministrator() == false) + // Opens Installer + case 0: + case 1 when args.Contains("--debug"): { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) - { - var startInfo = new ProcessStartInfo(exeName) - { - Verb = "runas", - UseShellExecute = true - }; - Process.Start(startInfo); - } - Environment.Exit(0); - return; - } - - var installer = new UserInterface.Setup.Installer(); - installer.ShowDialog(); - Environment.Exit(0); - } - else if (args.Length > 0) - { - if (args.Contains("--debug")) - IsDebug = true; - if (args.Contains("-ToastActivated")) // Clicked on notification, ignore it. - Environment.Exit(0); - if (args.Contains("--control-panel")) - { - // Check if user allowed opening the control panel - if (RegistryConfig.GetKey("ControlPanelIsInstalled") != "True") - { - Logging.Log("Control Panel is not allowed on this system, exiting ...", Logging.LogLevel.ERROR); - Environment.Exit(0); - return; - } - - Configuration.InitialEnvironment(); - var controlCenter = new UserInterface.ControlPanel.ControlPanel(); - controlCenter.ShowDialog(); - Environment.Exit(0); - } - if (args.Contains("-s")) // Silent Installation - { - foreach (var arg in args) - { - if (arg.StartsWith("-se:")) - Configuration.Search = ArgumentParse.ParseSearchEngine(arg); - if (arg.Contains("--url:")) - { - Configuration.CustomQueryUrl = ParseCustomSearchEngine(arg); - Configuration.Search = !string.IsNullOrEmpty(Configuration.CustomQueryUrl) ? SearchEngine.Custom : SearchEngine.Google; - } - } - + if (args.Contains("--debug")) + IsDebug = true; if (IsAdministrator() == false) { // Restart program and run as admin @@ -105,8 +56,7 @@ public void Application_Startup(object sender, StartupEventArgs e) var startInfo = new ProcessStartInfo(exeName) { Verb = "runas", - UseShellExecute = true, - Arguments = string.Join(" ", args) + UseShellExecute = true }; Process.Start(startInfo); } @@ -114,120 +64,180 @@ public void Application_Startup(object sender, StartupEventArgs e) return; } - Configuration.InitialEnvironment(); - InstallRoutine.Install(null); + var installer = new UserInterface.Setup.Installer(); + installer.ShowDialog(); Environment.Exit(0); + break; } - if (args.Contains("-u")) + case > 0: { - InstallRoutine.Uninstall(null); - Environment.Exit(0); - } - if (args.Contains("--update")) - { - var statusEnv = Configuration.InitialEnvironment(); - if (statusEnv == false) Environment.Exit(1); - - // Check for app update - var updateAvailable = Updater.CheckForAppUpdate(); - - var updateSkipped = RegistryConfig.GetKey("SkipVersion"); - if (updateAvailable == updateSkipped) + if (args.Contains("--debug")) + IsDebug = true; + if (args.Contains("-ToastActivated")) // Clicked on notification, ignore it. Environment.Exit(0); + if (args.Contains("--control-panel")) + { + // Check if user allowed opening the control panel + if (RegistryConfig.GetKey("ControlPanelIsInstalled") != "True") + { + Logging.Log("Control Panel is not allowed on this system, exiting ...", Logging.LogLevel.ERROR); + Environment.Exit(0); + return; + } - if (!string.IsNullOrEmpty(updateAvailable)) + Configuration.InitialEnvironment(); + var controlCenter = new UserInterface.ControlPanel.ControlPanel(); + controlCenter.ShowDialog(); + Environment.Exit(0); + } + if (args.Contains("-s")) // Silent Installation { - var updateMessage = LocalizationManager.LocalizeValue("NewUpdateAvailable", updateAvailable); - var remindMeLaterBtn = LocalizationManager.LocalizeValue("RemindMeLater"); - var installUpdateBtn = LocalizationManager.LocalizeValue("InstallUpdate"); - var skipUpdateUpdateBtn = LocalizationManager.LocalizeValue("SkipUpdate"); - - var updateDialog = new MessageUi("GoAwayEdge", updateMessage, installUpdateBtn, remindMeLaterBtn, skipUpdateUpdateBtn, true); - updateDialog.ShowDialog(); - switch (updateDialog.Summary) + foreach (var arg in args) { - case "Btn1": + if (arg.StartsWith("-se:")) + Configuration.Search = ArgumentParse.ParseSearchEngine(arg); + if (arg.Contains("--url:")) { - var updateResult = Updater.UpdateClient(); - if (!updateResult) Environment.Exit(0); - break; + Configuration.CustomQueryUrl = ParseCustomSearchEngine(arg); + Configuration.Search = !string.IsNullOrEmpty(Configuration.CustomQueryUrl) ? SearchEngine.Custom : SearchEngine.Google; } - case "Btn3": - RegistryConfig.SetKey("SkipVersion", updateAvailable); - Environment.Exit(0); - break; } - } - // Validate Ifeo binary - var binaryStatus = Updater.ValidateIfeoBinary(); - switch (binaryStatus) - { - case 0: // validated - break; - case 1: // failed validation - if (IsAdministrator() == false) + if (IsAdministrator() == false) + { + // Restart program and run as admin + var exeName = Process.GetCurrentProcess().MainModule?.FileName; + if (exeName != null) { - var updateNonIfeoMessage = LocalizationManager.LocalizeValue("NewNonIfeoUpdate"); - var remindMeLaterBtn = LocalizationManager.LocalizeValue("RemindMeLater"); - var installUpdateBtn = LocalizationManager.LocalizeValue("InstallUpdate"); + var startInfo = new ProcessStartInfo(exeName) + { + Verb = "runas", + UseShellExecute = true, + Arguments = string.Join(" ", args) + }; + Process.Start(startInfo); + } + Environment.Exit(0); + return; + } + + Configuration.InitialEnvironment(); + InstallRoutine.Install(null); + Environment.Exit(0); + } + if (args.Contains("-u")) + { + InstallRoutine.Uninstall(null); + Environment.Exit(0); + } + if (args.Contains("--update")) + { + var statusEnv = Configuration.InitialEnvironment(); + if (statusEnv == false) Environment.Exit(1); + + // Check for app update + var updateAvailable = Updater.CheckForAppUpdate(); - var ifeoMessageUi = new MessageUi("GoAwayEdge", updateNonIfeoMessage, installUpdateBtn, remindMeLaterBtn); - ifeoMessageUi.ShowDialog(); + var updateSkipped = RegistryConfig.GetKey("SkipVersion"); + if (updateAvailable == updateSkipped) + Environment.Exit(0); + + if (!string.IsNullOrEmpty(updateAvailable)) + { + var updateMessage = LocalizationManager.LocalizeValue("NewUpdateAvailable", updateAvailable); + var remindMeLaterBtn = LocalizationManager.LocalizeValue("RemindMeLater"); + var installUpdateBtn = LocalizationManager.LocalizeValue("InstallUpdate"); + var skipUpdateUpdateBtn = LocalizationManager.LocalizeValue("SkipUpdate"); + + var updateDialog = new MessageUi("GoAwayEdge", updateMessage, installUpdateBtn, remindMeLaterBtn, skipUpdateUpdateBtn, true); + updateDialog.ShowDialog(); + switch (updateDialog.Summary) + { + case "Btn1": + { + var updateResult = Updater.UpdateClient(); + if (!updateResult) Environment.Exit(0); + break; + } + case "Btn3": + RegistryConfig.SetKey("SkipVersion", updateAvailable); + Environment.Exit(0); + break; + } + } - if (ifeoMessageUi.Summary == "Btn1") + // Validate Ifeo binary + var binaryStatus = Updater.ValidateIfeoBinary(); + switch (binaryStatus) + { + case 0: // validated + break; + case 1: // failed validation + if (IsAdministrator() == false) { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) + var updateNonIfeoMessage = LocalizationManager.LocalizeValue("NewNonIfeoUpdate"); + var remindMeLaterBtn = LocalizationManager.LocalizeValue("RemindMeLater"); + var installUpdateBtn = LocalizationManager.LocalizeValue("InstallUpdate"); + + var ifeoMessageUi = new MessageUi("GoAwayEdge", updateNonIfeoMessage, installUpdateBtn, remindMeLaterBtn); + ifeoMessageUi.ShowDialog(); + + if (ifeoMessageUi.Summary == "Btn1") { - var startInfo = new ProcessStartInfo(exeName) + // Restart program and run as admin + var exeName = Process.GetCurrentProcess().MainModule?.FileName; + if (exeName != null) { - Verb = "runas", - UseShellExecute = true, - Arguments = "--update" - }; - Process.Start(startInfo); + var startInfo = new ProcessStartInfo(exeName) + { + Verb = "runas", + UseShellExecute = true, + Arguments = "--update" + }; + Process.Start(startInfo); + } + Environment.Exit(0); + return; } Environment.Exit(0); - return; } - Environment.Exit(0); - } - Updater.ModifyIfeoBinary(ModifyAction.Update); - break; - case 2: // missing - if (IsAdministrator() == false) - { - var ifeoMissingMessage = LocalizationManager.LocalizeValue("MissingIfeoFile"); - var yesBtn = LocalizationManager.LocalizeValue("Yes"); - var noBtn = LocalizationManager.LocalizeValue("No"); - var ifeoMessageUi = new MessageUi("GoAwayEdge", ifeoMissingMessage, yesBtn, noBtn); - ifeoMessageUi.ShowDialog(); - - if (ifeoMessageUi.Summary == "Btn1") + Updater.ModifyIfeoBinary(ModifyAction.Update); + break; + case 2: // missing + if (IsAdministrator() == false) { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) + var ifeoMissingMessage = LocalizationManager.LocalizeValue("MissingIfeoFile"); + var yesBtn = LocalizationManager.LocalizeValue("Yes"); + var noBtn = LocalizationManager.LocalizeValue("No"); + var ifeoMessageUi = new MessageUi("GoAwayEdge", ifeoMissingMessage, yesBtn, noBtn); + ifeoMessageUi.ShowDialog(); + + if (ifeoMessageUi.Summary == "Btn1") { - var startInfo = new ProcessStartInfo(exeName) + // Restart program and run as admin + var exeName = Process.GetCurrentProcess().MainModule?.FileName; + if (exeName != null) { - Verb = "runas", - UseShellExecute = true, - Arguments = "--update" - }; - Process.Start(startInfo); + var startInfo = new ProcessStartInfo(exeName) + { + Verb = "runas", + UseShellExecute = true, + Arguments = "--update" + }; + Process.Start(startInfo); + } + Environment.Exit(0); + return; } Environment.Exit(0); - return; } - Environment.Exit(0); - } - Updater.ModifyIfeoBinary(ModifyAction.Create); - break; + Updater.ModifyIfeoBinary(ModifyAction.Create); + break; + } + Environment.Exit(0); } - Environment.Exit(0); + + break; } } diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 63ad0a6..c6f1c75 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -17,7 +17,14 @@ public static void Parse(string[] args) var quotedArgs = args.Select(arg => arg.Contains(" ") ? $"\"{arg}\"" : arg); var argumentJoin = string.Join(" ", quotedArgs); DebugMessage.DisplayDebugMessage("GoAwayEdge", $"The following args are redirected (CTRL+C to copy):\n\n{argumentJoin}"); - + + if (RegistryConfig.GetKey("Enabled") == "False") + { + // Redirect to Edge + StartProcess(FileConfiguration.NonIfeoPath, argumentJoin, "GoAwayEdge is disabled. Redirecting everything to Edge ..."); + return; + } + var (isFile, isApp, singleArgument) = ParseArguments(args); if (_url != null) { From a2b5a5821f1215dfe20019f0f06b755be3a32774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sun, 4 Aug 2024 19:05:58 +0200 Subject: [PATCH 21/80] Added new languages --- GoAwayEdge/Common/Localization.cs | 7 ++++++- ...rceDictionary.da.xaml => ResourceDictionary.da-DK.xaml} | 0 ...rceDictionary.ja.xaml => ResourceDictionary.ja-JP.xaml} | 0 ...rceDictionary.nl.xaml => ResourceDictionary.nl-NL.xaml} | 0 ...rceDictionary.pt.xaml => ResourceDictionary.pt-PT.xaml} | 0 ...rceDictionary.ro.xaml => ResourceDictionary.ro-RO.xaml} | 0 6 files changed, 6 insertions(+), 1 deletion(-) rename GoAwayEdge/Localization/{ResourceDictionary.da.xaml => ResourceDictionary.da-DK.xaml} (100%) rename GoAwayEdge/Localization/{ResourceDictionary.ja.xaml => ResourceDictionary.ja-JP.xaml} (100%) rename GoAwayEdge/Localization/{ResourceDictionary.nl.xaml => ResourceDictionary.nl-NL.xaml} (100%) rename GoAwayEdge/Localization/{ResourceDictionary.pt.xaml => ResourceDictionary.pt-PT.xaml} (100%) rename GoAwayEdge/Localization/{ResourceDictionary.ro.xaml => ResourceDictionary.ro-RO.xaml} (100%) diff --git a/GoAwayEdge/Common/Localization.cs b/GoAwayEdge/Common/Localization.cs index 28154ca..38cfea4 100644 --- a/GoAwayEdge/Common/Localization.cs +++ b/GoAwayEdge/Common/Localization.cs @@ -7,7 +7,7 @@ internal class LocalizationManager { public static void LoadLanguage() { - // Set current language model + // Override language for testing const string overrideLanguage = ""; var language = Thread.CurrentThread.CurrentCulture.ToString(); @@ -24,6 +24,11 @@ public static void LoadLanguage() "pl-PL" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.pl-PL.xaml", UriKind.Relative), "ko-KR" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.ko-KR.xaml", UriKind.Relative), "pt-BR" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.pt-BR.xaml", UriKind.Relative), + "da-DK" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.da-DK.xaml", UriKind.Relative), + "ja-JP" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.ja-JP.xaml", UriKind.Relative), + "nl-NL" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.nl-NL.xaml", UriKind.Relative), + "pt-PT" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.pt-PT.xaml", UriKind.Relative), + "ro-RO" => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.ro-RO.xaml", UriKind.Relative), _ => new Uri("/GoAwayEdge;component/Localization/ResourceDictionary.xaml", UriKind.Relative) }; try diff --git a/GoAwayEdge/Localization/ResourceDictionary.da.xaml b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml similarity index 100% rename from GoAwayEdge/Localization/ResourceDictionary.da.xaml rename to GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.ja.xaml b/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml similarity index 100% rename from GoAwayEdge/Localization/ResourceDictionary.ja.xaml rename to GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.nl.xaml b/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml similarity index 100% rename from GoAwayEdge/Localization/ResourceDictionary.nl.xaml rename to GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml similarity index 100% rename from GoAwayEdge/Localization/ResourceDictionary.pt.xaml rename to GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml diff --git a/GoAwayEdge/Localization/ResourceDictionary.ro.xaml b/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml similarity index 100% rename from GoAwayEdge/Localization/ResourceDictionary.ro.xaml rename to GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml From c5b146148070c5a43db35bbec213237147b3edff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sun, 11 Aug 2024 15:00:30 +0200 Subject: [PATCH 22/80] validating custom url --- GoAwayEdge/Common/Configuration.cs | 15 ++-- .../ResourceDictionary.de-DE.xaml | 2 +- .../ControlPanel/Pages/EdgeSettings.xaml | 6 +- .../ControlPanel/Pages/EdgeSettings.xaml.cs | 88 ++++++++++++++++--- .../UserInterface/Setup/Pages/Settings.xaml | 4 +- .../Setup/Pages/Settings.xaml.cs | 30 ++++++- 6 files changed, 118 insertions(+), 27 deletions(-) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 250f958..16072cc 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,5 +1,6 @@ using System.IO; using System.Windows; +using GoAwayEdge.Common.Debugging; using Microsoft.Win32; namespace GoAwayEdge.Common @@ -165,7 +166,7 @@ public static void SetKey(string option, object value, RegistryValueKind valueKi } catch (Exception ex) { - Console.WriteLine("An error has occurred while writing to the registry: " + ex.Message); + Logging.Log("An error has occurred while writing to the registry: " + ex.Message, Logging.LogLevel.ERROR); } } @@ -189,16 +190,16 @@ public static string GetKey(string option, bool isUninstall = false) { return value.ToString()!; } - Console.WriteLine($"Value for key '{option}' not found in the registry."); + Logging.Log($"Value for key '{option}' not found in the registry.", Logging.LogLevel.ERROR); return ""; } } catch (Exception ex) { - Console.WriteLine("An error has occurred while reading the registry: " + ex.Message); + Logging.Log($"An error has occurred while reading the registry: {ex.Message}", Logging.LogLevel.ERROR); return ""; } - Console.WriteLine($"Registry key '{RegistryPath}' not found."); + Logging.Log($"Registry key '{RegistryPath}' not found.", Logging.LogLevel.ERROR); return ""; } @@ -213,7 +214,7 @@ public static bool RemoveKey(string option, bool isUninstall = false) { using var key = isUninstall ? Registry.LocalMachine.OpenSubKey(UninstallRegistryPath) - : Registry.LocalMachine.OpenSubKey(RegistryPath); + : Registry.LocalMachine.OpenSubKey(RegistryPath); var value = key?.GetValue(option); if (value != null) { @@ -224,7 +225,7 @@ public static bool RemoveKey(string option, bool isUninstall = false) } catch (Exception ex) { - Console.WriteLine("An error has occurred while removing a key from the registry: " + ex.Message); + Logging.Log("An error has occurred while removing a key from the registry: " + ex.Message, Logging.LogLevel.ERROR); } return false; @@ -248,7 +249,7 @@ public static bool RemoveSubKey(string option, bool isUninstall = false) } catch (Exception ex) { - Console.WriteLine("An error has occurred while removing a subkey from the registry: " + ex.Message); + Logging.Log("An error has occurred while removing a subkey from the registry: " + ex.Message, Logging.LogLevel.ERROR); } return false; diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 69475d2..8bcc269 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -63,7 +63,7 @@ Verwalte Hotkeys und mehr. Aktiviere/Deaktiviere GoAwayEdge Aktiviere GoAwayEdge - Deaktiviere GoAwaEdge + Deaktiviere GoAwayEdge GoAwayEdge wurde auf diesem System erfolgreich deaktiviert. GoAwayEdge konnte auf diesem System nicht aktiviert werden: {0} Installiere das Kontrollpanel, um GoAwayEdge einfacher zu konfigurieren. diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml index cf4fdc1..069ddd9 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml @@ -67,6 +67,7 @@ + - + + @@ -102,7 +104,7 @@ Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{DynamicResource ControlPanelEdgePowerDescription}"/> - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs index 2594cd2..7e21ab8 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs @@ -2,6 +2,7 @@ using System.Windows; using System.Windows.Controls; using GoAwayEdge.Common; +using Wpf.Ui.Controls; namespace GoAwayEdge.UserInterface.ControlPanel.Pages { @@ -27,8 +28,18 @@ public EdgeSettings() SearchEngineBox.Items.Add(searchEngine); } - SearchEngineBox.SelectedItem = Configuration.Search.ToString(); - if (Configuration.CustomQueryUrl != null) QueryUrlTextBox.Text = Configuration.CustomQueryUrl; + if (Configuration.Search == SearchEngine.Custom) + { + SearchEngineBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); + CustomSearchPanel.Visibility = Visibility.Visible; + if (Configuration.CustomQueryUrl != null) QueryUrlTextBox.Text = Configuration.CustomQueryUrl; + CustomUrlStatus.Symbol = Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out _) + ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; + } + else + { + SearchEngineBox.SelectedItem = Configuration.Search.ToString(); + } if (RegistryConfig.GetKey("Enabled") == "True") { @@ -42,49 +53,85 @@ public EdgeSettings() } } + private void FlushSettings() + { + try + { + RegistryConfig.SetKey("EdgeChannel", Configuration.Channel.ToString()); + RegistryConfig.SetKey("SearchEngine", Configuration.Search); + if (Configuration.Search == SearchEngine.Custom) + { + if (Configuration.CustomQueryUrl != null) + RegistryConfig.SetKey("CustomQueryUrl", Configuration.CustomQueryUrl); + } + else + { + RegistryConfig.RemoveKey("CustomQueryUrl"); + } + } + catch (Exception ex) + { + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("FailedFlushSetting", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + } + } + private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { switch (SearchEngineBox.SelectedIndex) { case 0: Configuration.Search = SearchEngine.Google; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 1: Configuration.Search = SearchEngine.Bing; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 2: Configuration.Search = SearchEngine.DuckDuckGo; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 3: Configuration.Search = SearchEngine.Yahoo; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 4: Configuration.Search = SearchEngine.Yandex; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 5: Configuration.Search = SearchEngine.Ecosia; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 6: Configuration.Search = SearchEngine.Ask; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 7: Configuration.Search = SearchEngine.Qwant; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 8: Configuration.Search = SearchEngine.Perplexity; - CustomSearchPanel.Visibility = System.Windows.Visibility.Collapsed; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); break; case 9: Configuration.Search = SearchEngine.Custom; - CustomSearchPanel.Visibility = System.Windows.Visibility.Visible; + CustomSearchPanel.Visibility = Visibility.Visible; if (string.IsNullOrEmpty(Configuration.CustomQueryUrl)) Debug.WriteLine("placeholder"); break; @@ -101,6 +148,7 @@ private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEv 3 => EdgeChannel.Canary, _ => EdgeChannel.Stable }; + FlushSettings(); } private void PowerToggle_OnClick(object sender, RoutedEventArgs e) @@ -154,5 +202,21 @@ private void PowerToggle_OnClick(object sender, RoutedEventArgs e) } } } + + private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + // Test if the URL is valid + if (Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) + { + CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomQueryUrl = QueryUrlTextBox.Text; + FlushSettings(); + } + else + { + CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + } + } } } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml index 261de2e..2e4055e 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml @@ -64,6 +64,7 @@ + - + + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index 00f57c7..0bf88b0 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -1,6 +1,7 @@ using System.Windows; using System.Windows.Controls; using GoAwayEdge.Common; +using Wpf.Ui.Controls; namespace GoAwayEdge.UserInterface.Setup.Pages { @@ -23,7 +24,19 @@ public Settings() { SearchEngineBox.Items.Add(searchEngine); } - SearchEngineBox.SelectedItem = Configuration.Search.ToString(); + + if (Configuration.Search == SearchEngine.Custom) + { + SearchEngineBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); + CustomSearchPanel.Visibility = Visibility.Visible; + if (Configuration.CustomQueryUrl != null) QueryUrlTextBox.Text = Configuration.CustomQueryUrl; + CustomUrlStatus.Symbol = Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out _) + ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; + } + else + { + SearchEngineBox.SelectedItem = Configuration.Search.ToString(); + } if (Configuration.NoEdgeInstalled) { @@ -108,9 +121,18 @@ private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedE private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e) { - Configuration.CustomQueryUrl = QueryUrlTextBox.Text; - Installer.ContentWindow!.NextBtn.IsEnabled = Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out var uriResult) - && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); + if (Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) + { + Installer.ContentWindow!.NextBtn.IsEnabled = true; + CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomQueryUrl = QueryUrlTextBox.Text; + } + else + { + Installer.ContentWindow!.NextBtn.IsEnabled = false; + CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + } } private void MsEdgeUninstallSwitch_OnClickUninstallSwitch_OnClick(object sender, RoutedEventArgs e) From 64f98ad6ec4f92b3b6b920a71f81bbde2e93b919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 12 Aug 2024 20:47:08 +0200 Subject: [PATCH 23/80] Implemented PoC for Copilot replacement --- GoAwayEdge/App.xaml.cs | 7 + GoAwayEdge/GoAwayEdge.csproj.user | 6 + .../CopilotDock/CopilotDock.xaml | 35 +++++ .../CopilotDock/CopilotDock.xaml.cs | 139 ++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml create mode 100644 GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 24a6d6c..c451b9f 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -90,6 +90,13 @@ public void Application_Startup(object sender, StartupEventArgs e) controlCenter.ShowDialog(); Environment.Exit(0); } + if (args.Contains("--copilot-dock")) + { + Configuration.InitialEnvironment(); + var copilotDock = new UserInterface.CopilotDock.CopilotDock(); + copilotDock.ShowDialog(); + Environment.Exit(0); + } if (args.Contains("-s")) // Silent Installation { foreach (var arg in args) diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 83a95aa..54afbb0 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -16,6 +16,9 @@ Code + + Code + Code @@ -60,6 +63,9 @@ Designer + + Designer + Designer diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml new file mode 100644 index 0000000..2980a66 --- /dev/null +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs new file mode 100644 index 0000000..abe4ddb --- /dev/null +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -0,0 +1,139 @@ +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Input; + +namespace GoAwayEdge.UserInterface.CopilotDock +{ + /// + /// Interaktionslogik für CopilotDock.xaml + /// + public partial class CopilotDock + { + private static bool _isDocked; + public CopilotDock() + { + InitializeComponent(); + DockWindowToRight(); + } + + // Testing + private void Window_MouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left) + this.DragMove(); + } + + #region Docking + + private void DockWindowToRight() + { + var screenWidth = SystemParameters.PrimaryScreenWidth; + var screenHeight = SystemParameters.PrimaryScreenHeight; + + Width = screenWidth * 0.3; + Height = screenHeight; + MinWidth = 200; + ResizeMode = ResizeMode.CanResizeWithGrip; + + // Set window position + Left = screenWidth - Width; + Top = 0; + + // Register App Bar + RegisterAppBar(); + } + + [StructLayout(LayoutKind.Sequential)] + private struct APPBARDATA + { + public uint cbSize; + public IntPtr hWnd; + public uint uCallbackMessage; + public uint uEdge; + public RECT rc; + public int lParam; + } + + [StructLayout(LayoutKind.Sequential)] + private struct RECT + { + public int left, top, right, bottom; + } + + private const int ABM_NEW = 0x00000000; + private const int ABM_REMOVE = 0x00000001; + private const int ABM_SETPOS = 0x00000003; + private const int ABE_RIGHT = 2; + + [DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)] + private static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData); + + private void RegisterAppBar() + { + APPBARDATA appBarData = new APPBARDATA(); + appBarData.cbSize = (uint)Marshal.SizeOf(appBarData); + appBarData.hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; + appBarData.uEdge = ABE_RIGHT; + appBarData.rc.left = (int)(SystemParameters.PrimaryScreenWidth - this.Width); + appBarData.rc.right = (int)SystemParameters.PrimaryScreenWidth; + appBarData.rc.top = 0; + appBarData.rc.bottom = (int)SystemParameters.PrimaryScreenHeight; + + SHAppBarMessage(ABM_NEW, ref appBarData); + SHAppBarMessage(ABM_SETPOS, ref appBarData); + } + + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) + { + base.OnRenderSizeChanged(sizeInfo); + AdjustWindowPosition(); + } + + private void AdjustWindowPosition() + { + this.Left = SystemParameters.PrimaryScreenWidth - this.Width; + } + + protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) + { + base.OnMouseLeftButtonUp(e); + if (_isDocked) RegisterAppBar(); + } + + private void UnregisterAppBar() + { + APPBARDATA appBarData = new APPBARDATA(); + appBarData.cbSize = (uint)Marshal.SizeOf(appBarData); + appBarData.hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; + + SHAppBarMessage(ABM_REMOVE, ref appBarData); + } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + UnregisterAppBar(); + } + + #endregion + + private void CloseButton_OnClick(object sender, RoutedEventArgs e) + { + this.Close(); + } + + private void DockButton_OnClick(object sender, RoutedEventArgs e) + { + if (_isDocked) + { + UnregisterAppBar(); + _isDocked = false; + } + else + { + DockWindowToRight(); + _isDocked = true; + } + } + } +} From 388543f381b36263014942ede7ca635afde1a9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 12 Aug 2024 22:51:50 +0200 Subject: [PATCH 24/80] Implemented Setting panel & WebView2 --- GoAwayEdge/Common/Configuration.cs | 43 +++++- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 25 ++++ GoAwayEdge/GoAwayEdge.csproj | 136 +++++++++--------- GoAwayEdge/GoAwayEdge.csproj.user | 3 + .../Localization/ResourceDictionary.xaml | 5 + .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../ControlPanel/ControlPanel.xaml | 2 +- .../ControlPanel/Pages/CopilotSettings.xaml | 65 +++++++++ .../Pages/CopilotSettings.xaml.cs | 101 +++++++++++++ .../ControlPanel/Pages/HomeScreen.xaml | 2 +- .../ControlPanel/Pages/HomeScreen.xaml.cs | 5 + .../CopilotDock/CopilotDock.xaml | 7 + .../CopilotDock/CopilotDock.xaml.cs | 36 ++++- 13 files changed, 360 insertions(+), 72 deletions(-) create mode 100644 GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml create mode 100644 GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 16072cc..0609cf9 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -19,6 +19,13 @@ public enum SearchEngine Custom } + public enum AiProvider + { + Copilot, + ChatGPT, + Custom + } + public enum EdgeChannel { Stable, @@ -31,11 +38,13 @@ internal class Configuration { public static EdgeChannel Channel { get; set; } public static SearchEngine Search { get; set; } + public static AiProvider Provider { get; set; } public static bool Uninstall { get; set; } public static bool UninstallEdge { get; set; } public static bool NoEdgeInstalled { get; set; } public static bool InstallControlPanel { get; set; } public static string? CustomQueryUrl { get; set; } + public static string? CustomProviderUrl { get; set; } public static string InstallDir = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @@ -55,7 +64,6 @@ public static bool InitialEnvironment() { NoEdgeInstalled = !File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft", "Edge", "Application", "msedge.exe")); - // RegistryConfig.SetKey("NoEdgeInstalled", NoEdgeInstalled); if (NoEdgeInstalled) return true; @@ -65,12 +73,17 @@ public static bool InitialEnvironment() try { - Channel = Runtime.ArgumentParse.ParseEdgeChannel(RegistryConfig.GetKey("Stable")); + Channel = Runtime.ArgumentParse.ParseEdgeChannel(RegistryConfig.GetKey("EdgeChannel")); Search = Runtime.ArgumentParse.ParseSearchEngine(RegistryConfig.GetKey("SearchEngine")); + Provider = Runtime.ArgumentParse.ParseAiProvider(RegistryConfig.GetKey("AiProvider")); if (Search == SearchEngine.Custom) { CustomQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); } + if (Provider == AiProvider.Custom) + { + CustomProviderUrl = RegistryConfig.GetKey("CustomProviderUrl"); + } } catch { @@ -126,6 +139,32 @@ public static List GetSearchEngines() return list; } + + /// + /// Get a list of all available AI Providers. + /// + /// + /// List of AI Providers. + /// + public static List GetAiProviders() + { + var list = (from aiProvider in (AiProvider[])Enum.GetValues(typeof(AiProvider)) + where aiProvider != AiProvider.Custom + select aiProvider.ToString()).ToList(); + + try + { + var resourceValue = + (string)Application.Current.MainWindow!.FindResource("SettingsSearchEngineCustomItem"); + list.Add(!string.IsNullOrEmpty(resourceValue) ? resourceValue : "Custom"); + } + catch + { + list.Add("Custom"); + } + + return list; + } } internal enum ModifyAction diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index c6f1c75..e34241b 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -104,12 +104,26 @@ private static void HandleUrl(string url) if (url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=taskbar") || url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=taskbar")) { + if (Configuration.Provider != AiProvider.Copilot) + { + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.Provider}' (Taskbar) ..."); + var w = new UserInterface.CopilotDock.CopilotDock(); + w.ShowDialog(); + return; + } DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Taskbar) with following url:\n{url}"); } // Copilot Hotkey else if (url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=hotkey") || url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=hotkey")) { + if (Configuration.Provider != AiProvider.Copilot) + { + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.Provider}' (Hotkey) ..."); + var w = new UserInterface.CopilotDock.CopilotDock(); + w.ShowDialog(); + return; + } DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Hotkey) with following url:\n{url}"); } // Default @@ -159,6 +173,17 @@ public static EdgeChannel ParseEdgeChannel(string argument) }; } + public static AiProvider ParseAiProvider(string argument) + { + return argument.ToLower() switch + { + "copilot" => AiProvider.Copilot, + "chatgpt" => AiProvider.ChatGPT, + "custom" => AiProvider.Custom, + _ => AiProvider.Copilot // Fallback channel + }; + } + public static SearchEngine ParseSearchEngine(string argument) { var arg = argument; diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index 49966af..e66ed02 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -1,68 +1,72 @@  - - WinExe - net8.0-windows10.0.18362.0 - enable - enable - true - false - win-x64 - true - true - GoAwayEdge - Exploitox - valnoxy - 2.0.0.192 - Copyright © 2018 - 2024 Exploitox. All rights reserved. - https://github.com/valnoxy/GoAwayEdge - https://github.com/valnoxy/GoAwayEdge - GoAwayEdge.App - GoAwayEdge.ico - $(Version) - $(Version) - $(Version) - false - GoAwayEdge - Redirect Edge calls to your favorite browser! - true - - - - - - - - - - - - - - - - - - - - Designer - MSBuild:Compile - - - - - - - - - - - - - - - - - - Code - - + + WinExe + net8.0-windows10.0.18362.0 + enable + enable + true + false + win-x64 + true + true + GoAwayEdge + Exploitox + valnoxy + 2.0.0.213 + Copyright © 2018 - 2024 Exploitox. All rights reserved. + https://github.com/valnoxy/GoAwayEdge + https://github.com/valnoxy/GoAwayEdge + GoAwayEdge.App + GoAwayEdge.ico + $(Version) + $(Version) + $(Version) + false + GoAwayEdge - Redirect Edge calls to your favorite browser! + true + + + + + + + + + + + + + + + + + + + + Designer + MSBuild:Compile + + + + + + + + + + + + + + + + + + + Code + + + Code + + \ No newline at end of file diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 54afbb0..01ca49f 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -57,6 +57,9 @@ Designer + + Designer + Designer diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 83a4505..561f724 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -59,6 +59,10 @@ Deactivate the forwarding of search queries to other browsers. Enable GoAwayEdge Disable GoAwayEdge + Change AI Provider + Change the provider to your favorite AI (or to your favorite website). + Custom AI Provider + Please enter the URL from the AI Provider (or your favorite website). Initialization failed: {0} @@ -82,5 +86,6 @@ GoAwayEdge was successfully disabled on this system. Could not enable GoAwayEdge on this system: {0} Could not disable GoAwayEdge on this system: {0} + Could not apply the settings: {0} \ No newline at end of file diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index d7300da..756afc2 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-07-29T22:22:22.2984409Z;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; + True|2024-08-12T20:11:19.4188626Z;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml index f4d06f8..188c531 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/ControlPanel.xaml @@ -39,7 +39,7 @@ - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml new file mode 100644 index 0000000..1af8558 --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs new file mode 100644 index 0000000..ca0a07c --- /dev/null +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -0,0 +1,101 @@ +using System.Windows; +using System.Windows.Controls; +using GoAwayEdge.Common; +using Wpf.Ui.Controls; + +namespace GoAwayEdge.UserInterface.ControlPanel.Pages +{ + /// + /// Interaktionslogik für CopilotSettings.xaml + /// + public partial class CopilotSettings + { + public CopilotSettings() + { + InitializeComponent(); + + foreach (var aiProvider in Configuration.GetAiProviders()) + { + CopilotProviderBox.Items.Add(aiProvider); + } + CopilotProviderBox.SelectedItem = Configuration.Provider.ToString(); + + if (Configuration.Provider == AiProvider.Custom) + { + CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); + CustomSearchPanel.Visibility = Visibility.Visible; + if (Configuration.CustomProviderUrl != null) QueryProviderTextBox.Text = Configuration.CustomProviderUrl; + CustomUrlStatus.Symbol = Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out _) + ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; + } + else + { + CopilotProviderBox.SelectedItem = Configuration.Search.ToString(); + } + } + + private void FlushSettings() + { + try + { + RegistryConfig.SetKey("AiProvider", Configuration.Provider.ToString()); + if (Configuration.Provider == AiProvider.Custom) + { + if (Configuration.CustomProviderUrl != null) + RegistryConfig.SetKey("CustomProviderUrl", Configuration.CustomProviderUrl); + } + else + { + RegistryConfig.RemoveKey("CustomProviderUrl"); + } + } + catch (Exception ex) + { + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("FailedFlushSetting", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + } + } + + private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + switch (CopilotProviderBox.SelectedIndex) + { + case 0: + Configuration.Provider = AiProvider.Copilot; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); + break; + case 1: + Configuration.Provider = AiProvider.ChatGPT; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); + break; + case 2: + Configuration.Provider = AiProvider.Custom; + CustomSearchPanel.Visibility = Visibility.Visible; + break; + } + FlushSettings(); + } + + private void QueryProviderTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + // Test if the URL is valid + if (Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) + { + CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomProviderUrl = QueryProviderTextBox.Text; + FlushSettings(); + } + else + { + CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + } + } + } +} diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml index f0881f2..bee27f4 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml @@ -38,7 +38,7 @@ - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs index c473456..9161b62 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/HomeScreen.xaml.cs @@ -16,5 +16,10 @@ private void EdgeSettings_OnClick(object sender, RoutedEventArgs e) { (Application.Current.MainWindow as ControlPanel)?.RootNavigation.Navigate(typeof(EdgeSettings)); } + + private void CopilotSetting_OnClick(object sender, RoutedEventArgs e) + { + (Application.Current.MainWindow as ControlPanel)?.RootNavigation.Navigate(typeof(CopilotSettings)); + } } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml index 2980a66..cc24667 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml @@ -7,6 +7,7 @@ mc:Ignorable="d" Title="GoAwayEdge - Copilot Dock" Height="450" Width="800" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" + xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" Background="{ui:ThemeResource ApplicationBackgroundBrush}" ExtendsContentIntoTitleBar="True" WindowBackdropType="Mica" @@ -28,8 +29,14 @@ + + + + + diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index abe4ddb..f550cc8 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -1,6 +1,10 @@ -using System.Runtime.InteropServices; +using System.IO; +using System.Runtime.InteropServices; using System.Windows; using System.Windows.Input; +using GoAwayEdge.Common; +using GoAwayEdge.Common.Debugging; +using Microsoft.Web.WebView2.Core; namespace GoAwayEdge.UserInterface.CopilotDock { @@ -14,6 +18,36 @@ public CopilotDock() { InitializeComponent(); DockWindowToRight(); + _ = InitializeWebViewAsync(); + } + + private async Task InitializeWebViewAsync() + { + try + { + var userProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "valnoxy", "GoAwayEdge"); + Directory.CreateDirectory(userProfilePath); + + var webView2Environment = await CoreWebView2Environment.CreateAsync(userDataFolder: userProfilePath); + await WebView.EnsureCoreWebView2Async(webView2Environment); + + switch (Configuration.Provider) + { + case AiProvider.ChatGPT: + WebView.Source = new Uri("https://chatgpt.com/"); + break; + case AiProvider.Custom: + if (Configuration.CustomProviderUrl != null) + WebView.Source = new Uri(Configuration.CustomProviderUrl); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + catch (Exception ex) + { + Logging.Log($"Failed to load WebView2 (Copilot replacement): {ex.Message}", Logging.LogLevel.ERROR); + } } // Testing From 3465574eba2811b105ca489690aa1c277e24e385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 13 Aug 2024 00:21:49 +0200 Subject: [PATCH 25/80] Improved Copilot Dock --- GoAwayEdge/App.xaml.cs | 3 +- GoAwayEdge/Common/Configuration.cs | 83 ++++++++--- .../Common/Installation/InstallRoutine.cs | 5 + GoAwayEdge/Common/Runtime/ArgumentParse.cs | 6 +- .../CopilotDock/CopilotDock.xaml | 6 +- .../CopilotDock/CopilotDock.xaml.cs | 54 ++++++- .../CopilotDock/InterfaceManager.cs | 141 ++++++++++++++++++ 7 files changed, 269 insertions(+), 29 deletions(-) create mode 100644 GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index c451b9f..24b45bb 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -93,8 +93,7 @@ public void Application_Startup(object sender, StartupEventArgs e) if (args.Contains("--copilot-dock")) { Configuration.InitialEnvironment(); - var copilotDock = new UserInterface.CopilotDock.CopilotDock(); - copilotDock.ShowDialog(); + UserInterface.CopilotDock.InterfaceManager.ShowDock(); Environment.Exit(0); } if (args.Contains("-s")) // Silent Installation diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 0609cf9..629ba35 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -193,14 +193,26 @@ public class RegistryConfig /// Name of key /// Value of key /// Type of value - /// Use the Uninstall Registry key instead. - public static void SetKey(string option, object value, RegistryValueKind valueKind = RegistryValueKind.String, bool isUninstall = false) + /// Use the Uninstall Registry key instead. + /// Use the CurrentUser Registry key instead. + public static void SetKey(string option, object value, RegistryValueKind valueKind = RegistryValueKind.String, + bool isUninstall = false, bool userSetting = false) { try { - using var key = isUninstall - ? Registry.LocalMachine.CreateSubKey(UninstallRegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree) - : Registry.LocalMachine.CreateSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + RegistryKey? key; + if (userSetting) + { + key = Registry.CurrentUser.CreateSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } + else if (isUninstall) + { + key = Registry.LocalMachine.CreateSubKey(UninstallRegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } + else + { + key = Registry.LocalMachine.CreateSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } key.SetValue(option, value, valueKind); } catch (Exception ex) @@ -214,14 +226,25 @@ public static void SetKey(string option, object value, RegistryValueKind valueKi /// /// Name of the key. /// Use the Uninstall Registry key instead. + /// Use the CurrentUser Registry key instead. /// The value of the key if it exists, otherwise null. - public static string GetKey(string option, bool isUninstall = false) + public static string GetKey(string option, bool isUninstall = false, bool userSetting = false) { try { - using var key = isUninstall - ? Registry.LocalMachine.OpenSubKey(UninstallRegistryPath) - : Registry.LocalMachine.OpenSubKey(RegistryPath); + RegistryKey? key; + if (userSetting) + { + key = Registry.CurrentUser.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } + else if (isUninstall) + { + key = Registry.LocalMachine.OpenSubKey(UninstallRegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } + else + { + key = Registry.LocalMachine.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } if (key != null) { var value = key.GetValue(option); @@ -246,14 +269,25 @@ public static string GetKey(string option, bool isUninstall = false) /// Removes a Key in the Registry /// /// Key Name - /// Use the Uninstall Registry key instead. - public static bool RemoveKey(string option, bool isUninstall = false) + /// Use the Uninstall Registry key instead. + /// Use the CurrentUser Registry key instead. + public static bool RemoveKey(string option, bool isUninstall = false, bool userSetting = false) { try { - using var key = isUninstall - ? Registry.LocalMachine.OpenSubKey(UninstallRegistryPath) - : Registry.LocalMachine.OpenSubKey(RegistryPath); + RegistryKey? key; + if (userSetting) + { + key = Registry.CurrentUser.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } + else if (isUninstall) + { + key = Registry.LocalMachine.OpenSubKey(UninstallRegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } + else + { + key = Registry.LocalMachine.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } var value = key?.GetValue(option); if (value != null) { @@ -274,14 +308,25 @@ public static bool RemoveKey(string option, bool isUninstall = false) /// Removes a SubKey in the Registry /// /// SubKey Name - /// Use the Uninstall Registry key instead. - public static bool RemoveSubKey(string option, bool isUninstall = false) + /// Use the Uninstall Registry key instead. + /// Use the CurrentUser Registry key instead. + public static bool RemoveSubKey(string option, bool isUninstall = false, bool userSetting = false) { try { - using var key = isUninstall - ? Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", true) - : Registry.LocalMachine.OpenSubKey(RegistryPath, true); + RegistryKey? key; + if (userSetting) + { + key = Registry.CurrentUser.OpenSubKey(RegistryPath, true); + } + else if (isUninstall) + { + key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", true); + } + else + { + key = Registry.LocalMachine.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + } key?.DeleteSubKey(option); key?.Close(); return true; diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index afee731..39ead3a 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -295,6 +295,11 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) @"SOFTWARE\valnoxy", true); generalKey?.DeleteSubKeyTree("GoAwayEdge"); generalKey?.Close(); + + var currentUserKey = Registry.CurrentUser.OpenSubKey( + @"SOFTWARE\valnoxy", true); + generalKey?.DeleteSubKeyTree("GoAwayEdge"); + generalKey?.Close(); } catch (Exception ex) { diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index e34241b..2aa1e91 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -107,8 +107,7 @@ private static void HandleUrl(string url) if (Configuration.Provider != AiProvider.Copilot) { DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.Provider}' (Taskbar) ..."); - var w = new UserInterface.CopilotDock.CopilotDock(); - w.ShowDialog(); + UserInterface.CopilotDock.InterfaceManager.ShowDock(); return; } DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Taskbar) with following url:\n{url}"); @@ -120,8 +119,7 @@ private static void HandleUrl(string url) if (Configuration.Provider != AiProvider.Copilot) { DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.Provider}' (Hotkey) ..."); - var w = new UserInterface.CopilotDock.CopilotDock(); - w.ShowDialog(); + UserInterface.CopilotDock.InterfaceManager.ShowDock(); return; } DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Hotkey) with following url:\n{url}"); diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml index cc24667..0004d75 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml @@ -13,10 +13,12 @@ WindowBackdropType="Mica" WindowCornerPreference="Round" WindowStartupLocation="CenterScreen" - MouseDown="Window_MouseDown"> + MouseDown="Window_MouseDown" + ShowInTaskbar="False" + Deactivated="CopilotDock_OnDeactivated"> - + diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index f550cc8..d70c5cc 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -1,10 +1,12 @@ -using System.IO; +using System.Diagnostics; +using System.IO; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Input; using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; using Microsoft.Web.WebView2.Core; +using Wpf.Ui.Controls; namespace GoAwayEdge.UserInterface.CopilotDock { @@ -17,7 +19,6 @@ public partial class CopilotDock public CopilotDock() { InitializeComponent(); - DockWindowToRight(); _ = InitializeWebViewAsync(); } @@ -43,6 +44,34 @@ private async Task InitializeWebViewAsync() default: throw new ArgumentOutOfRangeException(); } + + // Window settings + var screenWidth = SystemParameters.PrimaryScreenWidth; + var screenHeight = SystemParameters.PrimaryScreenHeight; + + Visibility = Visibility.Visible; + Width = screenWidth * 0.3; + Height = screenHeight; + MinWidth = 200; + ResizeMode = ResizeMode.CanResizeWithGrip; + + // Set window position + Left = screenWidth - Width; + Top = 0; + + // Last state + var lastState = RegistryConfig.GetKey("CopilotDockState", userSetting: true); + if (lastState == "Docked") + { + DockWindowToRight(); + _isDocked = true; + DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); + } + else + { + _isDocked = false; + DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); + } } catch (Exception ex) { @@ -64,6 +93,7 @@ private void DockWindowToRight() var screenWidth = SystemParameters.PrimaryScreenWidth; var screenHeight = SystemParameters.PrimaryScreenHeight; + Visibility = Visibility.Visible; Width = screenWidth * 0.3; Height = screenHeight; MinWidth = 200; @@ -162,12 +192,32 @@ private void DockButton_OnClick(object sender, RoutedEventArgs e) { UnregisterAppBar(); _isDocked = false; + DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); + RegistryConfig.SetKey("CopilotDockState", "Detached", userSetting: true); } else { DockWindowToRight(); _isDocked = true; + DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); + RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); } } + + private void CopilotDock_OnDeactivated(object? sender, EventArgs e) + { + if (_isDocked) return; + var currentProcess = Process.GetCurrentProcess(); + var currentTitle = currentProcess.MainWindowTitle; + var currentId = currentProcess.Id; + Logging.Log($"Deactivated CopilotDock (ID: {currentId}, Title: {currentTitle})", Logging.LogLevel.INFO); + Hide(); + } + + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + private const int SW_HIDE = 0; } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs new file mode 100644 index 0000000..28965c4 --- /dev/null +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -0,0 +1,141 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; +using GoAwayEdge.Common.Debugging; + +namespace GoAwayEdge.UserInterface.CopilotDock +{ + public class InterfaceManager + { + public static void ShowDock() + { + using var mutex = new Mutex(true, "GoAwayEdge_CopilotDock", out var createdNew); + if (createdNew) + { + var closed = false; + var copilotDock = new CopilotDock(); + copilotDock.Closed += (sender, args) => closed = true; + copilotDock.ShowDialog(); + + while (!closed) + { + Thread.Sleep(1000); + } + Logging.Log("Closed CopilotDock", Logging.LogLevel.INFO); + } + else + { + // check if dock is in background + BringToFront(); + } + } + + private static void BringToFront() + { + var currentProcess = Process.GetCurrentProcess(); + var currentTitle = currentProcess.MainWindowTitle; + var currentId = currentProcess.Id; + var processes = Process.GetProcessesByName(currentProcess.ProcessName); + foreach (var process in processes) + { + if (process.Id != currentProcess.Id) + { + if (process.MainWindowHandle == IntPtr.Zero) + { + var handle = GetWindowHandle(process.Id, process.MainWindowTitle); + if (handle != IntPtr.Zero) + { + // show window + ShowWindow(handle, 5); + // send WM_SHOWWINDOW message to toggle the visibility flag + SendMessage(handle, WM_SHOWWINDOW, IntPtr.Zero, new IntPtr(SW_PARENTOPENING)); + } + } + } + } + } + + // "stolen" from StackOverflow >:) + // https://stackoverflow.com/questions/21154693/activate-a-hidden-wpf-application-when-trying-to-run-a-second-instance + const int GWL_EXSTYLE = (-20); + const uint WS_EX_APPWINDOW = 0x40000; + + const uint WM_SHOWWINDOW = 0x0018; + const int SW_PARENTOPENING = 3; + + [DllImport("user32.dll")] + private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow); + + [DllImport("user32.dll")] + static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumWindowsProc ewp, int lParam); + + [DllImport("user32.dll")] + static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); + + [DllImport("user32.dll")] + private static extern uint GetWindowTextLength(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern uint GetWindowText(IntPtr hWnd, StringBuilder lpString, uint nMaxCount); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern bool GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + + [DllImport("user32.dll")] + static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); + + static bool IsApplicationWindow(IntPtr hWnd) + { + return (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_APPWINDOW) != 0; + } + + static IntPtr GetWindowHandle(int pid, string title) + { + var result = IntPtr.Zero; + + EnumWindowsProc enumerateHandle = delegate (IntPtr hWnd, int lParam) + { + int id; + GetWindowThreadProcessId(hWnd, out id); + + if (pid == id) + { + var clsName = new StringBuilder(256); + var hasClass = GetClassName(hWnd, clsName, 256); + if (hasClass) + { + + var maxLength = (int)GetWindowTextLength(hWnd); + var builder = new StringBuilder(maxLength + 1); + GetWindowText(hWnd, builder, (uint)builder.Capacity); + + var text = builder.ToString(); + var className = clsName.ToString(); + + // There could be multiple handle associated with our pid, + // so we return the first handle that satisfy: + // 1) the handle title/ caption matches our window title, + // 2) the window class name starts with HwndWrapper (WPF specific) + // 3) the window has WS_EX_APPWINDOW style + + if (title == text && className.StartsWith("HwndWrapper") && IsApplicationWindow(hWnd)) + { + result = hWnd; + return false; + } + } + } + return true; + }; + + EnumDesktopWindows(IntPtr.Zero, enumerateHandle, 0); + + return result; + } + } +} From 5bc952519cb15bd912eb82164786f20c4d0f65ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 13 Aug 2024 00:58:44 +0200 Subject: [PATCH 26/80] Fixed Control Panel access --- GoAwayEdge/App.xaml.cs | 18 ++++++++++++++++++ .../Common/Installation/InstallRoutine.cs | 5 +++-- .../PublishProfiles/FolderProfile.pubxml.user | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 24b45bb..2804466 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -77,6 +77,24 @@ public void Application_Startup(object sender, StartupEventArgs e) Environment.Exit(0); if (args.Contains("--control-panel")) { + if (IsAdministrator() == false) + { + // Restart program and run as admin + var exeName = Process.GetCurrentProcess().MainModule?.FileName; + if (exeName != null) + { + var startInfo = new ProcessStartInfo(exeName) + { + Verb = "runas", + UseShellExecute = true, + Arguments = string.Join(" ", args) + }; + Process.Start(startInfo); + } + Environment.Exit(0); + return; + } + // Check if user allowed opening the control panel if (RegistryConfig.GetKey("ControlPanelIsInstalled") != "True") { diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index 39ead3a..56d6ae7 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -205,6 +205,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) // Set enable flag RegistryConfig.SetKey("Enabled", true); + RegistryConfig.SetKey("AiProvider", "Copilot"); // Temporary // Switch FrameWindow content to InstallationSuccess worker?.ReportProgress(100, ""); @@ -298,8 +299,8 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) var currentUserKey = Registry.CurrentUser.OpenSubKey( @"SOFTWARE\valnoxy", true); - generalKey?.DeleteSubKeyTree("GoAwayEdge"); - generalKey?.Close(); + currentUserKey?.DeleteSubKeyTree("GoAwayEdge"); + currentUserKey?.Close(); } catch (Exception ex) { diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index 756afc2..eddc2a7 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-08-12T20:11:19.4188626Z;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; + True|2024-08-12T22:56:54.4657665Z;True|2024-08-13T00:49:21.1156303+02:00;True|2024-08-13T00:45:56.3970427+02:00;True|2024-08-13T00:25:23.5481220+02:00;True|2024-08-12T22:11:19.4188626+02:00;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; \ No newline at end of file From e72ebd75b59a5cf17d50434c699e8712766e8834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 13 Aug 2024 01:11:02 +0200 Subject: [PATCH 27/80] Fixed dock --- .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../CopilotDock/CopilotDock.xaml.cs | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index eddc2a7..052774b 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-08-12T22:56:54.4657665Z;True|2024-08-13T00:49:21.1156303+02:00;True|2024-08-13T00:45:56.3970427+02:00;True|2024-08-13T00:25:23.5481220+02:00;True|2024-08-12T22:11:19.4188626+02:00;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; + True|2024-08-12T23:10:27.4137217Z;True|2024-08-13T01:06:17.9215774+02:00;True|2024-08-13T00:56:54.4657665+02:00;True|2024-08-13T00:49:21.1156303+02:00;True|2024-08-13T00:45:56.3970427+02:00;True|2024-08-13T00:25:23.5481220+02:00;True|2024-08-12T22:11:19.4188626+02:00;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index d70c5cc..db0fada 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -60,17 +60,34 @@ private async Task InitializeWebViewAsync() Top = 0; // Last state - var lastState = RegistryConfig.GetKey("CopilotDockState", userSetting: true); - if (lastState == "Docked") + try + { + var lastState = RegistryConfig.GetKey("CopilotDockState", userSetting: true); + if (string.IsNullOrEmpty(lastState)) + { + DockWindowToRight(); + _isDocked = true; + DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); + RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); + } + else if (lastState == "Docked") + { + DockWindowToRight(); + _isDocked = true; + DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); + } + else + { + _isDocked = false; + DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); + } + } + catch { DockWindowToRight(); _isDocked = true; DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); - } - else - { - _isDocked = false; - DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); + RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); } } catch (Exception ex) From 36ca2176e1bee2c153d817daa77f406bbff988d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 13 Aug 2024 23:37:20 +0200 Subject: [PATCH 28/80] Move 'AiProvider' to UserSettings --- GoAwayEdge/App.xaml.cs | 19 +++++++++++++++++-- GoAwayEdge/Common/Configuration.cs | 10 +++++----- .../Common/Installation/InstallRoutine.cs | 15 ++++++++++++++- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 10 +++++++--- GoAwayEdge/GoAwayEdge.csproj | 1 + .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../Pages/CopilotSettings.xaml.cs | 6 +++--- .../ControlPanel/Pages/EdgeSettings.xaml.cs | 8 +++----- .../CopilotDock/CopilotDock.xaml.cs | 6 ++++-- 9 files changed, 55 insertions(+), 22 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 2804466..fbef1e2 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -108,12 +108,27 @@ public void Application_Startup(object sender, StartupEventArgs e) controlCenter.ShowDialog(); Environment.Exit(0); } + if (args.Contains("--copilot-dock")) { Configuration.InitialEnvironment(); - UserInterface.CopilotDock.InterfaceManager.ShowDock(); - Environment.Exit(0); + + if (Configuration.Provider != AiProvider.Copilot) + { + DebugMessage.DisplayDebugMessage("GoAwayEdge", + $"Opening AI Provider '{Configuration.Provider}' (Triggered with argument) ..."); + UserInterface.CopilotDock.InterfaceManager.ShowDock(); + Environment.Exit(0); + } + else + { + IsDebug = true; + DebugMessage.DisplayDebugMessage("GoAwayEdge", + "You cannot open the Copilot dock if your AI provider is Copilot."); + Environment.Exit(1); + } } + if (args.Contains("-s")) // Silent Installation { foreach (var arg in args) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 629ba35..7ed42b0 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -75,14 +75,14 @@ public static bool InitialEnvironment() { Channel = Runtime.ArgumentParse.ParseEdgeChannel(RegistryConfig.GetKey("EdgeChannel")); Search = Runtime.ArgumentParse.ParseSearchEngine(RegistryConfig.GetKey("SearchEngine")); - Provider = Runtime.ArgumentParse.ParseAiProvider(RegistryConfig.GetKey("AiProvider")); + Provider = Runtime.ArgumentParse.ParseAiProvider(RegistryConfig.GetKey("AiProvider", userSetting: true)); if (Search == SearchEngine.Custom) { CustomQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); } if (Provider == AiProvider.Custom) { - CustomProviderUrl = RegistryConfig.GetKey("CustomProviderUrl"); + CustomProviderUrl = RegistryConfig.GetKey("CustomProviderUrl", userSetting: true); } } catch @@ -235,15 +235,15 @@ public static string GetKey(string option, bool isUninstall = false, bool userSe RegistryKey? key; if (userSetting) { - key = Registry.CurrentUser.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + key = Registry.CurrentUser.OpenSubKey(RegistryPath); } else if (isUninstall) { - key = Registry.LocalMachine.OpenSubKey(UninstallRegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + key = Registry.LocalMachine.OpenSubKey(UninstallRegistryPath); } else { - key = Registry.LocalMachine.OpenSubKey(RegistryPath, RegistryKeyPermissionCheck.ReadWriteSubTree); + key = Registry.LocalMachine.OpenSubKey(RegistryPath); } if (key != null) { diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index 56d6ae7..d102394 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -103,6 +103,10 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) return; } + // Kill Microsoft Edge processes + KillProcess("msedge"); + KillProcess("msedge_non_ifeo"); + if (Configuration.UninstallEdge) { FileConfiguration.EdgePath = msEdge; @@ -205,7 +209,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) // Set enable flag RegistryConfig.SetKey("Enabled", true); - RegistryConfig.SetKey("AiProvider", "Copilot"); // Temporary + RegistryConfig.SetKey("AiProvider", "Copilot", userSetting: true); // Temporary // Switch FrameWindow content to InstallationSuccess worker?.ReportProgress(100, ""); @@ -404,6 +408,15 @@ internal static bool SetUninstallData() return false; } } + + internal static void KillProcess(string processName) + { + var processes = Process.GetProcessesByName(processName); + foreach (var process in processes) + { + process.Kill(); + } + } } public class Register diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 2aa1e91..c3bfd3b 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -25,11 +25,15 @@ public static void Parse(string[] args) return; } - var (isFile, isApp, singleArgument) = ParseArguments(args); + var (isFile, isApp, isOnlyEdge, singleArgument) = ParseArguments(args); if (_url != null) { HandleUrl(_url); } + else if (isOnlyEdge) + { + StartProcess(FileConfiguration.NonIfeoPath, "", "Opening Microsoft Edge without any arguments."); + } else if (isFile) { StartProcess(FileConfiguration.NonIfeoPath, $"--single-argument {singleArgument}", $"Opening '{singleArgument}' with Edge."); @@ -44,8 +48,8 @@ public static void Parse(string[] args) /// Parses the command line arguments to identify if a file path or app ID is present. /// /// The command line arguments. - /// A tuple with the values isFile, isApp, and singleArgument. - private static (bool isFile, bool isApp, string singleArgument) ParseArguments(string[] args) + /// A tuple with the values isFile, isApp, isOnlyEdge and singleArgument. + private static (bool isFile, bool isApp, bool isOnlyEdge, string singleArgument) ParseArguments(string[] args) { bool isFile = false, isApp = false, collectSingleArgument = false; var singleArgument = string.Empty; diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index e66ed02..3c87523 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -24,6 +24,7 @@ false GoAwayEdge - Redirect Edge calls to your favorite browser! true + true diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index 052774b..c610a64 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-08-12T23:10:27.4137217Z;True|2024-08-13T01:06:17.9215774+02:00;True|2024-08-13T00:56:54.4657665+02:00;True|2024-08-13T00:49:21.1156303+02:00;True|2024-08-13T00:45:56.3970427+02:00;True|2024-08-13T00:25:23.5481220+02:00;True|2024-08-12T22:11:19.4188626+02:00;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; + True|2024-08-13T17:39:30.3814052Z;True|2024-08-13T19:35:07.3638159+02:00;True|2024-08-13T01:10:27.4137217+02:00;True|2024-08-13T01:06:17.9215774+02:00;True|2024-08-13T00:56:54.4657665+02:00;True|2024-08-13T00:49:21.1156303+02:00;True|2024-08-13T00:45:56.3970427+02:00;True|2024-08-13T00:25:23.5481220+02:00;True|2024-08-12T22:11:19.4188626+02:00;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs index ca0a07c..6db1ae0 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -38,15 +38,15 @@ private void FlushSettings() { try { - RegistryConfig.SetKey("AiProvider", Configuration.Provider.ToString()); + RegistryConfig.SetKey("AiProvider", Configuration.Provider.ToString(), userSetting: true); if (Configuration.Provider == AiProvider.Custom) { if (Configuration.CustomProviderUrl != null) - RegistryConfig.SetKey("CustomProviderUrl", Configuration.CustomProviderUrl); + RegistryConfig.SetKey("CustomProviderUrl", Configuration.CustomProviderUrl, userSetting: true); } else { - RegistryConfig.RemoveKey("CustomProviderUrl"); + RegistryConfig.RemoveKey("CustomProviderUrl", userSetting: true); } } catch (Exception ex) diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs index 7e21ab8..c03dbd3 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs @@ -44,16 +44,16 @@ public EdgeSettings() if (RegistryConfig.GetKey("Enabled") == "True") { _appIsEnabled = true; - PowerToggle.Content = "Disable GoAwayEdge"; + PowerToggle.Content = LocalizationManager.LocalizeValue("ControlPanelEdgePowerDisable"); ; } else { _appIsEnabled = false; - PowerToggle.Content = "Enable GoAwayEdge"; + PowerToggle.Content = LocalizationManager.LocalizeValue("ControlPanelEdgePowerEnable"); ; } } - private void FlushSettings() + private static void FlushSettings() { try { @@ -132,8 +132,6 @@ private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedE case 9: Configuration.Search = SearchEngine.Custom; CustomSearchPanel.Visibility = Visibility.Visible; - if (string.IsNullOrEmpty(Configuration.CustomQueryUrl)) - Debug.WriteLine("placeholder"); break; } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index db0fada..bf1b258 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -7,6 +7,7 @@ using GoAwayEdge.Common.Debugging; using Microsoft.Web.WebView2.Core; using Wpf.Ui.Controls; +using static GoAwayEdge.Common.AiProvider; namespace GoAwayEdge.UserInterface.CopilotDock { @@ -34,14 +35,15 @@ private async Task InitializeWebViewAsync() switch (Configuration.Provider) { - case AiProvider.ChatGPT: + case ChatGPT: WebView.Source = new Uri("https://chatgpt.com/"); break; - case AiProvider.Custom: + case Custom: if (Configuration.CustomProviderUrl != null) WebView.Source = new Uri(Configuration.CustomProviderUrl); break; default: + Logging.Log($"Failed to load Provider! Provider Value '{Configuration.Provider}' in invalid!"); throw new ArgumentOutOfRangeException(); } From 8c165167c8d704ddf8931eacdac1c4b3330af4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 14 Aug 2024 00:12:59 +0200 Subject: [PATCH 29/80] Fixed Edge startup --- GoAwayEdge/App.xaml.cs | 1 + GoAwayEdge/Common/Installation/InstallRoutine.cs | 13 ++++++------- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 16 +++++++++++++--- .../Setup/Pages/Installation.xaml.cs | 1 + 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index fbef1e2..6126c8a 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -17,6 +17,7 @@ using GoAwayEdge.Common.Runtime; using GoAwayEdge.Common.Debugging; using GoAwayEdge.Common.Installation; +using InstallRoutine = GoAwayEdge.Common.Installation.InstallRoutine; namespace GoAwayEdge { diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index d102394..6313217 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -1,15 +1,14 @@ -using Microsoft.Win32.TaskScheduler; -using Microsoft.Win32; -using System.ComponentModel; +using System.ComponentModel; using System.Diagnostics; using System.IO; -using System.Windows; -using System.Runtime.InteropServices; using System.Reflection; -using GoAwayEdge.Common.Installation; +using System.Runtime.InteropServices; +using System.Windows; using GoAwayEdge.Common.Debugging; +using Microsoft.Win32; +using Microsoft.Win32.TaskScheduler; -namespace GoAwayEdge.Common +namespace GoAwayEdge.Common.Installation { public partial class InstallRoutine { diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index c3bfd3b..21c6fb9 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -51,10 +51,20 @@ public static void Parse(string[] args) /// A tuple with the values isFile, isApp, isOnlyEdge and singleArgument. private static (bool isFile, bool isApp, bool isOnlyEdge, string singleArgument) ParseArguments(string[] args) { - bool isFile = false, isApp = false, collectSingleArgument = false; + bool isFile = false, isApp = false, collectSingleArgument = false, isOnlyEdge = false; var singleArgument = string.Empty; + var cleanedArgs = args + .Where(str => str != "--debug") + .ToArray(); + if (cleanedArgs.Length == 1) + { + if (File.Exists(cleanedArgs[0]) && cleanedArgs[0].EndsWith("msedge.exe")) + { + isOnlyEdge = true; + } + } - foreach (var arg in args) + foreach (var arg in cleanedArgs) { if (arg.Contains("microsoft-edge:")) { @@ -84,7 +94,7 @@ private static (bool isFile, bool isApp, bool isOnlyEdge, string singleArgument) if (singleArgument.Contains("--app-id")) isApp = true; - return (isFile, isApp, singleArgument); + return (isFile, isApp, isOnlyEdge, singleArgument); } /// diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs index 5d2ccc3..4117f99 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs @@ -1,5 +1,6 @@ using System.ComponentModel; using GoAwayEdge.Common; +using InstallRoutine = GoAwayEdge.Common.Installation.InstallRoutine; namespace GoAwayEdge.UserInterface.Setup.Pages { From 72fb7180985418f8096aca3c109756f002c9ec13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 14 Aug 2024 00:37:04 +0200 Subject: [PATCH 30/80] Added version suffix support --- .../ControlPanel/Pages/About.xaml.cs | 20 +++++++++++++++- GoAwayEdge/UserInterface/MessageUI.xaml.cs | 23 +++++++++++++++++-- .../UserInterface/Setup/Installer.xaml.cs | 22 +++++++++++++++++- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml.cs index f5721a6..354c270 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/About.xaml.cs @@ -14,11 +14,29 @@ public About() { InitializeComponent(); + string versionText; var assembly = Assembly.GetExecutingAssembly(); + var version = Assembly.GetExecutingAssembly().GetName().Version!; + try + { + var informationVersion = assembly.GetCustomAttribute()?.InformationalVersion; + if (!string.IsNullOrEmpty(informationVersion) && version.ToString() != informationVersion) + { + versionText = $"{version}-{informationVersion}"; + } + else + { + versionText = $"{version}"; + } + } + catch + { + versionText = $"{version}"; + } var appDirectory = AppContext.BaseDirectory; var assemblyPath = Path.Combine(appDirectory, $"{assembly.GetName().Name}.exe"); var fvi = FileVersionInfo.GetVersionInfo(assemblyPath); - ValueVersion.Content = $"{fvi.ProductName} v{fvi.FileVersion}"; + ValueVersion.Content = $"{fvi.ProductName} v{versionText}"; ValueCopyright.Content = fvi.LegalCopyright; } diff --git a/GoAwayEdge/UserInterface/MessageUI.xaml.cs b/GoAwayEdge/UserInterface/MessageUI.xaml.cs index 7edfac7..73a1399 100644 --- a/GoAwayEdge/UserInterface/MessageUI.xaml.cs +++ b/GoAwayEdge/UserInterface/MessageUI.xaml.cs @@ -33,8 +33,27 @@ public MessageUi(string title, string message, string? btn1 = null, string? btn2 this.Btn2.Visibility = Visibility.Collapsed; if (btn3 is null or "") this.Btn3.Visibility = Visibility.Collapsed; - - VersionLbl.Content = $"Version {Assembly.GetExecutingAssembly().GetName().Version!}"; + + string versionText; + var assembly = Assembly.GetExecutingAssembly(); + var version = Assembly.GetExecutingAssembly().GetName().Version!; + try + { + var informationVersion = assembly.GetCustomAttribute()?.InformationalVersion; + if (!string.IsNullOrEmpty(informationVersion) && version.ToString() != informationVersion) + { + versionText = $"Version {version}-{informationVersion}"; + } + else + { + versionText = $"Version {version}"; + } + } + catch + { + versionText = $"Version {version}"; + } + VersionLbl.Content = versionText; _mainThread = isMainThread; } diff --git a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs index 900d81a..4fe0252 100644 --- a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs @@ -19,7 +19,27 @@ public Installer() { InitializeComponent(); - VersionLbl.Content = $"Version {Assembly.GetExecutingAssembly().GetName().Version!}"; + string versionText; + var assembly = Assembly.GetExecutingAssembly(); + var version = Assembly.GetExecutingAssembly().GetName().Version!; + try + { + var informationVersion = assembly.GetCustomAttribute()?.InformationalVersion; + if (!string.IsNullOrEmpty(informationVersion) && version.ToString() != informationVersion) + { + versionText = $"Version {version}-{informationVersion}"; + } + else + { + versionText = $"Version {version}"; + } + } + catch + { + versionText = $"Version {version}"; + } + + VersionLbl.Content = versionText; Configuration.InitialEnvironment(); _welcomePage = new Welcome(); From 6a4b98e074bebb4ad033792e98a3cd834a183283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 14 Aug 2024 01:30:29 +0200 Subject: [PATCH 31/80] Added Workflow --- .github/workflows/dotnet-desktop.yml | 101 +++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 .github/workflows/dotnet-desktop.yml diff --git a/.github/workflows/dotnet-desktop.yml b/.github/workflows/dotnet-desktop.yml new file mode 100644 index 0000000..6108d9b --- /dev/null +++ b/.github/workflows/dotnet-desktop.yml @@ -0,0 +1,101 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow will build, test, sign and package a WPF or Windows Forms desktop application +# built on .NET Core. +# To learn how to migrate your existing application to .NET Core, +# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework +# +# To configure this workflow: +# +# 1. Configure environment variables +# GitHub sets default environment variables for every workflow run. +# Replace the variables relative to your project in the "env" section below. +# +# 2. Signing +# Generate a signing certificate in the Windows Application +# Packaging Project or add an existing signing certificate to the project. +# Next, use PowerShell to encode the .pfx file using Base64 encoding +# by running the following Powershell script to generate the output string: +# +# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte +# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt' +# +# Open the output file, SigningCertificate_Encoded.txt, and copy the +# string inside. Then, add the string to the repo as a GitHub secret +# and name it "Base64_Encoded_Pfx." +# For more information on how to configure your signing certificate for +# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing +# +# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key". +# See "Build the Windows Application Packaging project" below to see how the secret is used. +# +# For more information on GitHub Actions, refer to https://github.com/features/actions +# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications, +# refer to https://github.com/microsoft/github-actions-for-desktop-apps + +name: CI/CD develop-v2 branch + +on: + push: + branches: [ "develop-v2" ] + pull_request: + branches: [ "develop-v2" ] + +jobs: + + build: + + strategy: + matrix: + configuration: [Debug, Release] + + runs-on: windows-latest # For a list of available runner types, refer to + # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on + + env: + Solution_Name: GoAwayEdge.sln + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # Install the .NET Core workload + - name: Install .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild + - name: Setup MSBuild.exe + uses: microsoft/setup-msbuild@v2 + + # Restore the application to populate the obj folder with RuntimeIdentifiers + - name: Restore the application + run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration + env: + Configuration: ${{ matrix.configuration }} + + # Get Git Hash + - name: Get Git Hash + id: vars + run: | + echo "sha_short=$(git rev-parse --short HEAD)" >> $env:GITHUB_OUTPUT + echo Short SHA: ${{ steps.vars.outputs.sha_short }} + + # Build app + - name: Build GoAwayEdge (Release) + run: msbuild $env:Solution_Name /t:Restore /t:Build,Publish /p:Configuration=$env:Configuration /p:InformationalVersion=${{ steps.vars.outputs.sha_short }} /p:OutputPath=..\publish\ + env: + Configuration: ${{ matrix.configuration }} + + # Upload builds + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: GoAwayEdge ${{ matrix.configuration }} + path: publish\publish\*.exe \ No newline at end of file From f52e8939fda50d1a1afd8ad56c46f0accf56da60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 20 Aug 2024 12:27:41 +0200 Subject: [PATCH 32/80] Added Gemini --- GoAwayEdge/Common/Configuration.cs | 1 + GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 7ed42b0..be60eec 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -23,6 +23,7 @@ public enum AiProvider { Copilot, ChatGPT, + Gemini, Custom } diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index bf1b258..40d3229 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -38,6 +38,9 @@ private async Task InitializeWebViewAsync() case ChatGPT: WebView.Source = new Uri("https://chatgpt.com/"); break; + case Gemini: + WebView.Source = new Uri("https://gemini.google.com/"); + break; case Custom: if (Configuration.CustomProviderUrl != null) WebView.Source = new Uri(Configuration.CustomProviderUrl); From 28cfbc8d5d485dc83ebb88ed4c6afa221c861d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 20 Aug 2024 21:50:36 +0200 Subject: [PATCH 33/80] Fixed Gemini --- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 1 + .../UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 21c6fb9..884c0c1 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -191,6 +191,7 @@ public static AiProvider ParseAiProvider(string argument) { "copilot" => AiProvider.Copilot, "chatgpt" => AiProvider.ChatGPT, + "gemini" => AiProvider.Gemini, "custom" => AiProvider.Custom, _ => AiProvider.Copilot // Fallback channel }; diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs index 6db1ae0..c582a63 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -75,6 +75,11 @@ private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChang FlushSettings(); break; case 2: + Configuration.Provider = AiProvider.Gemini; + CustomSearchPanel.Visibility = Visibility.Collapsed; + FlushSettings(); + break; + case 3: Configuration.Provider = AiProvider.Custom; CustomSearchPanel.Visibility = Visibility.Visible; break; From bc04f4318eaafa3bd021b71f1316b76c094e975c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 20 Aug 2024 23:14:49 +0200 Subject: [PATCH 34/80] Replaced my shitty AppBar implementation with ManagedShell --- GoAwayEdge/Common/Configuration.cs | 7 +- GoAwayEdge/GoAwayEdge.csproj | 5 +- .../CopilotDock/CopilotDock.xaml | 13 +- .../CopilotDock/CopilotDock.xaml.cs | 171 ++---------------- .../CopilotDock/InterfaceManager.cs | 34 +++- 5 files changed, 62 insertions(+), 168 deletions(-) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index be60eec..bea4bc4 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,6 +1,7 @@ using System.IO; using System.Windows; using GoAwayEdge.Common.Debugging; +using ManagedShell; using Microsoft.Win32; namespace GoAwayEdge.Common @@ -51,6 +52,9 @@ internal class Configuration Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "valnoxy", "GoAwayEdge"); + public static ShellManager ShellManager { get; set; } + public static bool AppBarIsAttached { get; set; } + /// /// Initialize the current environment. @@ -69,9 +73,10 @@ public static bool InitialEnvironment() if (NoEdgeInstalled) return true; + ShellManager = new ShellManager(); + FileConfiguration.EdgePath = RegistryConfig.GetKey("EdgeFilePath"); FileConfiguration.NonIfeoPath = RegistryConfig.GetKey("EdgeNonIEFOFilePath"); - try { Channel = Runtime.ArgumentParse.ParseEdgeChannel(RegistryConfig.GetKey("EdgeChannel")); diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index 3c87523..80cf2dc 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -55,9 +55,10 @@ + - - + + diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml index 0004d75..ae5b8da 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml @@ -1,4 +1,4 @@ - @@ -41,4 +40,4 @@ - + diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index 40d3229..577c14a 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -2,9 +2,10 @@ using System.IO; using System.Runtime.InteropServices; using System.Windows; -using System.Windows.Input; using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; +using ManagedShell; +using ManagedShell.AppBar; using Microsoft.Web.WebView2.Core; using Wpf.Ui.Controls; using static GoAwayEdge.Common.AiProvider; @@ -16,9 +17,13 @@ namespace GoAwayEdge.UserInterface.CopilotDock /// public partial class CopilotDock { - private static bool _isDocked; - public CopilotDock() + public CopilotDock(ShellManager shellManager, AppBarScreen screen, AppBarEdge edge, double desiredHeight, AppBarMode mode) + : base(shellManager.AppBarManager, shellManager.ExplorerHelper, shellManager.FullScreenHelper, screen, edge, mode, desiredHeight) { + this.MaxHeight = SystemParameters.WorkArea.Height; + this.MinHeight = SystemParameters.WorkArea.Height; + Configuration.AppBarIsAttached = mode != AppBarMode.None; + InitializeComponent(); _ = InitializeWebViewAsync(); } @@ -49,51 +54,6 @@ private async Task InitializeWebViewAsync() Logging.Log($"Failed to load Provider! Provider Value '{Configuration.Provider}' in invalid!"); throw new ArgumentOutOfRangeException(); } - - // Window settings - var screenWidth = SystemParameters.PrimaryScreenWidth; - var screenHeight = SystemParameters.PrimaryScreenHeight; - - Visibility = Visibility.Visible; - Width = screenWidth * 0.3; - Height = screenHeight; - MinWidth = 200; - ResizeMode = ResizeMode.CanResizeWithGrip; - - // Set window position - Left = screenWidth - Width; - Top = 0; - - // Last state - try - { - var lastState = RegistryConfig.GetKey("CopilotDockState", userSetting: true); - if (string.IsNullOrEmpty(lastState)) - { - DockWindowToRight(); - _isDocked = true; - DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); - RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); - } - else if (lastState == "Docked") - { - DockWindowToRight(); - _isDocked = true; - DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); - } - else - { - _isDocked = false; - DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); - } - } - catch - { - DockWindowToRight(); - _isDocked = true; - DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); - RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); - } } catch (Exception ex) { @@ -101,134 +61,33 @@ private async Task InitializeWebViewAsync() } } - // Testing - private void Window_MouseDown(object sender, MouseButtonEventArgs e) - { - if (e.ChangedButton == MouseButton.Left) - this.DragMove(); - } - - #region Docking - - private void DockWindowToRight() - { - var screenWidth = SystemParameters.PrimaryScreenWidth; - var screenHeight = SystemParameters.PrimaryScreenHeight; - - Visibility = Visibility.Visible; - Width = screenWidth * 0.3; - Height = screenHeight; - MinWidth = 200; - ResizeMode = ResizeMode.CanResizeWithGrip; - - // Set window position - Left = screenWidth - Width; - Top = 0; - - // Register App Bar - RegisterAppBar(); - } - - [StructLayout(LayoutKind.Sequential)] - private struct APPBARDATA - { - public uint cbSize; - public IntPtr hWnd; - public uint uCallbackMessage; - public uint uEdge; - public RECT rc; - public int lParam; - } - - [StructLayout(LayoutKind.Sequential)] - private struct RECT - { - public int left, top, right, bottom; - } - - private const int ABM_NEW = 0x00000000; - private const int ABM_REMOVE = 0x00000001; - private const int ABM_SETPOS = 0x00000003; - private const int ABE_RIGHT = 2; - - [DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)] - private static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData); - - private void RegisterAppBar() - { - APPBARDATA appBarData = new APPBARDATA(); - appBarData.cbSize = (uint)Marshal.SizeOf(appBarData); - appBarData.hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; - appBarData.uEdge = ABE_RIGHT; - appBarData.rc.left = (int)(SystemParameters.PrimaryScreenWidth - this.Width); - appBarData.rc.right = (int)SystemParameters.PrimaryScreenWidth; - appBarData.rc.top = 0; - appBarData.rc.bottom = (int)SystemParameters.PrimaryScreenHeight; - - SHAppBarMessage(ABM_NEW, ref appBarData); - SHAppBarMessage(ABM_SETPOS, ref appBarData); - } - - protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) - { - base.OnRenderSizeChanged(sizeInfo); - AdjustWindowPosition(); - } - - private void AdjustWindowPosition() - { - this.Left = SystemParameters.PrimaryScreenWidth - this.Width; - } - - protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) - { - base.OnMouseLeftButtonUp(e); - if (_isDocked) RegisterAppBar(); - } - - private void UnregisterAppBar() - { - APPBARDATA appBarData = new APPBARDATA(); - appBarData.cbSize = (uint)Marshal.SizeOf(appBarData); - appBarData.hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; - - SHAppBarMessage(ABM_REMOVE, ref appBarData); - } - - protected override void OnClosed(EventArgs e) - { - base.OnClosed(e); - UnregisterAppBar(); - } - - #endregion - private void CloseButton_OnClick(object sender, RoutedEventArgs e) { + Configuration.ShellManager.AppBarManager.SignalGracefulShutdown(); + Configuration.ShellManager.Dispose(); this.Close(); } private void DockButton_OnClick(object sender, RoutedEventArgs e) { - if (_isDocked) + Configuration.ShellManager.AppBarManager.RegisterBar(this, Width, Height, AppBarEdge.Right); + + if (Configuration.AppBarIsAttached) { - UnregisterAppBar(); - _isDocked = false; DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); RegistryConfig.SetKey("CopilotDockState", "Detached", userSetting: true); } else { - DockWindowToRight(); - _isDocked = true; DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); } + Configuration.AppBarIsAttached = !Configuration.AppBarIsAttached; } private void CopilotDock_OnDeactivated(object? sender, EventArgs e) { - if (_isDocked) return; + if (Configuration.AppBarIsAttached) return; var currentProcess = Process.GetCurrentProcess(); var currentTitle = currentProcess.MainWindowTitle; var currentId = currentProcess.Id; diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs index 28965c4..79ef178 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -1,7 +1,9 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; +using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; +using ManagedShell.AppBar; namespace GoAwayEdge.UserInterface.CopilotDock { @@ -12,8 +14,36 @@ public static void ShowDock() using var mutex = new Mutex(true, "GoAwayEdge_CopilotDock", out var createdNew); if (createdNew) { + var mode = AppBarMode.Normal; + + // Last state + try + { + var lastState = RegistryConfig.GetKey("CopilotDockState", userSetting: true); + if (string.IsNullOrEmpty(lastState)) + { + // Never set; leave Mode as Normal + RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); + } + else if (lastState != "Docked") + { + // Undocked or unknown state; set to None + mode = AppBarMode.None; + } + } + catch + { + // Error reading last state; set to Docked + RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); + } + var closed = false; - var copilotDock = new CopilotDock(); + var copilotDock = new CopilotDock( + Configuration.ShellManager, + AppBarScreen.FromPrimaryScreen(), + AppBarEdge.Right, + 500, // temporary size + mode); copilotDock.Closed += (sender, args) => closed = true; copilotDock.ShowDialog(); @@ -21,7 +51,7 @@ public static void ShowDock() { Thread.Sleep(1000); } - Logging.Log("Closed CopilotDock", Logging.LogLevel.INFO); + Logging.Log("Closed CopilotDock"); } else { From 29e3fd1e3b19cfe4a94b6b795bbf213e7e535ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Fri, 23 Aug 2024 19:53:38 +0200 Subject: [PATCH 35/80] Instance communication via Pipe --- GoAwayEdge/Common/Configuration.cs | 35 +++- .../CopilotDock/CopilotDock.xaml | 2 +- .../CopilotDock/CopilotDock.xaml.cs | 17 +- .../CopilotDock/InterfaceManager.cs | 197 +++++++++--------- 4 files changed, 140 insertions(+), 111 deletions(-) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index bea4bc4..2164924 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,4 +1,6 @@ using System.IO; +using System.IO.Pipes; +using System.Threading; using System.Windows; using GoAwayEdge.Common.Debugging; using ManagedShell; @@ -73,7 +75,14 @@ public static bool InitialEnvironment() if (NoEdgeInstalled) return true; - ShellManager = new ShellManager(); + if (!CopilotDockPipeAvailable()) + { + try { ShellManager = new ShellManager(); } + catch (Exception ex) + { + Logging.Log("An error has occurred while initializing the ShellManager: " + ex.Message, Logging.LogLevel.ERROR); + } + } FileConfiguration.EdgePath = RegistryConfig.GetKey("EdgeFilePath"); FileConfiguration.NonIfeoPath = RegistryConfig.GetKey("EdgeNonIEFOFilePath"); @@ -91,9 +100,9 @@ public static bool InitialEnvironment() CustomProviderUrl = RegistryConfig.GetKey("CustomProviderUrl", userSetting: true); } } - catch + catch (Exception ex) { - // ignored + Logging.Log("An error has occurred while reading the registry: " + ex.Message, Logging.LogLevel.ERROR); } return true; } @@ -106,6 +115,26 @@ public static bool InitialEnvironment() } } + public static bool CopilotDockPipeAvailable() + { + try + { + using var pipeClient = new NamedPipeClientStream(".", "CopilotDockPipe", PipeDirection.In); + pipeClient.Connect(1000); + return true; + } + catch (TimeoutException) + { + // Pipe does not exist or is not available + return false; + } + catch (Exception ex) + { + Console.WriteLine($"Failed to check for the pipe 'CopilotDockPipe': {ex.Message}"); + return false; + } + } + /// /// Get a list of all available Edge Channels. /// diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml index ae5b8da..d83da6b 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml @@ -23,7 +23,7 @@ - + diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index 577c14a..58101ef 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -1,6 +1,5 @@ using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; using System.Windows; using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; @@ -17,15 +16,19 @@ namespace GoAwayEdge.UserInterface.CopilotDock /// public partial class CopilotDock { + public static CopilotDock? Instance; public CopilotDock(ShellManager shellManager, AppBarScreen screen, AppBarEdge edge, double desiredHeight, AppBarMode mode) : base(shellManager.AppBarManager, shellManager.ExplorerHelper, shellManager.FullScreenHelper, screen, edge, mode, desiredHeight) { this.MaxHeight = SystemParameters.WorkArea.Height; this.MinHeight = SystemParameters.WorkArea.Height; Configuration.AppBarIsAttached = mode != AppBarMode.None; + Instance = this; InitializeComponent(); _ = InitializeWebViewAsync(); + + DockButton.Icon = Configuration.AppBarIsAttached ? new SymbolIcon(SymbolRegular.PinOff28) : new SymbolIcon(SymbolRegular.Pin28); } private async Task InitializeWebViewAsync() @@ -70,17 +73,17 @@ private void CloseButton_OnClick(object sender, RoutedEventArgs e) private void DockButton_OnClick(object sender, RoutedEventArgs e) { - Configuration.ShellManager.AppBarManager.RegisterBar(this, Width, Height, AppBarEdge.Right); - if (Configuration.AppBarIsAttached) { DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); RegistryConfig.SetKey("CopilotDockState", "Detached", userSetting: true); + this.AppBarMode = AppBarMode.None; } else { DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); + this.AppBarMode = AppBarMode.Normal; } Configuration.AppBarIsAttached = !Configuration.AppBarIsAttached; } @@ -92,13 +95,9 @@ private void CopilotDock_OnDeactivated(object? sender, EventArgs e) var currentTitle = currentProcess.MainWindowTitle; var currentId = currentProcess.Id; Logging.Log($"Deactivated CopilotDock (ID: {currentId}, Title: {currentTitle})", Logging.LogLevel.INFO); - Hide(); + this.Visibility = Visibility.Collapsed; } - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - private const int SW_HIDE = 0; + public void ShowWindow() => this.Visibility = Visibility.Visible; } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs index 79ef178..f94b024 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -1,6 +1,6 @@ -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Text; +using System.IO.Pipes; +using System.IO; +using System.Windows; using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; using ManagedShell.AppBar; @@ -9,6 +9,11 @@ namespace GoAwayEdge.UserInterface.CopilotDock { public class InterfaceManager { + private static AppBarWindow? _dockWindow; + private static NamedPipeServerStream? _pipeServer; + private static Thread? _pipeThread; + private static bool _closed = false; + public static void ShowDock() { using var mutex = new Mutex(true, "GoAwayEdge_CopilotDock", out var createdNew); @@ -37,21 +42,30 @@ public static void ShowDock() RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); } - var closed = false; - var copilotDock = new CopilotDock( + _dockWindow = new CopilotDock( Configuration.ShellManager, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, // temporary size mode); - copilotDock.Closed += (sender, args) => closed = true; - copilotDock.ShowDialog(); - while (!closed) + _dockWindow.Closed += (_, _) => + { + _closed = true; + StopNamedPipeServer(); // Stop the pipe when the dock is closed + }; + _dockWindow.ShowDialog(); + + // Dock is inactive, going now into loop... + while (!_closed) { + StartNamedPipeServer(); // Start pipe server if the dock is inactive Thread.Sleep(1000); } + + // Dock was closed Logging.Log("Closed CopilotDock"); + Environment.Exit(0); } else { @@ -60,112 +74,99 @@ public static void ShowDock() } } - private static void BringToFront() + private static void StartNamedPipeServer() { - var currentProcess = Process.GetCurrentProcess(); - var currentTitle = currentProcess.MainWindowTitle; - var currentId = currentProcess.Id; - var processes = Process.GetProcessesByName(currentProcess.ProcessName); - foreach (var process in processes) + if (_pipeServer != null) return; + + _pipeThread = new Thread(() => { - if (process.Id != currentProcess.Id) + try { - if (process.MainWindowHandle == IntPtr.Zero) + _pipeServer = new NamedPipeServerStream("CopilotDockPipe", PipeDirection.InOut); + Logging.Log("Named Pipe Server opened..."); + + while (true) { - var handle = GetWindowHandle(process.Id, process.MainWindowTitle); - if (handle != IntPtr.Zero) + _pipeServer.WaitForConnection(); + + using (var reader = new StreamReader(_pipeServer)) { - // show window - ShowWindow(handle, 5); - // send WM_SHOWWINDOW message to toggle the visibility flag - SendMessage(handle, WM_SHOWWINDOW, IntPtr.Zero, new IntPtr(SW_PARENTOPENING)); + var message = reader.ReadLine(); + if (message == "BringToFront") + { + Logging.Log("Received 'BringToFront' command via Named Pipe."); + + try + { + Application.Current.Dispatcher.Invoke(() => + { + CopilotDock.Instance!.Visibility = Visibility.Visible; + + try + { + _dockWindow.Visibility = Visibility.Visible; + _dockWindow.Activate(); + } + catch (Exception ex) + { + Logging.Log("Stage 2: Failed to bring CopilotDock to the front: " + ex.Message, Logging.LogLevel.ERROR); + } + }); + } + catch (Exception ex) + { + Logging.Log("Stage 1: Failed to bring CopilotDock to the front: " + ex.Message, Logging.LogLevel.ERROR); + } + } } + + _pipeServer.Disconnect(); } } - } - } - - // "stolen" from StackOverflow >:) - // https://stackoverflow.com/questions/21154693/activate-a-hidden-wpf-application-when-trying-to-run-a-second-instance - const int GWL_EXSTYLE = (-20); - const uint WS_EX_APPWINDOW = 0x40000; - - const uint WM_SHOWWINDOW = 0x0018; - const int SW_PARENTOPENING = 3; - - [DllImport("user32.dll")] - private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow); - - [DllImport("user32.dll")] - static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumWindowsProc ewp, int lParam); - - [DllImport("user32.dll")] - static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); - - [DllImport("user32.dll")] - private static extern uint GetWindowTextLength(IntPtr hWnd); - - [DllImport("user32.dll")] - private static extern uint GetWindowText(IntPtr hWnd, StringBuilder lpString, uint nMaxCount); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - static extern bool GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + catch (Exception ex) + { + Logging.Log("Error in Named Pipe Server: " + ex.Message, Logging.LogLevel.ERROR); + } + finally + { + _pipeServer?.Dispose(); + _pipeServer = null; + } + }); - [DllImport("user32.dll")] - static extern int GetWindowLong(IntPtr hWnd, int nIndex); + _pipeThread.IsBackground = true; + _pipeThread.Start(); + } - delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); - static bool IsApplicationWindow(IntPtr hWnd) + private static void StopNamedPipeServer() { - return (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_APPWINDOW) != 0; + if (_pipeServer != null) + { + _pipeServer.Disconnect(); + _pipeServer.Dispose(); + _pipeServer = null; + } + + if (_pipeThread is not { IsAlive: true }) return; + _pipeThread.Join(); + _pipeThread = null; } - static IntPtr GetWindowHandle(int pid, string title) + private static void BringToFront() { - var result = IntPtr.Zero; - - EnumWindowsProc enumerateHandle = delegate (IntPtr hWnd, int lParam) + using var pipeClient = new NamedPipeClientStream(".", "CopilotDockPipe", PipeDirection.Out); + try { - int id; - GetWindowThreadProcessId(hWnd, out id); - - if (pid == id) - { - var clsName = new StringBuilder(256); - var hasClass = GetClassName(hWnd, clsName, 256); - if (hasClass) - { - - var maxLength = (int)GetWindowTextLength(hWnd); - var builder = new StringBuilder(maxLength + 1); - GetWindowText(hWnd, builder, (uint)builder.Capacity); - - var text = builder.ToString(); - var className = clsName.ToString(); - - // There could be multiple handle associated with our pid, - // so we return the first handle that satisfy: - // 1) the handle title/ caption matches our window title, - // 2) the window class name starts with HwndWrapper (WPF specific) - // 3) the window has WS_EX_APPWINDOW style - - if (title == text && className.StartsWith("HwndWrapper") && IsApplicationWindow(hWnd)) - { - result = hWnd; - return false; - } - } - } - return true; - }; - - EnumDesktopWindows(IntPtr.Zero, enumerateHandle, 0); - - return result; + pipeClient.Connect(1000); + using var writer = new StreamWriter(pipeClient); + writer.WriteLine("BringToFront"); + writer.Flush(); + } + catch (Exception ex) + { + Logging.Log("Failed to connect to CopilotDock pipe: " + ex.Message, Logging.LogLevel.ERROR); + } } } } From 6f9b9803681ec6a73feaf63bedd6f826d655f46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sat, 2 Nov 2024 20:03:07 +0100 Subject: [PATCH 36/80] Extended logging --- GoAwayEdge/Common/Debugging/Logging.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/GoAwayEdge/Common/Debugging/Logging.cs b/GoAwayEdge/Common/Debugging/Logging.cs index 74e2fa8..58b1dee 100644 --- a/GoAwayEdge/Common/Debugging/Logging.cs +++ b/GoAwayEdge/Common/Debugging/Logging.cs @@ -14,6 +14,7 @@ * Backported from: https://git.heydu.net/valnoxy/xorieos/-/blob/main/srv03rtm/base/ntsetup/winnt32/modernsetup/common/logging.cs */ +using System.Diagnostics; using System.IO; using System.Reflection; @@ -51,10 +52,23 @@ public static void Log(string message, LogLevel level = LogLevel.INFO) { if (string.IsNullOrEmpty(_logFile)) throw new Exception("Logging class not initialized!"); - using var writer = new StreamWriter(_logFile, true); - var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {level} - {message}"; - writer.WriteLine(logMessage); + // Get calling method information + var stackTrace = new StackTrace(); + var callingMethod = stackTrace.GetFrame(1)?.GetMethod(); + var callingClass = callingMethod?.DeclaringType?.FullName ?? "UnknownClass"; + var methodName = callingMethod?.Name ?? "UnknownMethod"; + + // Construct the log message with calling class and method + var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {level} - {callingClass}.{methodName} - {message}"; + + using (var fileStream = new FileStream(_logFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) + using (var writer = new StreamWriter(fileStream)) + { + writer.WriteLine(logMessage); + } + + // Output log message to Debug console System.Diagnostics.Debug.WriteLine(logMessage); } @@ -72,4 +86,4 @@ private static void DeleteOldLogFiles() } } } -} +} \ No newline at end of file From 1844601cefa7b78342d83623345edc4782961695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Fri, 29 Nov 2024 00:13:52 +0100 Subject: [PATCH 37/80] Optimized Pipe Manager --- GoAwayEdge/Common/Configuration.cs | 26 +++- GoAwayEdge/Common/Debugging/Logging.cs | 2 +- GoAwayEdge/Common/Runtime/NamedPipeManager.cs | 126 +++++++++++++++ .../CopilotDock/CopilotDock.xaml.cs | 4 +- .../CopilotDock/InterfaceManager.cs | 146 +++--------------- .../CopilotDock/WindowManager.cs | 55 +++++++ 6 files changed, 229 insertions(+), 130 deletions(-) create mode 100644 GoAwayEdge/Common/Runtime/NamedPipeManager.cs create mode 100644 GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 2164924..5b490b5 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,6 +1,5 @@ -using System.IO; +using System.IO; using System.IO.Pipes; -using System.Threading; using System.Windows; using GoAwayEdge.Common.Debugging; using ManagedShell; @@ -69,14 +68,19 @@ public static bool InitialEnvironment() // Check if Edge is installed try { + Logging.Log("Initialize environment ..."); NoEdgeInstalled = !File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft", "Edge", "Application", "msedge.exe")); if (NoEdgeInstalled) + { + Logging.Log("Edge is not installed on this device - completed initialization"); return true; + } if (!CopilotDockPipeAvailable()) { + Logging.Log("Copilot Dock (Pipe) is not available - spawning ShellManager"); try { ShellManager = new ShellManager(); } catch (Exception ex) { @@ -84,6 +88,7 @@ public static bool InitialEnvironment() } } + Logging.Log("Fetching settings from registry ..."); FileConfiguration.EdgePath = RegistryConfig.GetKey("EdgeFilePath"); FileConfiguration.NonIfeoPath = RegistryConfig.GetKey("EdgeNonIEFOFilePath"); try @@ -104,6 +109,13 @@ public static bool InitialEnvironment() { Logging.Log("An error has occurred while reading the registry: " + ex.Message, Logging.LogLevel.ERROR); } + Logging.Log($"Value of EdgePath: {FileConfiguration.EdgePath}"); + Logging.Log($"Value of NonIfeoPath: {FileConfiguration.NonIfeoPath}"); + Logging.Log($"Value of Channel: {Channel}"); + Logging.Log($"Value of Search: {Search}"); + Logging.Log($"Value of Provider: {Provider}"); + Logging.Log($"Value of CustomQueryUrl: {CustomQueryUrl}"); + Logging.Log($"Value of CustomProviderUrl: {CustomProviderUrl}"); return true; } catch (Exception ex) @@ -119,7 +131,7 @@ public static bool CopilotDockPipeAvailable() { try { - using var pipeClient = new NamedPipeClientStream(".", "CopilotDockPipe", PipeDirection.In); + using var pipeClient = new NamedPipeClientStream(".", "GoAwayEdge_CopilotDockPipe", PipeDirection.In); pipeClient.Connect(1000); return true; } @@ -128,9 +140,14 @@ public static bool CopilotDockPipeAvailable() // Pipe does not exist or is not available return false; } + catch (UnauthorizedAccessException ex) + { + Logging.Log($"Access Denied for Pipe 'GoAwayEdge_CopilotDockPipe': {ex.Message}", Logging.LogLevel.ERROR); + return true; + } catch (Exception ex) { - Console.WriteLine($"Failed to check for the pipe 'CopilotDockPipe': {ex.Message}"); + Logging.Log($"Failed to check for the pipe 'GoAwayEdge_CopilotDockPipe': {ex.Message}", Logging.LogLevel.ERROR); return false; } } @@ -148,7 +165,6 @@ public static List GetEdgeChannels() return list; } - /// /// Get a list of all available Search Engines. /// diff --git a/GoAwayEdge/Common/Debugging/Logging.cs b/GoAwayEdge/Common/Debugging/Logging.cs index 58b1dee..d4b7c83 100644 --- a/GoAwayEdge/Common/Debugging/Logging.cs +++ b/GoAwayEdge/Common/Debugging/Logging.cs @@ -22,7 +22,7 @@ namespace GoAwayEdge.Common.Debugging { internal class Logging { - private static string LogPath = Path.Combine(Path.GetTempPath(), "GoAwayEdge", "Logs"); + private static readonly string LogPath = Path.Combine(Path.GetTempPath(), "GoAwayEdge", "Logs"); private static string? _logFile; internal enum LogLevel { INFO, ERROR, WARNING } diff --git a/GoAwayEdge/Common/Runtime/NamedPipeManager.cs b/GoAwayEdge/Common/Runtime/NamedPipeManager.cs new file mode 100644 index 0000000..b9c144c --- /dev/null +++ b/GoAwayEdge/Common/Runtime/NamedPipeManager.cs @@ -0,0 +1,126 @@ +using System.IO.Pipes; +using System.Text; +using GoAwayEdge.Common.Debugging; + +namespace GoAwayEdge.Common.Runtime +{ + public class NamedPipeManager(string pipeName, int maxRetryAttempts = 3) + { + private bool _isServerRunning; + private Thread? _pipeThread; + private readonly object _lock = new(); + + public event Action? MessageReceived; + public event Action? ErrorOccurred; + + public void StartServer() + { + _isServerRunning = true; + + _pipeThread = new Thread(() => + { + while (_isServerRunning) + { + try + { + using (var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous)) + { + Logging.Log("Waiting for client connection..."); + pipeServer.WaitForConnection(); + + Logging.Log("Client connected."); + var buffer = new byte[256]; + while (pipeServer.IsConnected) + { + try + { + int bytesRead = pipeServer.Read(buffer, 0, buffer.Length); + if (bytesRead > 0) + { + string message = Encoding.UTF8.GetString(buffer, 0, bytesRead); + MessageReceived?.Invoke(message); + } + } + catch (Exception ex) + { + HandleError(ex); + break; + } + } + + Logging.Log("Client disconnected. Resetting pipe..."); + pipeServer.Disconnect(); + } + } + catch (Exception ex) + { + HandleError(ex); + Thread.Sleep(2000); + } + } + }); + + _pipeThread.IsBackground = true; + _pipeThread.Start(); + } + + public void SendMessage(string message) + { + int attempt = 0; + + while (attempt < maxRetryAttempts) + { + try + { + using (var pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) + { + Logging.Log("Attempting to connect to server..."); + Logging.Log($"Reaching to pipe: {pipeName}"); + pipeClient.Connect(10000); + Logging.Log("Connected to server."); + + byte[] messageBytes = Encoding.UTF8.GetBytes(message); + pipeClient.Write(messageBytes, 0, messageBytes.Length); + pipeClient.Flush(); + break; + } + } + catch (TimeoutException ex) + { + attempt++; + HandleError(new TimeoutException("Connection timed out.", ex)); + Thread.Sleep(2000); + } + catch (UnauthorizedAccessException ex) + { + HandleError(ex); + break; + } + catch (Exception ex) + { + attempt++; + HandleError(ex); + Thread.Sleep(1000); + } + } + + if (attempt == maxRetryAttempts) + { + Logging.Log("Unable to send message after multiple attempts.", Logging.LogLevel.ERROR); + } + } + + + public void StopServer() + { + _isServerRunning = false; + _pipeThread?.Join(); // Wait for ending tasks + } + + private void HandleError(Exception ex) + { + Logging.Log($"Pipe error: {ex.Message}", Logging.LogLevel.ERROR); + ErrorOccurred?.Invoke(ex); + } + } +} diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index 58101ef..dbf856e 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -95,9 +95,7 @@ private void CopilotDock_OnDeactivated(object? sender, EventArgs e) var currentTitle = currentProcess.MainWindowTitle; var currentId = currentProcess.Id; Logging.Log($"Deactivated CopilotDock (ID: {currentId}, Title: {currentTitle})", Logging.LogLevel.INFO); - this.Visibility = Visibility.Collapsed; + WindowManager.HideCopilotDock(); } - - public void ShowWindow() => this.Visibility = Visibility.Visible; } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs index f94b024..dc0e5d4 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -1,24 +1,22 @@ -using System.IO.Pipes; -using System.IO; -using System.Windows; -using GoAwayEdge.Common; +using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; +using GoAwayEdge.Common.Runtime; using ManagedShell.AppBar; namespace GoAwayEdge.UserInterface.CopilotDock { public class InterfaceManager { - private static AppBarWindow? _dockWindow; - private static NamedPipeServerStream? _pipeServer; - private static Thread? _pipeThread; - private static bool _closed = false; + private const string MutexName = "GoAwayEdge_CopilotDock"; + private const string PipeName = "GoAwayEdge_CopilotDockPipe"; + private static readonly NamedPipeManager PipeManager = new(PipeName); public static void ShowDock() { - using var mutex = new Mutex(true, "GoAwayEdge_CopilotDock", out var createdNew); + using var mutex = new Mutex(true, MutexName, out var createdNew); if (createdNew) { + PipeManager.StartServer(); var mode = AppBarMode.Normal; // Last state @@ -42,26 +40,27 @@ public static void ShowDock() RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); } - _dockWindow = new CopilotDock( - Configuration.ShellManager, + // PipeManager configuration + PipeManager.MessageReceived += (message) => + { + Logging.Log($"Message received: {message}"); + if (message.Contains("BringToFront")) + { + WindowManager.ShowHiddenCopilotDock(); + } + }; + + PipeManager.ErrorOccurred += (ex) => + { + Logging.Log($"Error occurred: {ex.Message}", Logging.LogLevel.ERROR); + }; + + WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, // temporary size mode); - _dockWindow.Closed += (_, _) => - { - _closed = true; - StopNamedPipeServer(); // Stop the pipe when the dock is closed - }; - _dockWindow.ShowDialog(); - - // Dock is inactive, going now into loop... - while (!_closed) - { - StartNamedPipeServer(); // Start pipe server if the dock is inactive - Thread.Sleep(1000); - } // Dock was closed Logging.Log("Closed CopilotDock"); @@ -69,103 +68,8 @@ public static void ShowDock() } else { - // check if dock is in background - BringToFront(); - } - } - - private static void StartNamedPipeServer() - { - if (_pipeServer != null) return; - - _pipeThread = new Thread(() => - { - try - { - _pipeServer = new NamedPipeServerStream("CopilotDockPipe", PipeDirection.InOut); - Logging.Log("Named Pipe Server opened..."); - - while (true) - { - _pipeServer.WaitForConnection(); - - using (var reader = new StreamReader(_pipeServer)) - { - var message = reader.ReadLine(); - if (message == "BringToFront") - { - Logging.Log("Received 'BringToFront' command via Named Pipe."); - - try - { - Application.Current.Dispatcher.Invoke(() => - { - CopilotDock.Instance!.Visibility = Visibility.Visible; - - try - { - _dockWindow.Visibility = Visibility.Visible; - _dockWindow.Activate(); - } - catch (Exception ex) - { - Logging.Log("Stage 2: Failed to bring CopilotDock to the front: " + ex.Message, Logging.LogLevel.ERROR); - } - }); - } - catch (Exception ex) - { - Logging.Log("Stage 1: Failed to bring CopilotDock to the front: " + ex.Message, Logging.LogLevel.ERROR); - } - } - } - - _pipeServer.Disconnect(); - } - } - catch (Exception ex) - { - Logging.Log("Error in Named Pipe Server: " + ex.Message, Logging.LogLevel.ERROR); - } - finally - { - _pipeServer?.Dispose(); - _pipeServer = null; - } - }); - - _pipeThread.IsBackground = true; - _pipeThread.Start(); - } - - - private static void StopNamedPipeServer() - { - if (_pipeServer != null) - { - _pipeServer.Disconnect(); - _pipeServer.Dispose(); - _pipeServer = null; - } - - if (_pipeThread is not { IsAlive: true }) return; - _pipeThread.Join(); - _pipeThread = null; - } - - private static void BringToFront() - { - using var pipeClient = new NamedPipeClientStream(".", "CopilotDockPipe", PipeDirection.Out); - try - { - pipeClient.Connect(1000); - using var writer = new StreamWriter(pipeClient); - writer.WriteLine("BringToFront"); - writer.Flush(); - } - catch (Exception ex) - { - Logging.Log("Failed to connect to CopilotDock pipe: " + ex.Message, Logging.LogLevel.ERROR); + PipeManager.SendMessage("BringToFront"); + Environment.Exit(0); // Exit the second instance } } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs b/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs new file mode 100644 index 0000000..274d16e --- /dev/null +++ b/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs @@ -0,0 +1,55 @@ +using System.Windows; +using System.Windows.Threading; +using GoAwayEdge.Common.Debugging; +using ManagedShell; +using ManagedShell.AppBar; + +namespace GoAwayEdge.UserInterface.CopilotDock; + +public static class WindowManager +{ + private static CopilotDock? _copilotDockInstance; + private static TaskCompletionSource? _closeCompletionSource; + + public static void ShowCopilotDockAsync(ShellManager shellManager, AppBarScreen screen, AppBarEdge edge, double desiredHeight, AppBarMode mode) + { + if (_copilotDockInstance == null) + { + _copilotDockInstance = new CopilotDock(shellManager, screen, edge, desiredHeight, mode); + + var frame = new DispatcherFrame(); + _copilotDockInstance.Closed += (s, e) => + { + _copilotDockInstance = null; + frame.Continue = false; + }; + + _copilotDockInstance.Show(); + Dispatcher.PushFrame(frame); + } + else + { + _copilotDockInstance.Show(); + _copilotDockInstance.Activate(); + } + } + + private static void OnCopilotDockClosed(object sender, System.EventArgs e) + { + _closeCompletionSource?.TrySetResult(true); + if (_copilotDockInstance != null) _copilotDockInstance.Closed -= OnCopilotDockClosed!; + _copilotDockInstance = null; + } + + public static void HideCopilotDock() + { + _copilotDockInstance?.Hide(); + } + + public static void ShowHiddenCopilotDock() + { + if (_copilotDockInstance is not { IsVisible: false }) return; + _copilotDockInstance.Show(); + _copilotDockInstance.Activate(); + } +} \ No newline at end of file From 58ab3b10cac49dba0af3a525bd95cea82d59a03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Fri, 29 Nov 2024 00:14:46 +0100 Subject: [PATCH 38/80] New Setup page for selecting redirect or removal --- GoAwayEdge/Common/Configuration.cs | 3 +- GoAwayEdge/GoAwayEdge.csproj | 9 +- GoAwayEdge/GoAwayEdge.csproj.user | 3 + GoAwayEdge/UserInterface/Setup/Installer.xaml | 84 ++++++++++--------- .../UserInterface/Setup/Installer.xaml.cs | 19 +++-- .../UserInterface/Setup/Pages/License.xaml | 2 +- .../UserInterface/Setup/Pages/License.xaml.cs | 9 ++ .../Setup/Pages/RedirectOrRemove.xaml | 55 ++++++++++++ .../Setup/Pages/RedirectOrRemove.xaml.cs | 39 +++++++++ .../UserInterface/Setup/Pages/Welcome.xaml.cs | 1 + 10 files changed, 173 insertions(+), 51 deletions(-) create mode 100644 GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml create mode 100644 GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 5b490b5..11ce286 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.IO.Pipes; using System.Windows; using GoAwayEdge.Common.Debugging; @@ -42,6 +42,7 @@ internal class Configuration public static EdgeChannel Channel { get; set; } public static SearchEngine Search { get; set; } public static AiProvider Provider { get; set; } + public static bool LicenseAccepted { get; set; } public static bool Uninstall { get; set; } public static bool UninstallEdge { get; set; } public static bool NoEdgeInstalled { get; set; } diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index 80cf2dc..77d5b08 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -55,10 +55,10 @@ - + - - + + @@ -70,5 +70,8 @@ Code + + Code + \ No newline at end of file diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 01ca49f..61534d1 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -75,6 +75,9 @@ Designer + + Designer + Designer diff --git a/GoAwayEdge/UserInterface/Setup/Installer.xaml b/GoAwayEdge/UserInterface/Setup/Installer.xaml index 54d21d7..82f75bf 100644 --- a/GoAwayEdge/UserInterface/Setup/Installer.xaml +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml @@ -15,55 +15,59 @@ ResizeMode="NoResize"> - - - - - + + + + + + - - - + + - - - - - - - - - - - - + Padding="15,2"> + + + + + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - - - + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs index 4fe0252..71eb733 100644 --- a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs @@ -12,8 +12,9 @@ public partial class Installer { internal static Installer? ContentWindow; public static License? LicensePage; + public static Settings? SettingPage; private static Welcome? _welcomePage; - private static Settings? _settingPage; + private static RedirectOrRemove? _redirectOrRemovePage; public Installer() { @@ -43,7 +44,7 @@ public Installer() Configuration.InitialEnvironment(); _welcomePage = new Welcome(); - LicensePage = new License(); + _redirectOrRemovePage = new RedirectOrRemove(); FrameWindow.Content = _welcomePage; ContentWindow = this; } @@ -61,10 +62,10 @@ internal void NextBtn_OnClick(object sender, RoutedEventArgs e) FrameWindow.Content = new Installation(); break; case License: - NextBtn.IsEnabled = true; + NextBtn.IsEnabled = false; BackBtn.IsEnabled = true; - _settingPage = new Settings(); - FrameWindow.Content = _settingPage; + FrameWindow.Content = _redirectOrRemovePage; + SettingPage = new Settings(); break; } } @@ -73,10 +74,16 @@ private void BackBtn_OnClick(object sender, RoutedEventArgs e) { switch (FrameWindow.Content) { + case RedirectOrRemove: + NextBtn.IsEnabled = false; + BackBtn.IsEnabled = true; + LicensePage = new License(); + FrameWindow.Content = LicensePage; + break; case Settings: NextBtn.IsEnabled = true; BackBtn.IsEnabled = true; - FrameWindow.Content = LicensePage; + FrameWindow.Content = _redirectOrRemovePage; break; case License: NextBtn.IsEnabled = false; diff --git a/GoAwayEdge/UserInterface/Setup/Pages/License.xaml b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml index a655c33..2c6e98f 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/License.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml @@ -16,7 +16,7 @@ - + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs index 287cb80..8788a4d 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs @@ -1,4 +1,5 @@ using System.Windows; +using GoAwayEdge.Common; namespace GoAwayEdge.UserInterface.Setup.Pages { @@ -11,6 +12,12 @@ public License() { InitializeComponent(); + if (Configuration.LicenseAccepted) + { + Installer.ContentWindow!.NextBtn.IsEnabled = true; + AcceptLicenseRadioBtn.IsChecked = true; + } + const string license = @"MIT License Copyright (c) 2023-2024 valnoxy @@ -40,10 +47,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE private void AcceptLicenseRb_Click(object sender, RoutedEventArgs e) { Installer.ContentWindow!.NextBtn.IsEnabled = true; + Configuration.LicenseAccepted = true; } private void DeclineLicenseRb_Click(object sender, RoutedEventArgs e) { Installer.ContentWindow!.NextBtn.IsEnabled = false; + Configuration.LicenseAccepted = false; } } } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml new file mode 100644 index 0000000..bac6bb7 --- /dev/null +++ b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs new file mode 100644 index 0000000..f3a6ea0 --- /dev/null +++ b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs @@ -0,0 +1,39 @@ +using System.Windows; +using Wpf.Ui; +using Wpf.Ui.Extensions; + +namespace GoAwayEdge.UserInterface.Setup.Pages +{ + /// + /// Interaktionslogik für RedirectOrRemove.xaml + /// + public partial class RedirectOrRemove + { + public RedirectOrRemove() + { + InitializeComponent(); + } + + private void InstallBtn_Click(object sender, RoutedEventArgs e) + { + Installer.ContentWindow!.FrameWindow.Content = Installer.SettingPage; + Installer.ContentWindow!.NextBtn.IsEnabled = true; + } + + private void UninstallBtn_Click(object sender, RoutedEventArgs e) + { + var contentDialogService = new ContentDialogService(); + contentDialogService.SetDialogHost(Installer.ContentWindow!.RootContentDialogPresenter); + + contentDialogService.ShowSimpleDialogAsync( + new SimpleContentDialogCreateOptions() + { + Title = "Warning", + Content = "Removing Microsoft Edge can cause serious system issues, as it’s deeply integrated into Windows and essential for many features, including updates, help files, and some apps. Deleting it could result in instability or broken functionality.\n\nOnly proceed if you fully understand the risks and have a reliable backup or restore point in place.", + PrimaryButtonText = "Remove Microsoft Edge", + CloseButtonText = "Cancel" + } + ); + } + } +} diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs index 9107ea4..834b8a4 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Welcome.xaml.cs @@ -26,6 +26,7 @@ public Welcome() private void InstallBtn_Click(object sender, RoutedEventArgs e) { + Installer.LicensePage = new License(); Installer.ContentWindow!.FrameWindow.Content = Installer.LicensePage; Installer.ContentWindow!.BackBtn.IsEnabled = true; } From 81584f86a90e5659162e876eded0476c678b606a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 2 Dec 2024 22:44:18 +0100 Subject: [PATCH 39/80] Fixed Interface Manager Copilot Dock now shows if re-opened --- GoAwayEdge/Common/Runtime/NamedPipeManager.cs | 7 ------ .../CopilotDock/CopilotDock.xaml.cs | 5 ++-- .../CopilotDock/InterfaceManager.cs | 4 ++- .../CopilotDock/WindowManager.cs | 25 ++++++++++--------- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/GoAwayEdge/Common/Runtime/NamedPipeManager.cs b/GoAwayEdge/Common/Runtime/NamedPipeManager.cs index b9c144c..fce15a8 100644 --- a/GoAwayEdge/Common/Runtime/NamedPipeManager.cs +++ b/GoAwayEdge/Common/Runtime/NamedPipeManager.cs @@ -110,13 +110,6 @@ public void SendMessage(string message) } } - - public void StopServer() - { - _isServerRunning = false; - _pipeThread?.Join(); // Wait for ending tasks - } - private void HandleError(Exception ex) { Logging.Log($"Pipe error: {ex.Message}", Logging.LogLevel.ERROR); diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index dbf856e..1018c5f 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -68,7 +68,7 @@ private void CloseButton_OnClick(object sender, RoutedEventArgs e) { Configuration.ShellManager.AppBarManager.SignalGracefulShutdown(); Configuration.ShellManager.Dispose(); - this.Close(); + Environment.Exit(0); } private void DockButton_OnClick(object sender, RoutedEventArgs e) @@ -92,9 +92,8 @@ private void CopilotDock_OnDeactivated(object? sender, EventArgs e) { if (Configuration.AppBarIsAttached) return; var currentProcess = Process.GetCurrentProcess(); - var currentTitle = currentProcess.MainWindowTitle; var currentId = currentProcess.Id; - Logging.Log($"Deactivated CopilotDock (ID: {currentId}, Title: {currentTitle})", Logging.LogLevel.INFO); + Logging.Log($"Deactivated CopilotDock (PID: {currentId})"); WindowManager.HideCopilotDock(); } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs index dc0e5d4..a627af5 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -2,6 +2,8 @@ using GoAwayEdge.Common.Debugging; using GoAwayEdge.Common.Runtime; using ManagedShell.AppBar; +using System.Windows; +using ManagedShell; namespace GoAwayEdge.UserInterface.CopilotDock { @@ -46,7 +48,7 @@ public static void ShowDock() Logging.Log($"Message received: {message}"); if (message.Contains("BringToFront")) { - WindowManager.ShowHiddenCopilotDock(); + WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, mode); } }; diff --git a/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs b/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs index 274d16e..8ebf95b 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs @@ -9,7 +9,6 @@ namespace GoAwayEdge.UserInterface.CopilotDock; public static class WindowManager { private static CopilotDock? _copilotDockInstance; - private static TaskCompletionSource? _closeCompletionSource; public static void ShowCopilotDockAsync(ShellManager shellManager, AppBarScreen screen, AppBarEdge edge, double desiredHeight, AppBarMode mode) { @@ -29,27 +28,29 @@ public static void ShowCopilotDockAsync(ShellManager shellManager, AppBarScreen } else { - _copilotDockInstance.Show(); - _copilotDockInstance.Activate(); + Application.Current.Dispatcher.Invoke(() => + { + _copilotDockInstance.Show(); + _copilotDockInstance.Activate(); + }); } } private static void OnCopilotDockClosed(object sender, System.EventArgs e) { - _closeCompletionSource?.TrySetResult(true); if (_copilotDockInstance != null) _copilotDockInstance.Closed -= OnCopilotDockClosed!; _copilotDockInstance = null; } public static void HideCopilotDock() { - _copilotDockInstance?.Hide(); - } - - public static void ShowHiddenCopilotDock() - { - if (_copilotDockInstance is not { IsVisible: false }) return; - _copilotDockInstance.Show(); - _copilotDockInstance.Activate(); + try + { + _copilotDockInstance?.Hide(); + } + catch (Exception ex) + { + Logging.Log("Failed to hide Copilot Dock: " + ex.Message); + } } } \ No newline at end of file From 225fc58684782e870147ef84b05b8df7d0c2931a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 16 Dec 2024 01:23:25 +0100 Subject: [PATCH 40/80] Moving some settings & new AI Providers - New UI providers (GitHub Copilot & Grok) - Microsoft Edge removal moved to a separate page - AI provider list added to the setup stage --- GoAwayEdge/App.xaml.cs | 93 +++++-------------- GoAwayEdge/Assets/Copilot.xaml | 36 +++---- GoAwayEdge/Assets/CopilotWhite.xaml | 10 ++ GoAwayEdge/Assets/EdgeIcon.xaml | 7 ++ GoAwayEdge/Common/Configuration.cs | 10 +- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 2 + GoAwayEdge/GoAwayEdge.csproj | 13 +-- GoAwayEdge/GoAwayEdge.csproj.user | 6 ++ .../ResourceDictionary.de-DE.xaml | 8 +- .../Localization/ResourceDictionary.xaml | 2 +- .../ControlPanel/Pages/CopilotSettings.xaml | 7 +- .../Pages/CopilotSettings.xaml.cs | 15 ++- .../CopilotDock/CopilotDock.xaml.cs | 11 ++- .../CopilotDock/InterfaceManager.cs | 2 +- .../CopilotDock/WindowManager.cs | 6 -- .../UserInterface/Setup/Installer.xaml.cs | 2 +- .../UserInterface/Setup/Pages/License.xaml.cs | 2 +- .../Setup/Pages/RedirectOrRemove.xaml.cs | 13 ++- .../UserInterface/Setup/Pages/Settings.xaml | 44 +++++++-- .../Setup/Pages/Settings.xaml.cs | 70 +++++++++++++- 20 files changed, 225 insertions(+), 134 deletions(-) create mode 100644 GoAwayEdge/Assets/CopilotWhite.xaml create mode 100644 GoAwayEdge/Assets/EdgeIcon.xaml diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 6126c8a..4727191 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -27,7 +27,7 @@ namespace GoAwayEdge public partial class App { public static bool IsDebug = false; - + public void Application_Startup(object sender, StartupEventArgs e) { #if DEBUG @@ -50,17 +50,7 @@ public void Application_Startup(object sender, StartupEventArgs e) IsDebug = true; if (IsAdministrator() == false) { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) - { - var startInfo = new ProcessStartInfo(exeName) - { - Verb = "runas", - UseShellExecute = true - }; - Process.Start(startInfo); - } + ElevateAsAdmin(); Environment.Exit(0); return; } @@ -80,18 +70,7 @@ public void Application_Startup(object sender, StartupEventArgs e) { if (IsAdministrator() == false) { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) - { - var startInfo = new ProcessStartInfo(exeName) - { - Verb = "runas", - UseShellExecute = true, - Arguments = string.Join(" ", args) - }; - Process.Start(startInfo); - } + ElevateAsAdmin(string.Join(" ", args)); Environment.Exit(0); return; } @@ -145,18 +124,7 @@ public void Application_Startup(object sender, StartupEventArgs e) if (IsAdministrator() == false) { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) - { - var startInfo = new ProcessStartInfo(exeName) - { - Verb = "runas", - UseShellExecute = true, - Arguments = string.Join(" ", args) - }; - Process.Start(startInfo); - } + ElevateAsAdmin(string.Join(" ", args)); Environment.Exit(0); return; } @@ -223,22 +191,8 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") - { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) - { - var startInfo = new ProcessStartInfo(exeName) - { - Verb = "runas", - UseShellExecute = true, - Arguments = "--update" - }; - Process.Start(startInfo); - } - Environment.Exit(0); - return; - } + ElevateAsAdmin("--update"); + Environment.Exit(0); } Updater.ModifyIfeoBinary(ModifyAction.Update); @@ -253,22 +207,8 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") - { - // Restart program and run as admin - var exeName = Process.GetCurrentProcess().MainModule?.FileName; - if (exeName != null) - { - var startInfo = new ProcessStartInfo(exeName) - { - Verb = "runas", - UseShellExecute = true, - Arguments = "--update" - }; - Process.Start(startInfo); - } - Environment.Exit(0); - return; - } + ElevateAsAdmin("--update"); + Environment.Exit(0); } Updater.ModifyIfeoBinary(ModifyAction.Create); @@ -285,7 +225,21 @@ public void Application_Startup(object sender, StartupEventArgs e) ArgumentParse.Parse(args); Environment.Exit(0); } - + + private void ElevateAsAdmin(string arguments = null) + { + // Restart program and run as admin + var exeName = Process.GetCurrentProcess().MainModule?.FileName; + if (exeName == null) return; + var startInfo = new ProcessStartInfo(exeName) + { + Verb = "runas", + UseShellExecute = true, + Arguments = arguments + }; + Process.Start(startInfo); + } + private static string? ParseCustomSearchEngine(string argument) { var argParsed = argument.Remove(0, 6); @@ -293,6 +247,7 @@ public void Application_Startup(object sender, StartupEventArgs e) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); return result ? argParsed : null; } + private static bool IsAdministrator() { var identity = WindowsIdentity.GetCurrent(); diff --git a/GoAwayEdge/Assets/Copilot.xaml b/GoAwayEdge/Assets/Copilot.xaml index 118dade..32c2ca9 100644 --- a/GoAwayEdge/Assets/Copilot.xaml +++ b/GoAwayEdge/Assets/Copilot.xaml @@ -1,14 +1,14 @@ - F1 M48,48z M0,0z M21.676,19.303C21.676,19.303,22.49,16.048,26.367,15.904L38.144,15.904C38.144,15.904 34.745,15.617 34.075,11.5 33.405,7.383 31.634,5.755 29.144,5.707 26.655,5.659 25.506,8.292 25.218,9.202 24.931,10.112 21.676,19.303 21.676,19.303z - F1 M48,48z M0,0z M19.234,29.261L25.266,9.011C25.266,9.011,26.415,5.612,29.144,5.708L14.016,5.708C14.016,5.708 11.431,5.708 9.564,8.676 9.564,8.676 6.692,12.41 5.016,20.07 3.34,27.73 4.011,28.16 4.011,28.16 4.011,28.16 3.58,32.373 10.043,32.038L15.022,32.038C15.021,32.037,18.037,32.085,19.234,29.261z - F1 M48,48z M0,0z M28.887,6.707L31.358,6.303C30.762,5.945,30.048,5.759,29.308,5.719L29.109,5.708C29.105,5.708 29.102,5.708 29.098,5.707 29.082,5.707 29.067,5.709 29.05,5.709 28.875,5.708 28.71,5.724 28.548,5.748 28.479,5.758 28.412,5.771 28.346,5.785 28.241,5.808 28.14,5.837 28.041,5.869 27.589,6.018 27.193,6.255 26.855,6.546 26.738,6.648 26.63,6.755 26.526,6.866 25.765,7.677 25.344,8.699 25.186,9.2 25.147,9.325 25.047,9.616 24.912,10.008L22.694,17.452C22.78,17.36 22.892,17.273 22.991,17.183 23.047,17.132 23.099,17.08 23.159,17.031 23.247,16.959 23.339,16.892 23.436,16.823 23.602,16.705 23.777,16.592 23.973,16.49 23.998,16.477 24.016,16.46 24.042,16.447L26.173,9.293C26.174,9.296,27.066,6.787,28.887,6.707z - F1 M48,48z M0,0z M28.864,6.207L30.34,5.867C30.34,5.867 29.654,5.691 29.088,5.712 28.668,5.727 28.286,5.784 27.941,5.915 27.914,5.926 27.885,5.934 27.858,5.946 27.777,5.979 27.699,6.019 27.622,6.058 27.565,6.088 27.507,6.117 27.452,6.149 27.404,6.177 27.358,6.207 27.311,6.237 27.226,6.293 27.142,6.351 27.062,6.413 27.045,6.426 27.029,6.439 27.013,6.452 26.584,6.798 26.24,7.219 25.974,7.62 25.968,7.629 25.962,7.637 25.957,7.646 25.928,7.69 25.904,7.732 25.877,7.776 25.535,8.338 25.321,8.88 25.219,9.204 25.201,9.262 25.169,9.356 25.128,9.478L22.751,17.456C22.931,17.262,23.139,17.071,23.377,16.893L25.682,9.155C25.685,9.143,26.684,6.292,28.864,6.207z - F1 M48,48z M0,0z M26.474,28.607C26.474,28.607,25.66,31.862,21.783,32.006L10.006,32.006C10.006,32.006 13.405,32.293 14.075,36.41 14.745,40.527 16.516,42.155 19.006,42.203 21.496,42.251 22.644,39.618 22.932,38.708 23.219,37.799 26.474,28.607 26.474,28.607z - F1 M48,48z M0,0z M19.255,41.171L16.784,41.575C17.38,41.933,18.094,42.119,18.834,42.159L19.033,42.17C19.037,42.17 19.04,42.17 19.044,42.171 19.06,42.171 19.075,42.169 19.092,42.169 19.267,42.17 19.432,42.154 19.594,42.13 19.663,42.12 19.73,42.107 19.796,42.093 19.901,42.07 20.002,42.041 20.101,42.009 20.553,41.86 20.949,41.623 21.287,41.332 21.404,41.23 21.512,41.123 21.616,41.012 22.377,40.201 22.798,39.179 22.956,38.678 22.995,38.553 23.095,38.262 23.23,37.87L25.448,30.426C25.362,30.518 25.25,30.605 25.151,30.695 25.095,30.746 25.043,30.798 24.983,30.847 24.895,30.919 24.803,30.986 24.706,31.055 24.54,31.173 24.365,31.286 24.169,31.388 24.144,31.401 24.126,31.418 24.1,31.431L21.969,38.585C21.969,38.582,21.077,41.091,19.255,41.171z - F1 M48,48z M0,0z M19.278,41.671L17.802,42.011C17.802,42.011 18.488,42.187 19.054,42.166 19.474,42.151 19.856,42.094 20.201,41.963 20.228,41.952 20.257,41.944 20.284,41.932 20.365,41.899 20.443,41.859 20.52,41.82 20.577,41.79 20.635,41.761 20.69,41.729 20.738,41.701 20.784,41.671 20.831,41.641 20.916,41.585 21,41.527 21.08,41.465 21.097,41.452 21.113,41.439 21.129,41.426 21.558,41.08 21.902,40.659 22.168,40.258 22.174,40.249 22.18,40.241 22.185,40.232 22.214,40.188 22.238,40.146 22.265,40.102 22.607,39.54 22.821,38.998 22.923,38.674 22.941,38.616 22.973,38.522 23.014,38.4L25.391,30.422C25.211,30.616,25.003,30.807,24.765,30.985L22.46,38.723C22.457,38.736,21.458,41.586,19.278,41.671z - F1 M48,48z M0,0z M28.915,18.65L22.845,38.913C22.845,38.913,21.734,42.299,19.006,42.203L34.134,42.203C34.134,42.203 36.719,42.203 38.586,39.235 38.586,39.235 41.458,35.501 43.134,27.841 44.81,20.181 44.139,19.751 44.139,19.751 44.139,19.751 44.57,15.538 38.107,15.873L33.128,15.873C33.128,15.873,30.112,15.826,28.915,18.65z - - + F1 M48,48z M0,0z M21.676,19.303C21.676,19.303,22.49,16.048,26.367,15.904L38.144,15.904C38.144,15.904 34.745,15.617 34.075,11.5 33.405,7.383 31.634,5.755 29.144,5.707 26.655,5.659 25.506,8.292 25.218,9.202 24.931,10.112 21.676,19.303 21.676,19.303z + F1 M48,48z M0,0z M19.234,29.261L25.266,9.011C25.266,9.011,26.415,5.612,29.144,5.708L14.016,5.708C14.016,5.708 11.431,5.708 9.564,8.676 9.564,8.676 6.692,12.41 5.016,20.07 3.34,27.73 4.011,28.16 4.011,28.16 4.011,28.16 3.58,32.373 10.043,32.038L15.022,32.038C15.021,32.037,18.037,32.085,19.234,29.261z + F1 M48,48z M0,0z M28.887,6.707L31.358,6.303C30.762,5.945,30.048,5.759,29.308,5.719L29.109,5.708C29.105,5.708 29.102,5.708 29.098,5.707 29.082,5.707 29.067,5.709 29.05,5.709 28.875,5.708 28.71,5.724 28.548,5.748 28.479,5.758 28.412,5.771 28.346,5.785 28.241,5.808 28.14,5.837 28.041,5.869 27.589,6.018 27.193,6.255 26.855,6.546 26.738,6.648 26.63,6.755 26.526,6.866 25.765,7.677 25.344,8.699 25.186,9.2 25.147,9.325 25.047,9.616 24.912,10.008L22.694,17.452C22.78,17.36 22.892,17.273 22.991,17.183 23.047,17.132 23.099,17.08 23.159,17.031 23.247,16.959 23.339,16.892 23.436,16.823 23.602,16.705 23.777,16.592 23.973,16.49 23.998,16.477 24.016,16.46 24.042,16.447L26.173,9.293C26.174,9.296,27.066,6.787,28.887,6.707z + F1 M48,48z M0,0z M28.864,6.207L30.34,5.867C30.34,5.867 29.654,5.691 29.088,5.712 28.668,5.727 28.286,5.784 27.941,5.915 27.914,5.926 27.885,5.934 27.858,5.946 27.777,5.979 27.699,6.019 27.622,6.058 27.565,6.088 27.507,6.117 27.452,6.149 27.404,6.177 27.358,6.207 27.311,6.237 27.226,6.293 27.142,6.351 27.062,6.413 27.045,6.426 27.029,6.439 27.013,6.452 26.584,6.798 26.24,7.219 25.974,7.62 25.968,7.629 25.962,7.637 25.957,7.646 25.928,7.69 25.904,7.732 25.877,7.776 25.535,8.338 25.321,8.88 25.219,9.204 25.201,9.262 25.169,9.356 25.128,9.478L22.751,17.456C22.931,17.262,23.139,17.071,23.377,16.893L25.682,9.155C25.685,9.143,26.684,6.292,28.864,6.207z + F1 M48,48z M0,0z M26.474,28.607C26.474,28.607,25.66,31.862,21.783,32.006L10.006,32.006C10.006,32.006 13.405,32.293 14.075,36.41 14.745,40.527 16.516,42.155 19.006,42.203 21.496,42.251 22.644,39.618 22.932,38.708 23.219,37.799 26.474,28.607 26.474,28.607z + F1 M48,48z M0,0z M19.255,41.171L16.784,41.575C17.38,41.933,18.094,42.119,18.834,42.159L19.033,42.17C19.037,42.17 19.04,42.17 19.044,42.171 19.06,42.171 19.075,42.169 19.092,42.169 19.267,42.17 19.432,42.154 19.594,42.13 19.663,42.12 19.73,42.107 19.796,42.093 19.901,42.07 20.002,42.041 20.101,42.009 20.553,41.86 20.949,41.623 21.287,41.332 21.404,41.23 21.512,41.123 21.616,41.012 22.377,40.201 22.798,39.179 22.956,38.678 22.995,38.553 23.095,38.262 23.23,37.87L25.448,30.426C25.362,30.518 25.25,30.605 25.151,30.695 25.095,30.746 25.043,30.798 24.983,30.847 24.895,30.919 24.803,30.986 24.706,31.055 24.54,31.173 24.365,31.286 24.169,31.388 24.144,31.401 24.126,31.418 24.1,31.431L21.969,38.585C21.969,38.582,21.077,41.091,19.255,41.171z + F1 M48,48z M0,0z M19.278,41.671L17.802,42.011C17.802,42.011 18.488,42.187 19.054,42.166 19.474,42.151 19.856,42.094 20.201,41.963 20.228,41.952 20.257,41.944 20.284,41.932 20.365,41.899 20.443,41.859 20.52,41.82 20.577,41.79 20.635,41.761 20.69,41.729 20.738,41.701 20.784,41.671 20.831,41.641 20.916,41.585 21,41.527 21.08,41.465 21.097,41.452 21.113,41.439 21.129,41.426 21.558,41.08 21.902,40.659 22.168,40.258 22.174,40.249 22.18,40.241 22.185,40.232 22.214,40.188 22.238,40.146 22.265,40.102 22.607,39.54 22.821,38.998 22.923,38.674 22.941,38.616 22.973,38.522 23.014,38.4L25.391,30.422C25.211,30.616,25.003,30.807,24.765,30.985L22.46,38.723C22.457,38.736,21.458,41.586,19.278,41.671z + F1 M48,48z M0,0z M28.915,18.65L22.845,38.913C22.845,38.913,21.734,42.299,19.006,42.203L34.134,42.203C34.134,42.203 36.719,42.203 38.586,39.235 38.586,39.235 41.458,35.501 43.134,27.841 44.81,20.181 44.139,19.751 44.139,19.751 44.139,19.751 44.57,15.538 38.107,15.873L33.128,15.873C33.128,15.873,30.112,15.826,28.915,18.65z + + @@ -18,7 +18,7 @@ - + @@ -36,17 +36,17 @@ - + - + - + @@ -57,17 +57,17 @@ - + - + - + @@ -77,5 +77,5 @@ - + \ No newline at end of file diff --git a/GoAwayEdge/Assets/CopilotWhite.xaml b/GoAwayEdge/Assets/CopilotWhite.xaml new file mode 100644 index 0000000..ab29391 --- /dev/null +++ b/GoAwayEdge/Assets/CopilotWhite.xaml @@ -0,0 +1,10 @@ + + F1 M37,32z M0,0z M35.9718,9.96262C35.1149,8.80378,33.7888,8.14,32.3347,8.14L30.1805,8.14 28.5052,8.14 26.9512,3.14352C26.4006,1.29278,24.649,0,22.6932,0L22.4105,0 11.6361,0C8.0131,0,4.87994,2.331,3.8395,5.8016L0.190558,17.9642C-0.216442,19.3221 0.0351583,20.7533 0.881718,21.8907 1.72754,23.0273 3.02624,23.68 4.44334,23.68L7.84438,23.68C8.6162,23.9686,9.37174,24.4318,9.6559,26.1079L9.76838,26.7858C10.2242,29.5719 10.5254,31.4123 13.9753,31.8148 14.0041,31.8185 14.033,31.82 14.0604,31.82L25.019,31.82C28.6968,31.82,31.8781,29.4905,32.9348,26.0221L36.6467,13.8587C37.0574,12.5156,36.8109,11.0948,35.9718,9.96262z M22.4105,1.48L22.6932,1.48C24.0001,1.48,25.1678,2.33766,25.5363,3.5742L26.9556,8.14 25.3328,8.14C24.5173,8.14 23.7573,8.39604 23.1357,8.8393 23.0825,8.81858 23.0321,8.7912 22.9722,8.78306 20.8972,8.50482 19.4261,8.81488 18.3923,9.31068L19.623,5.20812C19.9885,3.99156,21.1496,1.48,22.4105,1.48z M21.9858,10.1735C21.8896,10.3637,21.8052,10.5628,21.7416,10.7729L18.3805,21.7878C17.5739,22.1785 15.7424,22.2673 14.2365,22.2585 14.514,21.9025 14.7367,21.4977 14.8729,21.0426L17.6235,11.874C17.8899,11.4064,18.9525,9.99814,21.9858,10.1735z M4.44334,22.2C3.4991,22.2 2.6333,21.7649 2.06868,21.0071 1.5048,20.2494 1.33682,19.2955 1.6084,18.3897L5.25734,6.22636C6.10908,3.38772,8.67244,1.48,11.6361,1.48L19.8575,1.48C18.8371,2.7713,18.2947,4.4844,18.2051,4.78262L16.2449,11.3168C16.2005,11.4056 16.1753,11.467 16.1694,11.4833 16.1442,11.5477 16.142,11.6136 16.1361,11.6794L13.4543,20.6186C13.1709,21.5643,12.3155,22.2,11.3276,22.2L10.7555,22.2 4.44334,22.2z M14.087,30.337C11.8071,30.0581,11.6791,29.3003,11.2284,26.5468L11.1152,25.8608C10.9524,24.8995,10.6431,24.2032,10.2627,23.68L11.3276,23.68C11.3298,23.68,11.332,23.6793,11.3342,23.6793L12.371,23.6785C12.5708,23.6918 13.4033,23.7429 14.4415,23.7429 15.5219,23.7429 16.8198,23.6844 17.8655,23.4743L16.9094,26.6082C16.6149,27.5702,15.4656,30.3015,14.087,30.337z M35.2318,13.4273L31.5199,25.5907C30.6667,28.3864,27.9938,30.34,25.019,30.34L16.6489,30.34C17.6827,29.0502,18.2347,27.3386,18.325,27.0411L23.1565,11.2058C23.4421,10.2719,24.3368,9.62,25.3321,9.62L27.9605,9.62 30.1805,9.62 32.3347,9.62C33.3144,9.62 34.2069,10.0662 34.7826,10.8425 35.3398,11.5951 35.5026,12.5363 35.2318,13.4273z + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/Assets/EdgeIcon.xaml b/GoAwayEdge/Assets/EdgeIcon.xaml new file mode 100644 index 0000000..d941c18 --- /dev/null +++ b/GoAwayEdge/Assets/EdgeIcon.xaml @@ -0,0 +1,7 @@ + + F1 M37,36z M0,0z M18.3169,1.6453E-05C10.5041,1.6453E-05 3.85789,4.6666 1.13039,11.9701 3.35676,9.52188 6.30504,8.21538 9.73085,8.21538L9.75652,8.21538C15.0719,8.2236,20.6898,11.5841,22.5465,15.8643L22.5385,15.8643C23.2039,17.1624 23.0489,18.5017 22.8353,19.3478 22.5889,20.309 22.2192,20.7604 22.0796,20.9412L22.0042,21.039C21.733,21.3759 21.7752,21.8697 22.0956,22.1655 22.1531,22.2147 22.2436,22.2807 22.3668,22.3628L22.5802,22.4944C23.6236,23.1516 25.9815,23.8246 28.1175,23.8246 29.7524,23.8246 31.8878,23.5701 33.8924,21.5573 37.2607,18.189 35.9622,13.4894 35.4857,12.1257 34.6724,9.81717 31.2968,2.14434 21.8244,0.336961 20.6743,0.115147 19.4917,1.6453E-05 18.3169,1.6453E-05z M9.73085,9.85845C5.45886,9.85845 2.03344,12.2499 0.0617534,16.604 -0.58726,24.1293 3.97176,30.8812 9.39389,33.9044 10.1743,34.3399 12.6551,35.5892 16.1138,36 13.0577,34.5541 10.7331,32.0317 9.66506,28.7538 7.89054,23.307 10.1172,17.4911 15.334,13.9421L15.342,13.9501C16.1307,13.4325 17.0919,13.1366 18.0778,13.1366 18.1928,13.1366 18.2997,13.1362 18.4148,13.1526 16.1062,11.1809 12.8373,9.86667 9.75653,9.85845L9.73085,9.85845z M13.1405,18.2134C10.8567,21.1463 10.1088,24.7865 11.2343,28.2451 12.7213,32.8129 17.0679,35.7044 22.3668,35.7208 26.4909,34.8007 30.0801,32.3926 33.0869,28.5067L33.1607,28.4088C33.3661,28.1048 33.3506,27.7015 33.1206,27.414 32.8823,27.1347 32.4882,27.0367 32.1514,27.1845L31.7567,27.3658C31.5924,27.4398 31.4448,27.4879 31.2641,27.5536 31.0751,27.6193 30.8615,27.7017 30.5821,27.8167 29.5224,28.2521 27.9454,28.4987 26.253,28.4987 24.8318,28.4987 23.4434,28.3186 22.3507,27.99 20.8062,27.53 16.0976,26.1082 13.6412,20.6861 13.3372,20.0124 13.1323,19.15 13.1405,18.2134z + + + + + \ No newline at end of file diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 11ce286..7866071 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -26,6 +26,8 @@ public enum AiProvider Copilot, ChatGPT, Gemini, + GitHub_Copilot, + Grok, Custom } @@ -64,7 +66,7 @@ internal class Configuration /// /// Boolean status of the initialization. /// - public static bool InitialEnvironment() + public static bool InitialEnvironment(bool setupRunning = false) { // Check if Edge is installed try @@ -79,7 +81,7 @@ public static bool InitialEnvironment() return true; } - if (!CopilotDockPipeAvailable()) + if (!IsCopilotDockPipeAvailable() && !setupRunning) { Logging.Log("Copilot Dock (Pipe) is not available - spawning ShellManager"); try { ShellManager = new ShellManager(); } @@ -128,7 +130,7 @@ public static bool InitialEnvironment() } } - public static bool CopilotDockPipeAvailable() + public static bool IsCopilotDockPipeAvailable() { try { @@ -202,7 +204,7 @@ public static List GetAiProviders() { var list = (from aiProvider in (AiProvider[])Enum.GetValues(typeof(AiProvider)) where aiProvider != AiProvider.Custom - select aiProvider.ToString()).ToList(); + select aiProvider.ToString().Replace("_", " ")).ToList(); try { diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 884c0c1..111f7f9 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -192,6 +192,8 @@ public static AiProvider ParseAiProvider(string argument) "copilot" => AiProvider.Copilot, "chatgpt" => AiProvider.ChatGPT, "gemini" => AiProvider.Gemini, + "github_copilot" => AiProvider.GitHub_Copilot, + "grok" => AiProvider.Grok, "custom" => AiProvider.Custom, _ => AiProvider.Copilot // Fallback channel }; diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index 77d5b08..e32a552 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -12,7 +12,7 @@ GoAwayEdge Exploitox valnoxy - 2.0.0.213 + 2.0.0.231 Copyright © 2018 - 2024 Exploitox. All rights reserved. https://github.com/valnoxy/GoAwayEdge https://github.com/valnoxy/GoAwayEdge @@ -43,10 +43,7 @@ - - Designer - MSBuild:Compile - + @@ -55,10 +52,10 @@ - + - - + + diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 61534d1..3dd6034 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -45,12 +45,18 @@ Designer + + Designer + Designer Designer + + Designer + Designer diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 8bcc269..9362eab 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -20,8 +20,8 @@ Ich lehne diese Lizenz ab. Einstellungen - Edge Channel - Wählen Sie den installierten Microsoft Edge Channel aus. + Edge Kanal + Wählen Sie den installierten Microsoft Edge Kanal aus. Suchmaschine Wählen Sie Ihre bevorzugte Suchmaschine. Benutzerdefiniert @@ -72,4 +72,8 @@ Deaktiviere die Weiterleitung von Suchanfragen an anderen Browsern. GoAwayEdge wurde auf diesem System erfolgreich aktiviert. GoAwayEdge konnte auf diesem System nicht deaktiviert werden: {0} + KI Anbieter + Wechseln Sie den Anbieter Ihrer bevorzugten KI (oder zu Ihrer bevorzugten Webseite). + Benutzerdefinierter KI Anbieter + Bitte geben Sie die URL des KI-Anbieters (oder einer Webseite) ein. diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 561f724..8aea2b7 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -59,7 +59,7 @@ Deactivate the forwarding of search queries to other browsers. Enable GoAwayEdge Disable GoAwayEdge - Change AI Provider + AI Provider Change the provider to your favorite AI (or to your favorite website). Custom AI Provider Please enter the URL from the AI Provider (or your favorite website). diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml index 1af8558..01f30cc 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml @@ -13,7 +13,10 @@ - + + + + @@ -55,7 +58,7 @@ Text="{DynamicResource ControlPanelCustomCopilotProviderDescription}"/> - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs index c582a63..32dfe94 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -18,7 +18,7 @@ public CopilotSettings() { CopilotProviderBox.Items.Add(aiProvider); } - CopilotProviderBox.SelectedItem = Configuration.Provider.ToString(); + CopilotProviderBox.SelectedItem = Configuration.Provider.ToString().Replace("_", " "); if (Configuration.Provider == AiProvider.Custom) { @@ -30,7 +30,7 @@ public CopilotSettings() } else { - CopilotProviderBox.SelectedItem = Configuration.Search.ToString(); + CopilotProviderBox.SelectedItem = Configuration.Provider.ToString(); } } @@ -67,19 +67,24 @@ private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChang case 0: Configuration.Provider = AiProvider.Copilot; CustomSearchPanel.Visibility = Visibility.Collapsed; - FlushSettings(); break; case 1: Configuration.Provider = AiProvider.ChatGPT; CustomSearchPanel.Visibility = Visibility.Collapsed; - FlushSettings(); break; case 2: Configuration.Provider = AiProvider.Gemini; CustomSearchPanel.Visibility = Visibility.Collapsed; - FlushSettings(); break; case 3: + Configuration.Provider = AiProvider.GitHub_Copilot; + CustomSearchPanel.Visibility = Visibility.Collapsed; + break; + case 4: + Configuration.Provider = AiProvider.Grok; + CustomSearchPanel.Visibility = Visibility.Collapsed; + break; + case 5: Configuration.Provider = AiProvider.Custom; CustomSearchPanel.Visibility = Visibility.Visible; break; diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index 1018c5f..d6e9e35 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -20,8 +20,8 @@ public partial class CopilotDock public CopilotDock(ShellManager shellManager, AppBarScreen screen, AppBarEdge edge, double desiredHeight, AppBarMode mode) : base(shellManager.AppBarManager, shellManager.ExplorerHelper, shellManager.FullScreenHelper, screen, edge, mode, desiredHeight) { - this.MaxHeight = SystemParameters.WorkArea.Height; - this.MinHeight = SystemParameters.WorkArea.Height; + MaxHeight = SystemParameters.WorkArea.Height; + MinHeight = SystemParameters.WorkArea.Height; Configuration.AppBarIsAttached = mode != AppBarMode.None; Instance = this; @@ -49,10 +49,17 @@ private async Task InitializeWebViewAsync() case Gemini: WebView.Source = new Uri("https://gemini.google.com/"); break; + case GitHub_Copilot: + WebView.Source = new Uri("https://github.com/copilot"); + break; + case Grok: + WebView.Source = new Uri("https://x.com/i/grok"); + break; case Custom: if (Configuration.CustomProviderUrl != null) WebView.Source = new Uri(Configuration.CustomProviderUrl); break; + case Copilot: default: Logging.Log($"Failed to load Provider! Provider Value '{Configuration.Provider}' in invalid!"); throw new ArgumentOutOfRangeException(); diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs index a627af5..123209a 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -48,7 +48,7 @@ public static void ShowDock() Logging.Log($"Message received: {message}"); if (message.Contains("BringToFront")) { - WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, mode); + WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, mode); // Dummy data } }; diff --git a/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs b/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs index 8ebf95b..85a8e91 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/WindowManager.cs @@ -36,12 +36,6 @@ public static void ShowCopilotDockAsync(ShellManager shellManager, AppBarScreen } } - private static void OnCopilotDockClosed(object sender, System.EventArgs e) - { - if (_copilotDockInstance != null) _copilotDockInstance.Closed -= OnCopilotDockClosed!; - _copilotDockInstance = null; - } - public static void HideCopilotDock() { try diff --git a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs index 71eb733..10da43e 100644 --- a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs @@ -41,7 +41,7 @@ public Installer() } VersionLbl.Content = versionText; - Configuration.InitialEnvironment(); + Configuration.InitialEnvironment(setupRunning: true); _welcomePage = new Welcome(); _redirectOrRemovePage = new RedirectOrRemove(); diff --git a/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs index 8788a4d..c85a954 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/License.xaml.cs @@ -20,7 +20,7 @@ public License() const string license = @"MIT License -Copyright (c) 2023-2024 valnoxy +Copyright (c) 2023-2025 valnoxy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal diff --git a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs index f3a6ea0..f7195c1 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs @@ -1,5 +1,7 @@ using System.Windows; +using GoAwayEdge.Common.Debugging; using Wpf.Ui; +using Wpf.Ui.Controls; using Wpf.Ui.Extensions; namespace GoAwayEdge.UserInterface.Setup.Pages @@ -20,13 +22,13 @@ private void InstallBtn_Click(object sender, RoutedEventArgs e) Installer.ContentWindow!.NextBtn.IsEnabled = true; } - private void UninstallBtn_Click(object sender, RoutedEventArgs e) + private async void UninstallBtn_Click(object sender, RoutedEventArgs e) { var contentDialogService = new ContentDialogService(); contentDialogService.SetDialogHost(Installer.ContentWindow!.RootContentDialogPresenter); - contentDialogService.ShowSimpleDialogAsync( - new SimpleContentDialogCreateOptions() + var result = await contentDialogService.ShowSimpleDialogAsync( + new SimpleContentDialogCreateOptions { Title = "Warning", Content = "Removing Microsoft Edge can cause serious system issues, as it’s deeply integrated into Windows and essential for many features, including updates, help files, and some apps. Deleting it could result in instability or broken functionality.\n\nOnly proceed if you fully understand the risks and have a reliable backup or restore point in place.", @@ -34,6 +36,11 @@ private void UninstallBtn_Click(object sender, RoutedEventArgs e) CloseButtonText = "Cancel" } ); + + if (result == ContentDialogResult.Primary) + { + Logging.Log("User pressed 'Remove Microsoft Edge'"); + } } } } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml index 2e4055e..4729b28 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml @@ -10,7 +10,10 @@ - + + + + @@ -83,8 +86,11 @@ - - + + + + + @@ -95,13 +101,39 @@ + Text="{DynamicResource ControlPanelCopilotProviderTitle}" /> + Text="{DynamicResource ControlPanelCopilotProviderDescription}" /> - + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index 0bf88b0..885ee62 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -38,9 +38,28 @@ public Settings() SearchEngineBox.SelectedItem = Configuration.Search.ToString(); } + foreach (var aiProvider in Configuration.GetAiProviders()) + { + CopilotProviderBox.Items.Add(aiProvider); + } + CopilotProviderBox.SelectedItem = Configuration.Provider.ToString().Replace("_", " "); + + if (Configuration.Provider == AiProvider.Custom) + { + CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); + CustomSearchPanel.Visibility = Visibility.Visible; + if (Configuration.CustomProviderUrl != null) QueryProviderTextBox.Text = Configuration.CustomProviderUrl; + CustomUrlStatus.Symbol = Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out _) + ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; + } + else + { + CopilotProviderBox.SelectedItem = Configuration.Search.ToString(); + } + if (Configuration.NoEdgeInstalled) { - MsEdgeRemoveStackPanel.IsEnabled = false; + CopilotStackPanel.IsEnabled = false; EdgeStackPanel.IsEnabled = false; } @@ -135,14 +154,55 @@ private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e } } - private void MsEdgeUninstallSwitch_OnClickUninstallSwitch_OnClick(object sender, RoutedEventArgs e) + private void ControlPanelSwitch_OnClick(object sender, RoutedEventArgs e) { - Configuration.UninstallEdge = MsEdgeUninstallSwitch.IsChecked!.Value; + Configuration.InstallControlPanel = ControlPanelSwitch.IsChecked!.Value; } - private void ControlPanelSwitch_OnClick(object sender, RoutedEventArgs e) + private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { - Configuration.InstallControlPanel = ControlPanelSwitch.IsChecked!.Value; + switch (CopilotProviderBox.SelectedIndex) + { + case 0: + Configuration.Provider = AiProvider.Copilot; + CustomAiPanel.Visibility = Visibility.Collapsed; + break; + case 1: + Configuration.Provider = AiProvider.ChatGPT; + CustomAiPanel.Visibility = Visibility.Collapsed; + break; + case 2: + Configuration.Provider = AiProvider.Gemini; + CustomAiPanel.Visibility = Visibility.Collapsed; + break; + case 3: + Configuration.Provider = AiProvider.GitHub_Copilot; + CustomAiPanel.Visibility = Visibility.Collapsed; + break; + case 4: + Configuration.Provider = AiProvider.Grok; + CustomAiPanel.Visibility = Visibility.Collapsed; + break; + case 5: + Configuration.Provider = AiProvider.Custom; + CustomAiPanel.Visibility = Visibility.Visible; + break; + } + } + + private void QueryProviderTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + // Test if the URL is valid + if (Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) + { + CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomProviderUrl = QueryProviderTextBox.Text; + } + else + { + CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + } } } } From 2c440220f434972bc4a68c5d95ad9395922c5f9d Mon Sep 17 00:00:00 2001 From: valnoxy Date: Mon, 16 Dec 2024 00:26:39 +0000 Subject: [PATCH 41/80] Translated using Weblate (German) Currently translated at 100.0% (72 of 72 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/de/ --- GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 9362eab..5ade673 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -76,4 +76,5 @@ Wechseln Sie den Anbieter Ihrer bevorzugten KI (oder zu Ihrer bevorzugten Webseite). Benutzerdefinierter KI Anbieter Bitte geben Sie die URL des KI-Anbieters (oder einer Webseite) ein. + Die Einstellungen konnten nicht übernommen werden: {0} From 6859115ced93c9f3bbc2eb37e3acd4b59beecf0a Mon Sep 17 00:00:00 2001 From: valnoxy Date: Mon, 16 Dec 2024 00:30:32 +0000 Subject: [PATCH 42/80] Translated using Weblate (French) Currently translated at 100.0% (72 of 72 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/fr/ --- .../ResourceDictionary.fr-FR.xaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml index 53a5a4b..87a926b 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml @@ -56,4 +56,25 @@ Création réussie La version non-IEFO de Edge a été créée avec succès. Sauter cette version + Impossible de désactiver GoAwayEdge sur ce système : {0} + Panneau de contrôle GoAwayEdge + Bienvenue à GoAwayEdge + Microsoft Edge + Windows Copilot + Gérer les moteurs de recherche et plus encore. + Gestion des touches de raccourci et plus encore. + Activer/désactiver GoAwayEdge + Désactiver la transmission des requêtes de recherche à d'autres navigateurs. + Activer GoAwayEdge + Désactiver GoAwayEdge + Installer le panneau de contrôle + Installez le panneau de contrôle pour configurer GoAwayEdge plus facilement. + Fournisseur d'IA + Changez de fournisseur pour votre IA préférée (ou pour votre site web préféré). + Fournisseur d'IA sur mesure + Veuillez saisir l'URL du fournisseur d'IA (ou votre site web préféré). + GoAwayEdge a été activé avec succès sur ce système. + GoAwayEdge a été désactivé avec succès sur ce système. + Impossible d'activer GoAwayEdge sur ce système : {0} + Impossible d'appliquer les paramètres : {0} From 4560a65df6b706e579d1d38417755da4a2930c5e Mon Sep 17 00:00:00 2001 From: valnoxy Date: Mon, 16 Dec 2024 00:31:14 +0000 Subject: [PATCH 43/80] Translated using Weblate (Italian) Currently translated at 100.0% (72 of 72 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/it/ --- .../ResourceDictionary.it-IT.xaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml index c09164e..383cc59 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml @@ -56,4 +56,25 @@ Creazione riuscita La versione non IFO di Edge è stata creata con successo. Salta questa versione + Disattivare l'inoltro delle query di ricerca ad altri browser. + Inserire l'URL del provider AI (o del proprio sito web preferito). + Pannello di controllo GoAwayEdge + Benvenuti a GoAwayEdge + Microsoft Edge + Windows Copilot + Gestire i motori di ricerca e altro ancora. + Gestione dei tasti di scelta rapida e altro ancora. + Abilitazione/disabilitazione di GoAwayEdge + Abilitare GoAwayEdge + Disattivare GoAwayEdge + Installare il pannello di controllo + Installate il Pannello di controllo per configurare GoAwayEdge più facilmente. + Fornitore di AI + Cambiare il provider con il vostro AI preferito (o con il vostro sito web preferito). + Fornitore di intelligenza artificiale personalizzata + GoAwayEdge è stato attivato con successo su questo sistema. + GoAwayEdge è stato disattivato con successo su questo sistema. + Impossibile abilitare GoAwayEdge su questo sistema: {0} + Impossibile disattivare GoAwayEdge su questo sistema: {0} + Impossibile applicare le impostazioni: {0} From 60646ca02a423b5d0f79ebae2c197e8c92fec92b Mon Sep 17 00:00:00 2001 From: valnoxy Date: Mon, 16 Dec 2024 00:28:36 +0000 Subject: [PATCH 44/80] Translated using Weblate (Danish) Currently translated at 100.0% (72 of 72 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/da/ --- GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml index 76ce337..b01462f 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml @@ -66,4 +66,9 @@ Spring denne version over Den alternative opstartsfil for Edge er blevet opdateret. Kunne ikke deaktivere GoAwayEdge på dette system: {0} + AI-udbyder + Skift udbyder til din foretrukne AI (eller til din foretrukne hjemmeside). + Brugerdefineret AI-udbyder + Indtast venligst URL'en fra AI-udbyderen (eller din foretrukne hjemmeside). + Kunne ikke anvende indstillingerne: {0} From bd36fd59a94bb95fec1c02758eef094ab459b188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Tue, 17 Dec 2024 00:48:10 +0100 Subject: [PATCH 45/80] Added Weather service support - Default, Weather.com, AccuWeather & Custom --- GoAwayEdge/App.xaml.cs | 6 +- GoAwayEdge/Assets/CopilotWhite.xaml | 10 -- GoAwayEdge/Assets/EdgeIcon.xaml | 7 - GoAwayEdge/Assets/Settings.xaml | 13 ++ GoAwayEdge/Common/Configuration.cs | 115 +++++++++++++-- .../Common/Installation/InstallRoutine.cs | 23 ++- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 31 +++- GoAwayEdge/Common/Runtime/UrlParse.cs | 2 +- GoAwayEdge/Common/Runtime/Weather.cs | 61 ++++++++ GoAwayEdge/GoAwayEdge.csproj | 4 +- GoAwayEdge/GoAwayEdge.csproj.user | 6 - .../ResourceDictionary.de-DE.xaml | 10 ++ .../Localization/ResourceDictionary.xaml | 11 ++ .../ControlPanel/Pages/CopilotSettings.xaml | 2 +- .../Pages/CopilotSettings.xaml.cs | 32 ++--- .../ControlPanel/Pages/EdgeSettings.xaml | 50 +++++++ .../ControlPanel/Pages/EdgeSettings.xaml.cs | 71 ++++++++++ .../CopilotDock/CopilotDock.xaml.cs | 8 +- .../Setup/Pages/RedirectOrRemove.xaml | 8 +- .../UserInterface/Setup/Pages/Settings.xaml | 56 +++++++- .../Setup/Pages/Settings.xaml.cs | 134 +++++++++++++----- 21 files changed, 552 insertions(+), 108 deletions(-) delete mode 100644 GoAwayEdge/Assets/CopilotWhite.xaml delete mode 100644 GoAwayEdge/Assets/EdgeIcon.xaml create mode 100644 GoAwayEdge/Common/Runtime/Weather.cs diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 4727191..b58d430 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -1,6 +1,6 @@ /* * GoAwayEdge - * Copyright (c) 2018 - 2024 valnoxy. + * Copyright (c) 2018 - 2025 Exploitox (valnoxy). * * GoAwayEdge is licensed under MIT License (https://github.com/valnoxy/GoAwayEdge/blob/main/LICENSE). * So you are allowed to use freely and modify the application. @@ -93,10 +93,10 @@ public void Application_Startup(object sender, StartupEventArgs e) { Configuration.InitialEnvironment(); - if (Configuration.Provider != AiProvider.Copilot) + if (Configuration.AiProvider != AiProvider.Copilot) { DebugMessage.DisplayDebugMessage("GoAwayEdge", - $"Opening AI Provider '{Configuration.Provider}' (Triggered with argument) ..."); + $"Opening AI Provider '{Configuration.AiProvider}' (Triggered with argument) ..."); UserInterface.CopilotDock.InterfaceManager.ShowDock(); Environment.Exit(0); } diff --git a/GoAwayEdge/Assets/CopilotWhite.xaml b/GoAwayEdge/Assets/CopilotWhite.xaml deleted file mode 100644 index ab29391..0000000 --- a/GoAwayEdge/Assets/CopilotWhite.xaml +++ /dev/null @@ -1,10 +0,0 @@ - - F1 M37,32z M0,0z M35.9718,9.96262C35.1149,8.80378,33.7888,8.14,32.3347,8.14L30.1805,8.14 28.5052,8.14 26.9512,3.14352C26.4006,1.29278,24.649,0,22.6932,0L22.4105,0 11.6361,0C8.0131,0,4.87994,2.331,3.8395,5.8016L0.190558,17.9642C-0.216442,19.3221 0.0351583,20.7533 0.881718,21.8907 1.72754,23.0273 3.02624,23.68 4.44334,23.68L7.84438,23.68C8.6162,23.9686,9.37174,24.4318,9.6559,26.1079L9.76838,26.7858C10.2242,29.5719 10.5254,31.4123 13.9753,31.8148 14.0041,31.8185 14.033,31.82 14.0604,31.82L25.019,31.82C28.6968,31.82,31.8781,29.4905,32.9348,26.0221L36.6467,13.8587C37.0574,12.5156,36.8109,11.0948,35.9718,9.96262z M22.4105,1.48L22.6932,1.48C24.0001,1.48,25.1678,2.33766,25.5363,3.5742L26.9556,8.14 25.3328,8.14C24.5173,8.14 23.7573,8.39604 23.1357,8.8393 23.0825,8.81858 23.0321,8.7912 22.9722,8.78306 20.8972,8.50482 19.4261,8.81488 18.3923,9.31068L19.623,5.20812C19.9885,3.99156,21.1496,1.48,22.4105,1.48z M21.9858,10.1735C21.8896,10.3637,21.8052,10.5628,21.7416,10.7729L18.3805,21.7878C17.5739,22.1785 15.7424,22.2673 14.2365,22.2585 14.514,21.9025 14.7367,21.4977 14.8729,21.0426L17.6235,11.874C17.8899,11.4064,18.9525,9.99814,21.9858,10.1735z M4.44334,22.2C3.4991,22.2 2.6333,21.7649 2.06868,21.0071 1.5048,20.2494 1.33682,19.2955 1.6084,18.3897L5.25734,6.22636C6.10908,3.38772,8.67244,1.48,11.6361,1.48L19.8575,1.48C18.8371,2.7713,18.2947,4.4844,18.2051,4.78262L16.2449,11.3168C16.2005,11.4056 16.1753,11.467 16.1694,11.4833 16.1442,11.5477 16.142,11.6136 16.1361,11.6794L13.4543,20.6186C13.1709,21.5643,12.3155,22.2,11.3276,22.2L10.7555,22.2 4.44334,22.2z M14.087,30.337C11.8071,30.0581,11.6791,29.3003,11.2284,26.5468L11.1152,25.8608C10.9524,24.8995,10.6431,24.2032,10.2627,23.68L11.3276,23.68C11.3298,23.68,11.332,23.6793,11.3342,23.6793L12.371,23.6785C12.5708,23.6918 13.4033,23.7429 14.4415,23.7429 15.5219,23.7429 16.8198,23.6844 17.8655,23.4743L16.9094,26.6082C16.6149,27.5702,15.4656,30.3015,14.087,30.337z M35.2318,13.4273L31.5199,25.5907C30.6667,28.3864,27.9938,30.34,25.019,30.34L16.6489,30.34C17.6827,29.0502,18.2347,27.3386,18.325,27.0411L23.1565,11.2058C23.4421,10.2719,24.3368,9.62,25.3321,9.62L27.9605,9.62 30.1805,9.62 32.3347,9.62C33.3144,9.62 34.2069,10.0662 34.7826,10.8425 35.3398,11.5951 35.5026,12.5363 35.2318,13.4273z - - - - - - - - \ No newline at end of file diff --git a/GoAwayEdge/Assets/EdgeIcon.xaml b/GoAwayEdge/Assets/EdgeIcon.xaml deleted file mode 100644 index d941c18..0000000 --- a/GoAwayEdge/Assets/EdgeIcon.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - F1 M37,36z M0,0z M18.3169,1.6453E-05C10.5041,1.6453E-05 3.85789,4.6666 1.13039,11.9701 3.35676,9.52188 6.30504,8.21538 9.73085,8.21538L9.75652,8.21538C15.0719,8.2236,20.6898,11.5841,22.5465,15.8643L22.5385,15.8643C23.2039,17.1624 23.0489,18.5017 22.8353,19.3478 22.5889,20.309 22.2192,20.7604 22.0796,20.9412L22.0042,21.039C21.733,21.3759 21.7752,21.8697 22.0956,22.1655 22.1531,22.2147 22.2436,22.2807 22.3668,22.3628L22.5802,22.4944C23.6236,23.1516 25.9815,23.8246 28.1175,23.8246 29.7524,23.8246 31.8878,23.5701 33.8924,21.5573 37.2607,18.189 35.9622,13.4894 35.4857,12.1257 34.6724,9.81717 31.2968,2.14434 21.8244,0.336961 20.6743,0.115147 19.4917,1.6453E-05 18.3169,1.6453E-05z M9.73085,9.85845C5.45886,9.85845 2.03344,12.2499 0.0617534,16.604 -0.58726,24.1293 3.97176,30.8812 9.39389,33.9044 10.1743,34.3399 12.6551,35.5892 16.1138,36 13.0577,34.5541 10.7331,32.0317 9.66506,28.7538 7.89054,23.307 10.1172,17.4911 15.334,13.9421L15.342,13.9501C16.1307,13.4325 17.0919,13.1366 18.0778,13.1366 18.1928,13.1366 18.2997,13.1362 18.4148,13.1526 16.1062,11.1809 12.8373,9.86667 9.75653,9.85845L9.73085,9.85845z M13.1405,18.2134C10.8567,21.1463 10.1088,24.7865 11.2343,28.2451 12.7213,32.8129 17.0679,35.7044 22.3668,35.7208 26.4909,34.8007 30.0801,32.3926 33.0869,28.5067L33.1607,28.4088C33.3661,28.1048 33.3506,27.7015 33.1206,27.414 32.8823,27.1347 32.4882,27.0367 32.1514,27.1845L31.7567,27.3658C31.5924,27.4398 31.4448,27.4879 31.2641,27.5536 31.0751,27.6193 30.8615,27.7017 30.5821,27.8167 29.5224,28.2521 27.9454,28.4987 26.253,28.4987 24.8318,28.4987 23.4434,28.3186 22.3507,27.99 20.8062,27.53 16.0976,26.1082 13.6412,20.6861 13.3372,20.0124 13.1323,19.15 13.1405,18.2134z - - - - - \ No newline at end of file diff --git a/GoAwayEdge/Assets/Settings.xaml b/GoAwayEdge/Assets/Settings.xaml index 05842cb..040b27b 100644 --- a/GoAwayEdge/Assets/Settings.xaml +++ b/GoAwayEdge/Assets/Settings.xaml @@ -229,4 +229,17 @@ + F1 M37,36z M0,0z M18.3169,1.6453E-05C10.5041,1.6453E-05 3.85789,4.6666 1.13039,11.9701 3.35676,9.52188 6.30504,8.21538 9.73085,8.21538L9.75652,8.21538C15.0719,8.2236,20.6898,11.5841,22.5465,15.8643L22.5385,15.8643C23.2039,17.1624 23.0489,18.5017 22.8353,19.3478 22.5889,20.309 22.2192,20.7604 22.0796,20.9412L22.0042,21.039C21.733,21.3759 21.7752,21.8697 22.0956,22.1655 22.1531,22.2147 22.2436,22.2807 22.3668,22.3628L22.5802,22.4944C23.6236,23.1516 25.9815,23.8246 28.1175,23.8246 29.7524,23.8246 31.8878,23.5701 33.8924,21.5573 37.2607,18.189 35.9622,13.4894 35.4857,12.1257 34.6724,9.81717 31.2968,2.14434 21.8244,0.336961 20.6743,0.115147 19.4917,1.6453E-05 18.3169,1.6453E-05z M9.73085,9.85845C5.45886,9.85845 2.03344,12.2499 0.0617534,16.604 -0.58726,24.1293 3.97176,30.8812 9.39389,33.9044 10.1743,34.3399 12.6551,35.5892 16.1138,36 13.0577,34.5541 10.7331,32.0317 9.66506,28.7538 7.89054,23.307 10.1172,17.4911 15.334,13.9421L15.342,13.9501C16.1307,13.4325 17.0919,13.1366 18.0778,13.1366 18.1928,13.1366 18.2997,13.1362 18.4148,13.1526 16.1062,11.1809 12.8373,9.86667 9.75653,9.85845L9.73085,9.85845z M13.1405,18.2134C10.8567,21.1463 10.1088,24.7865 11.2343,28.2451 12.7213,32.8129 17.0679,35.7044 22.3668,35.7208 26.4909,34.8007 30.0801,32.3926 33.0869,28.5067L33.1607,28.4088C33.3661,28.1048 33.3506,27.7015 33.1206,27.414 32.8823,27.1347 32.4882,27.0367 32.1514,27.1845L31.7567,27.3658C31.5924,27.4398 31.4448,27.4879 31.2641,27.5536 31.0751,27.6193 30.8615,27.7017 30.5821,27.8167 29.5224,28.2521 27.9454,28.4987 26.253,28.4987 24.8318,28.4987 23.4434,28.3186 22.3507,27.99 20.8062,27.53 16.0976,26.1082 13.6412,20.6861 13.3372,20.0124 13.1323,19.15 13.1405,18.2134z + + + + + F1 M37,32z M0,0z M35.9718,9.96262C35.1149,8.80378,33.7888,8.14,32.3347,8.14L30.1805,8.14 28.5052,8.14 26.9512,3.14352C26.4006,1.29278,24.649,0,22.6932,0L22.4105,0 11.6361,0C8.0131,0,4.87994,2.331,3.8395,5.8016L0.190558,17.9642C-0.216442,19.3221 0.0351583,20.7533 0.881718,21.8907 1.72754,23.0273 3.02624,23.68 4.44334,23.68L7.84438,23.68C8.6162,23.9686,9.37174,24.4318,9.6559,26.1079L9.76838,26.7858C10.2242,29.5719 10.5254,31.4123 13.9753,31.8148 14.0041,31.8185 14.033,31.82 14.0604,31.82L25.019,31.82C28.6968,31.82,31.8781,29.4905,32.9348,26.0221L36.6467,13.8587C37.0574,12.5156,36.8109,11.0948,35.9718,9.96262z M22.4105,1.48L22.6932,1.48C24.0001,1.48,25.1678,2.33766,25.5363,3.5742L26.9556,8.14 25.3328,8.14C24.5173,8.14 23.7573,8.39604 23.1357,8.8393 23.0825,8.81858 23.0321,8.7912 22.9722,8.78306 20.8972,8.50482 19.4261,8.81488 18.3923,9.31068L19.623,5.20812C19.9885,3.99156,21.1496,1.48,22.4105,1.48z M21.9858,10.1735C21.8896,10.3637,21.8052,10.5628,21.7416,10.7729L18.3805,21.7878C17.5739,22.1785 15.7424,22.2673 14.2365,22.2585 14.514,21.9025 14.7367,21.4977 14.8729,21.0426L17.6235,11.874C17.8899,11.4064,18.9525,9.99814,21.9858,10.1735z M4.44334,22.2C3.4991,22.2 2.6333,21.7649 2.06868,21.0071 1.5048,20.2494 1.33682,19.2955 1.6084,18.3897L5.25734,6.22636C6.10908,3.38772,8.67244,1.48,11.6361,1.48L19.8575,1.48C18.8371,2.7713,18.2947,4.4844,18.2051,4.78262L16.2449,11.3168C16.2005,11.4056 16.1753,11.467 16.1694,11.4833 16.1442,11.5477 16.142,11.6136 16.1361,11.6794L13.4543,20.6186C13.1709,21.5643,12.3155,22.2,11.3276,22.2L10.7555,22.2 4.44334,22.2z M14.087,30.337C11.8071,30.0581,11.6791,29.3003,11.2284,26.5468L11.1152,25.8608C10.9524,24.8995,10.6431,24.2032,10.2627,23.68L11.3276,23.68C11.3298,23.68,11.332,23.6793,11.3342,23.6793L12.371,23.6785C12.5708,23.6918 13.4033,23.7429 14.4415,23.7429 15.5219,23.7429 16.8198,23.6844 17.8655,23.4743L16.9094,26.6082C16.6149,27.5702,15.4656,30.3015,14.087,30.337z M35.2318,13.4273L31.5199,25.5907C30.6667,28.3864,27.9938,30.34,25.019,30.34L16.6489,30.34C17.6827,29.0502,18.2347,27.3386,18.325,27.0411L23.1565,11.2058C23.4421,10.2719,24.3368,9.62,25.3321,9.62L27.9605,9.62 30.1805,9.62 32.3347,9.62C33.3144,9.62 34.2069,10.0662 34.7826,10.8425 35.3398,11.5951 35.5026,12.5363 35.2318,13.4273z + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 7866071..02cf3e2 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.ComponentModel; +using System.IO; using System.IO.Pipes; using System.Windows; using GoAwayEdge.Common.Debugging; @@ -39,24 +40,39 @@ public enum EdgeChannel Canary } + public enum WeatherProvider + { + Default, + + [Description("https://weather.com/{country-code}/weather/today/l/{latitude},{longitude}")] + WeatherCom, + + [Description("https://www.accuweather.com/{short-country-code}/search-locations?query={latitude},{longitude}")] + AccuWeather, + + Custom + } + internal class Configuration { public static EdgeChannel Channel { get; set; } public static SearchEngine Search { get; set; } - public static AiProvider Provider { get; set; } + public static AiProvider AiProvider { get; set; } + public static WeatherProvider WeatherProvider { get; set; } public static bool LicenseAccepted { get; set; } public static bool Uninstall { get; set; } public static bool UninstallEdge { get; set; } public static bool NoEdgeInstalled { get; set; } public static bool InstallControlPanel { get; set; } public static string? CustomQueryUrl { get; set; } - public static string? CustomProviderUrl { get; set; } + public static string? CustomAiProviderUrl { get; set; } + public static string? CustomWeatherProviderUrl { get; set; } public static string InstallDir = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "valnoxy", "GoAwayEdge"); - public static ShellManager ShellManager { get; set; } + public static ShellManager? ShellManager { get; set; } public static bool AppBarIsAttached { get; set; } @@ -98,14 +114,19 @@ public static bool InitialEnvironment(bool setupRunning = false) { Channel = Runtime.ArgumentParse.ParseEdgeChannel(RegistryConfig.GetKey("EdgeChannel")); Search = Runtime.ArgumentParse.ParseSearchEngine(RegistryConfig.GetKey("SearchEngine")); - Provider = Runtime.ArgumentParse.ParseAiProvider(RegistryConfig.GetKey("AiProvider", userSetting: true)); + AiProvider = Runtime.ArgumentParse.ParseAiProvider(RegistryConfig.GetKey("AiProvider", userSetting: true)); + WeatherProvider = Runtime.ArgumentParse.ParseWeatherProvider(RegistryConfig.GetKey("WeatherProvider", userSetting: true)); if (Search == SearchEngine.Custom) { CustomQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); } - if (Provider == AiProvider.Custom) + if (AiProvider == AiProvider.Custom) + { + CustomAiProviderUrl = RegistryConfig.GetKey("CustomAiProviderUrl", userSetting: true); + } + if (WeatherProvider == WeatherProvider.Custom) { - CustomProviderUrl = RegistryConfig.GetKey("CustomProviderUrl", userSetting: true); + CustomWeatherProviderUrl = RegistryConfig.GetKey("CustomWeatherProviderUrl", userSetting: true); } } catch (Exception ex) @@ -116,9 +137,11 @@ public static bool InitialEnvironment(bool setupRunning = false) Logging.Log($"Value of NonIfeoPath: {FileConfiguration.NonIfeoPath}"); Logging.Log($"Value of Channel: {Channel}"); Logging.Log($"Value of Search: {Search}"); - Logging.Log($"Value of Provider: {Provider}"); + Logging.Log($"Value of AiProvider: {AiProvider}"); + Logging.Log($"Value of WeatherProvider: {WeatherProvider}"); Logging.Log($"Value of CustomQueryUrl: {CustomQueryUrl}"); - Logging.Log($"Value of CustomProviderUrl: {CustomProviderUrl}"); + Logging.Log($"Value of CustomAiProviderUrl: {CustomAiProviderUrl}"); + Logging.Log($"Value of CustomWeatherProviderUrl: {CustomWeatherProviderUrl}"); return true; } catch (Exception ex) @@ -219,6 +242,80 @@ public static List GetAiProviders() return list; } + + /// + /// Get a list of all available AI Providers. + /// + /// + /// List of AI Providers. + /// + public static List GetWeatherProviders() + { + var list = (from weatherProvider in (WeatherProvider[])Enum.GetValues(typeof(WeatherProvider)) + where (weatherProvider != WeatherProvider.Custom && weatherProvider != WeatherProvider.Default) + select weatherProvider.ToString().Replace("_", " ")).ToList(); + + try + { + var resourceValueCustom = + (string)Application.Current.MainWindow!.FindResource("SettingsSearchEngineCustomItem"); + list.Add(!string.IsNullOrEmpty(resourceValueCustom) ? resourceValueCustom : "Custom"); + } + catch + { + list.Add("Custom"); + } + + try + { + var resourceValueDefault = + (string)Application.Current.MainWindow!.FindResource("Default"); + list.Insert(0, !string.IsNullOrEmpty(resourceValueDefault) ? resourceValueDefault : "Default"); + } + catch + { + list.Insert(0, "Default"); + } + + return list; + } + + /// + /// Retrieves the description of an enumeration value based on the . + /// + /// The enumeration value for which to retrieve the description. + /// + /// The description defined by the if it exists; + /// otherwise, the string representation of the enumeration value. + /// + /// + /// Example usage: + /// + /// public enum SampleEnum + /// { + /// [Description("First Value")] + /// First, + /// + /// [Description("Second Value")] + /// Second, + /// + /// Third // No DescriptionAttribute + /// } + /// + /// var value = SampleEnum.First; + /// string description = GetEnumDescription(value); // "First Value" + /// + /// value = SampleEnum.Third; + /// description = GetEnumDescription(value); // "Third" + /// + /// + public static string GetEnumDescription(Enum value) + { + var fieldInfo = value.GetType().GetField(value.ToString()); + var attributes = (DescriptionAttribute[])fieldInfo!.GetCustomAttributes(typeof(DescriptionAttribute), false); + + return attributes.Length > 0 ? attributes[0].Description : value.ToString(); + } } internal enum ModifyAction diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index 6313217..404935e 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -72,6 +72,28 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) RegistryConfig.RemoveKey("CustomQueryUrl"); } + RegistryConfig.SetKey("AiProvider", Configuration.AiProvider, userSetting: true); + if (Configuration.AiProvider == AiProvider.Custom) + { + if (Configuration.CustomAiProviderUrl != null) + RegistryConfig.SetKey("CustomAiProviderUrl", Configuration.CustomAiProviderUrl, userSetting: true); + } + else + { + RegistryConfig.RemoveKey("CustomAiProviderUrl", userSetting: true); + } + + RegistryConfig.SetKey("WeatherProvider", Configuration.WeatherProvider, userSetting: true); + if (Configuration.WeatherProvider == WeatherProvider.Custom) + { + if (Configuration.CustomWeatherProviderUrl != null) + RegistryConfig.SetKey("CustomWeatherProviderUrl", Configuration.CustomWeatherProviderUrl, userSetting: true); + } + else + { + RegistryConfig.RemoveKey("CustomWeatherProviderUrl", userSetting: true); + } + status = Register.ImageFileExecutionOption( Register.IfeoType.msedge, Path.Combine(Configuration.InstallDir, "GoAwayEdge.exe"), @@ -208,7 +230,6 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) // Set enable flag RegistryConfig.SetKey("Enabled", true); - RegistryConfig.SetKey("AiProvider", "Copilot", userSetting: true); // Temporary // Switch FrameWindow content to InstallationSuccess worker?.ReportProgress(100, ""); diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 111f7f9..6db5651 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -118,9 +118,9 @@ private static void HandleUrl(string url) if (url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=taskbar") || url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=taskbar")) { - if (Configuration.Provider != AiProvider.Copilot) + if (Configuration.AiProvider != AiProvider.Copilot) { - DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.Provider}' (Taskbar) ..."); + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.AiProvider}' (Taskbar) ..."); UserInterface.CopilotDock.InterfaceManager.ShowDock(); return; } @@ -130,14 +130,23 @@ private static void HandleUrl(string url) else if (url.Contains("microsoft-edge://?ux=copilot&tcp=1&source=hotkey") || url.Contains("microsoft-edge:///?ux=copilot&tcp=1&source=hotkey")) { - if (Configuration.Provider != AiProvider.Copilot) + if (Configuration.AiProvider != AiProvider.Copilot) { - DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.Provider}' (Hotkey) ..."); + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.AiProvider}' (Hotkey) ..."); UserInterface.CopilotDock.InterfaceManager.ShowDock(); return; } DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Windows Copilot (Hotkey) with following url:\n{url}"); } + // Weather Provider + else if (url.Contains("%3Floc%3D") && url.Contains("msn.com")) // ?loc= + { + var parsedUrl = UrlParse.Parse(url); + var parsedWeather = Weather.ParseUrl(parsedUrl); + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening Weather URL in default browser:\n\n{parsedWeather}"); + p.StartInfo.FileName = parsedWeather; + p.StartInfo.Arguments = string.Empty; + } // Default else { @@ -195,7 +204,7 @@ public static AiProvider ParseAiProvider(string argument) "github_copilot" => AiProvider.GitHub_Copilot, "grok" => AiProvider.Grok, "custom" => AiProvider.Custom, - _ => AiProvider.Copilot // Fallback channel + _ => AiProvider.Copilot // Fallback provider }; } @@ -220,5 +229,17 @@ public static SearchEngine ParseSearchEngine(string argument) _ => SearchEngine.Google // Fallback search engine }; } + + public static WeatherProvider ParseWeatherProvider(string argument) + { + return argument.ToLower() switch + { + "default" => WeatherProvider.Default, + "weathercom" => WeatherProvider.WeatherCom, + "accuweather" => WeatherProvider.AccuWeather, + "custom" => WeatherProvider.Custom, + _ => WeatherProvider.Default // Fallback provider + }; + } } } diff --git a/GoAwayEdge/Common/Runtime/UrlParse.cs b/GoAwayEdge/Common/Runtime/UrlParse.cs index 4a1bf5c..5e5c81e 100644 --- a/GoAwayEdge/Common/Runtime/UrlParse.cs +++ b/GoAwayEdge/Common/Runtime/UrlParse.cs @@ -34,7 +34,7 @@ public static string Parse(string encodedUrl) #if DEBUG var uriMessageUi = new MessageUi("GoAwayEdge", - "New Uri: " + encodedUrl, "OK", isMainThread: true); + "Got extracted and decoded url variable from Microsoft-Edge Protocol:\n\n" + encodedUrl, "OK", isMainThread: true); uriMessageUi.ShowDialog(); #endif var uri = new Uri(encodedUrl); diff --git a/GoAwayEdge/Common/Runtime/Weather.cs b/GoAwayEdge/Common/Runtime/Weather.cs new file mode 100644 index 0000000..4649552 --- /dev/null +++ b/GoAwayEdge/Common/Runtime/Weather.cs @@ -0,0 +1,61 @@ +using System.Buffers.Text; +using System.Globalization; +using System.Security.Policy; +using System.Text; +using System.Web; +using Newtonsoft.Json; + +namespace GoAwayEdge.Common.Runtime +{ + public class Weather + { + public class GeoData + { + public string L { get; set; } // City + public string R { get; set; } // Region + public string C { get; set; } // Country + public string I { get; set; } // Short Country code + public string G { get; set; } // Country code (lowercase) + public double X { get; set; } // longitude + public double Y { get; set; } // latitude + } + + public static string? ParseUrl(string encodedUrl) + { + // Encoded URL structure: https://msn.com//.../?loc= + // This function will locate the argument "?loc", decode the base64 geolocation information and format the template + + if (Configuration.WeatherProvider == WeatherProvider.Default) + return encodedUrl; + + var encodedUri = new Uri(encodedUrl); + var locValue = HttpUtility.ParseQueryString(encodedUri.Query).Get("loc"); // Output: Base64 + if (string.IsNullOrEmpty(locValue)) + return ""; + + var encodedLocValue = Encoding.UTF8.GetString(Convert.FromBase64String(locValue)); // Output: Json + var locObject = JsonConvert.DeserializeObject(encodedLocValue); + var language = Thread.CurrentThread.CurrentCulture.ToString(); // Country code (full case) + if (locObject == null) + return ""; + + var lat = locObject.Y.ToString(CultureInfo.InvariantCulture).Replace(",", "."); + var lon = locObject.X.ToString(CultureInfo.InvariantCulture).Replace(",", "."); + var placeholders = new Dictionary + { + { "country-code", language }, + { "short-country-code", locObject.I }, + { "latitude", lat }, + { "longitude", lon } + }; + + var weatherProviderUrl = Configuration.WeatherProvider == WeatherProvider.Custom + ? Configuration.CustomWeatherProviderUrl : Configuration.GetEnumDescription(Configuration.WeatherProvider); + + weatherProviderUrl = placeholders.Aggregate(weatherProviderUrl, (current, placeholder) => current.Replace($"{{{placeholder.Key}}}", placeholder.Value)); + var isValid = Uri.TryCreate(weatherProviderUrl, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); + return isValid ? weatherProviderUrl : ""; + } + } +} diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index e32a552..b70bedb 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -12,8 +12,8 @@ GoAwayEdge Exploitox valnoxy - 2.0.0.231 - Copyright © 2018 - 2024 Exploitox. All rights reserved. + 2.0.0.257 + Copyright © 2018 - 2025 Exploitox. All rights reserved. https://github.com/valnoxy/GoAwayEdge https://github.com/valnoxy/GoAwayEdge GoAwayEdge.App diff --git a/GoAwayEdge/GoAwayEdge.csproj.user b/GoAwayEdge/GoAwayEdge.csproj.user index 3dd6034..61534d1 100644 --- a/GoAwayEdge/GoAwayEdge.csproj.user +++ b/GoAwayEdge/GoAwayEdge.csproj.user @@ -45,18 +45,12 @@ Designer - - Designer - Designer Designer - - Designer - Designer diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 5ade673..a53b3b2 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -5,6 +5,7 @@ Beenden Ja Nein + Standard Willkommen Das Installationsprogramm führt alle notwendigen Schritte durch, um GoAwayEdge auf Ihrem System zu installieren. Nach der Installation werden alle Edge-Aufrufe an Ihren Browser weitergeleitet. Bitte wählen Sie die gewünschte Option, um fortzufahren. @@ -18,6 +19,11 @@ Bitte lesen Sie die folgende Lizenz. Sie müssen die Lizenzbedingungen akzeptieren, bevor Sie mit der Installation fortfahren können. Ich akzeptiere diese Lizenz. Ich lehne diese Lizenz ab. + + Umleiten oder Entfernen? + Sollen alle Aufrufe von Edge auf einen anderen Browser umgeleitet werden, oder soll Edge vollständig entfernt werden? + Alles umleiten (Empfohlen) + Leite alle Aufrufe von Edge auf deinen Lieblingsbrowser um. Einstellungen Edge Kanal @@ -64,6 +70,10 @@ Aktiviere/Deaktiviere GoAwayEdge Aktiviere GoAwayEdge Deaktiviere GoAwayEdge + Wetterdienst + Wechsel den Anbieter zu Ihres bevorzugten Wetterdienstes. + Benutzerdefinierter Wetterdienst + Bitte geben Sie die URL des Wetterdienstes ein. GoAwayEdge wurde auf diesem System erfolgreich deaktiviert. GoAwayEdge konnte auf diesem System nicht aktiviert werden: {0} Installiere das Kontrollpanel, um GoAwayEdge einfacher zu konfigurieren. diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 8aea2b7..1a7d5b8 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -7,6 +7,7 @@ Exit Yes No + Default Welcome @@ -23,6 +24,12 @@ I accept this license. I decline this license. + + Redirect or Remove? + Do you want to redirect all calls from Edge to another browser, or completely remove Edge? + Redirect everything + Redirect all calls from Edge to your favorite browser. + Settings Edge Channel @@ -63,6 +70,10 @@ Change the provider to your favorite AI (or to your favorite website). Custom AI Provider Please enter the URL from the AI Provider (or your favorite website). + Weather Service + Change the service to your favorite Weather website. + Custom Weather Service + Please enter the URL from the Weather Service. Initialization failed: {0} diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml index 01f30cc..c05335c 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml @@ -15,7 +15,7 @@ - + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs index 32dfe94..a85c7eb 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -18,19 +18,19 @@ public CopilotSettings() { CopilotProviderBox.Items.Add(aiProvider); } - CopilotProviderBox.SelectedItem = Configuration.Provider.ToString().Replace("_", " "); + CopilotProviderBox.SelectedItem = Configuration.AiProvider.ToString().Replace("_", " "); - if (Configuration.Provider == AiProvider.Custom) + if (Configuration.AiProvider == AiProvider.Custom) { CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); CustomSearchPanel.Visibility = Visibility.Visible; - if (Configuration.CustomProviderUrl != null) QueryProviderTextBox.Text = Configuration.CustomProviderUrl; + if (Configuration.CustomAiProviderUrl != null) QueryProviderTextBox.Text = Configuration.CustomAiProviderUrl; CustomUrlStatus.Symbol = Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out _) ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; } else { - CopilotProviderBox.SelectedItem = Configuration.Provider.ToString(); + CopilotProviderBox.SelectedItem = Configuration.AiProvider.ToString(); } } @@ -38,15 +38,15 @@ private void FlushSettings() { try { - RegistryConfig.SetKey("AiProvider", Configuration.Provider.ToString(), userSetting: true); - if (Configuration.Provider == AiProvider.Custom) + RegistryConfig.SetKey("AiProvider", Configuration.AiProvider.ToString(), userSetting: true); + if (Configuration.AiProvider == AiProvider.Custom) { - if (Configuration.CustomProviderUrl != null) - RegistryConfig.SetKey("CustomProviderUrl", Configuration.CustomProviderUrl, userSetting: true); + if (Configuration.CustomAiProviderUrl != null) + RegistryConfig.SetKey("CustomAiProviderUrl", Configuration.CustomAiProviderUrl, userSetting: true); } else { - RegistryConfig.RemoveKey("CustomProviderUrl", userSetting: true); + RegistryConfig.RemoveKey("CustomAiProviderUrl", userSetting: true); } } catch (Exception ex) @@ -65,27 +65,27 @@ private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChang switch (CopilotProviderBox.SelectedIndex) { case 0: - Configuration.Provider = AiProvider.Copilot; + Configuration.AiProvider = AiProvider.Copilot; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 1: - Configuration.Provider = AiProvider.ChatGPT; + Configuration.AiProvider = AiProvider.ChatGPT; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 2: - Configuration.Provider = AiProvider.Gemini; + Configuration.AiProvider = AiProvider.Gemini; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 3: - Configuration.Provider = AiProvider.GitHub_Copilot; + Configuration.AiProvider = AiProvider.GitHub_Copilot; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 4: - Configuration.Provider = AiProvider.Grok; + Configuration.AiProvider = AiProvider.Grok; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 5: - Configuration.Provider = AiProvider.Custom; + Configuration.AiProvider = AiProvider.Custom; CustomSearchPanel.Visibility = Visibility.Visible; break; } @@ -99,7 +99,7 @@ private void QueryProviderTextBox_OnTextChanged(object sender, TextChangedEventA && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) { CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; - Configuration.CustomProviderUrl = QueryProviderTextBox.Text; + Configuration.CustomAiProviderUrl = QueryProviderTextBox.Text; FlushSettings(); } else diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml index 069ddd9..babefd5 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml @@ -86,6 +86,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs index c03dbd3..b9cfbd7 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/EdgeSettings.xaml.cs @@ -23,6 +23,7 @@ public EdgeSettings() } EdgeChannelBox.SelectedItem = Configuration.Channel.ToString(); + // Search Engine foreach (var searchEngine in Configuration.GetSearchEngines()) { SearchEngineBox.Items.Add(searchEngine); @@ -41,6 +42,25 @@ public EdgeSettings() SearchEngineBox.SelectedItem = Configuration.Search.ToString(); } + // Weather Provider + foreach (var weatherProvider in Configuration.GetWeatherProviders()) + { + WeatherProviderBox.Items.Add(weatherProvider); + } + WeatherProviderBox.SelectedItem = Configuration.WeatherProvider.ToString().Replace("_", " "); + + if (Configuration.WeatherProvider == WeatherProvider.Custom) + { + WeatherProviderBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); + CustomWeatherPanel.Visibility = Visibility.Visible; + if (Configuration.CustomWeatherProviderUrl != null) QueryWeatherProviderTextBox.Text = Configuration.CustomWeatherProviderUrl; + CustomWeatherUrlStatus.Symbol = Uri.TryCreate(QueryWeatherProviderTextBox.Text, UriKind.Absolute, out _) + ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; + } + + if (Configuration.WeatherProvider == WeatherProvider.Default) + WeatherProviderBox.SelectedItem = LocalizationManager.LocalizeValue("Default"); + if (RegistryConfig.GetKey("Enabled") == "True") { _appIsEnabled = true; @@ -68,6 +88,17 @@ private static void FlushSettings() { RegistryConfig.RemoveKey("CustomQueryUrl"); } + + RegistryConfig.SetKey("WeatherProvider", Configuration.WeatherProvider, userSetting: true); + if (Configuration.WeatherProvider == WeatherProvider.Custom) + { + if (Configuration.CustomWeatherProviderUrl != null) + RegistryConfig.SetKey("CustomWeatherProviderUrl", Configuration.CustomWeatherProviderUrl, userSetting: true); + } + else + { + RegistryConfig.RemoveKey("CustomWeatherProviderUrl", userSetting: true); + } } catch (Exception ex) { @@ -136,6 +167,30 @@ private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedE } } + private void WeatherProviderBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + switch (WeatherProviderBox.SelectedIndex) + { + case 0: + Configuration.WeatherProvider = WeatherProvider.Default; + CustomWeatherPanel.Visibility = Visibility.Collapsed; + break; + case 1: + Configuration.WeatherProvider = WeatherProvider.WeatherCom; + CustomWeatherPanel.Visibility = Visibility.Collapsed; + break; + case 2: + Configuration.WeatherProvider = WeatherProvider.AccuWeather; + CustomWeatherPanel.Visibility = Visibility.Collapsed; + break; + case 3: + Configuration.WeatherProvider = WeatherProvider.Custom; + CustomWeatherPanel.Visibility = Visibility.Visible; + break; + } + FlushSettings(); + } + private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { Configuration.Channel = EdgeChannelBox.SelectedIndex switch @@ -216,5 +271,21 @@ private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; } } + + private void QueryWeatherProviderTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + // Test if the URL is valid + if (Uri.TryCreate(QueryWeatherProviderTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) + { + CustomWeatherUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomWeatherProviderUrl = QueryWeatherProviderTextBox.Text; + FlushSettings(); + } + else + { + CustomWeatherUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + } + } } } diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index d6e9e35..46ae52d 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -41,7 +41,7 @@ private async Task InitializeWebViewAsync() var webView2Environment = await CoreWebView2Environment.CreateAsync(userDataFolder: userProfilePath); await WebView.EnsureCoreWebView2Async(webView2Environment); - switch (Configuration.Provider) + switch (Configuration.AiProvider) { case ChatGPT: WebView.Source = new Uri("https://chatgpt.com/"); @@ -56,12 +56,12 @@ private async Task InitializeWebViewAsync() WebView.Source = new Uri("https://x.com/i/grok"); break; case Custom: - if (Configuration.CustomProviderUrl != null) - WebView.Source = new Uri(Configuration.CustomProviderUrl); + if (Configuration.CustomAiProviderUrl != null) + WebView.Source = new Uri(Configuration.CustomAiProviderUrl); break; case Copilot: default: - Logging.Log($"Failed to load Provider! Provider Value '{Configuration.Provider}' in invalid!"); + Logging.Log($"Failed to load AiProvider! AiProvider Value '{Configuration.AiProvider}' in invalid!"); throw new ArgumentOutOfRangeException(); } } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml index bac6bb7..5a78aa8 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml +++ b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml @@ -15,8 +15,8 @@ - - + + + Text="{DynamicResource RedirectEverythingTitle}" /> + Text="{DynamicResource RedirectEverythingDescription}" /> - + @@ -89,7 +89,7 @@ - + @@ -133,7 +133,57 @@ Text="{DynamicResource ControlPanelCustomCopilotProviderDescription}"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index 885ee62..c394df4 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -14,16 +14,19 @@ public Settings() { InitializeComponent(); + // Edge Channel foreach (var edgeChannels in Configuration.GetEdgeChannels()) { EdgeChannelBox.Items.Add(edgeChannels); } EdgeChannelBox.SelectedItem = Configuration.Channel.ToString(); + // Search Engine foreach (var searchEngine in Configuration.GetSearchEngines()) { SearchEngineBox.Items.Add(searchEngine); } + SearchEngineBox.SelectedItem = Configuration.Search.ToString().Replace("_", " "); if (Configuration.Search == SearchEngine.Custom) { @@ -33,33 +36,47 @@ public Settings() CustomUrlStatus.Symbol = Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out _) ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; } - else - { - SearchEngineBox.SelectedItem = Configuration.Search.ToString(); - } + // AI Provider foreach (var aiProvider in Configuration.GetAiProviders()) { CopilotProviderBox.Items.Add(aiProvider); } - CopilotProviderBox.SelectedItem = Configuration.Provider.ToString().Replace("_", " "); + CopilotProviderBox.SelectedItem = Configuration.AiProvider.ToString().Replace("_", " "); - if (Configuration.Provider == AiProvider.Custom) + if (Configuration.AiProvider == AiProvider.Custom) { CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); - CustomSearchPanel.Visibility = Visibility.Visible; - if (Configuration.CustomProviderUrl != null) QueryProviderTextBox.Text = Configuration.CustomProviderUrl; - CustomUrlStatus.Symbol = Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out _) + CustomAiPanel.Visibility = Visibility.Visible; + if (Configuration.CustomAiProviderUrl != null) QueryAiProviderTextBox.Text = Configuration.CustomAiProviderUrl; + CustomUrlStatus.Symbol = Uri.TryCreate(QueryAiProviderTextBox.Text, UriKind.Absolute, out _) ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; } - else + + // Weather Provider + foreach (var weatherProvider in Configuration.GetWeatherProviders()) { - CopilotProviderBox.SelectedItem = Configuration.Search.ToString(); + WeatherProviderBox.Items.Add(weatherProvider); } + WeatherProviderBox.SelectedItem = Configuration.WeatherProvider.ToString().Replace("_", " "); + + if (Configuration.WeatherProvider == WeatherProvider.Custom) + { + WeatherProviderBox.SelectedItem = LocalizationManager.LocalizeValue("SettingsSearchEngineCustomItem"); + CustomWeatherPanel.Visibility = Visibility.Visible; + if (Configuration.CustomWeatherProviderUrl != null) QueryWeatherProviderTextBox.Text = Configuration.CustomWeatherProviderUrl; + CustomWeatherUrlStatus.Symbol = Uri.TryCreate(QueryWeatherProviderTextBox.Text, UriKind.Absolute, out _) + ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; + } + + if (Configuration.WeatherProvider == WeatherProvider.Default) + WeatherProviderBox.SelectedItem = LocalizationManager.LocalizeValue("Default"); + // Others if (Configuration.NoEdgeInstalled) { CopilotStackPanel.IsEnabled = false; + WeatherStackPanel.IsEnabled = false; EdgeStackPanel.IsEnabled = false; } @@ -68,6 +85,20 @@ public Settings() ControlPanelSwitch.IsChecked = true; } + private void EnableNextBtnValidation() + { + var validation = true; + + if (Configuration.Search == SearchEngine.Custom) + validation = !string.IsNullOrEmpty(Configuration.CustomQueryUrl) && CustomUrlStatus.Symbol == SymbolRegular.CheckmarkCircle24; + if (Configuration.AiProvider == AiProvider.Custom) + validation = !string.IsNullOrEmpty(Configuration.CustomAiProviderUrl) && CustomAiUrlStatus.Symbol == SymbolRegular.CheckmarkCircle24; + if (Configuration.WeatherProvider == WeatherProvider.Custom) + validation = !string.IsNullOrEmpty(Configuration.CustomWeatherProviderUrl) && CustomWeatherUrlStatus.Symbol == SymbolRegular.CheckmarkCircle24; + + Installer.ContentWindow!.NextBtn.IsEnabled = validation; + } + private void EdgeChannelBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { Configuration.Channel = EdgeChannelBox.SelectedIndex switch @@ -87,71 +118,60 @@ private void SearchEngineBox_OnSelectionChanged(object sender, SelectionChangedE case 0: Configuration.Search = SearchEngine.Google; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 1: Configuration.Search = SearchEngine.Bing; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 2: Configuration.Search = SearchEngine.DuckDuckGo; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 3: Configuration.Search = SearchEngine.Yahoo; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 4: Configuration.Search = SearchEngine.Yandex; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 5: Configuration.Search = SearchEngine.Ecosia; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 6: Configuration.Search = SearchEngine.Ask; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 7: Configuration.Search = SearchEngine.Qwant; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 8: Configuration.Search = SearchEngine.Perplexity; CustomSearchPanel.Visibility = Visibility.Collapsed; - Installer.ContentWindow!.NextBtn.IsEnabled = true; break; case 9: Configuration.Search = SearchEngine.Custom; CustomSearchPanel.Visibility = Visibility.Visible; - if (string.IsNullOrEmpty(Configuration.CustomQueryUrl)) - Installer.ContentWindow!.NextBtn.IsEnabled = false; break; } + EnableNextBtnValidation(); } - + private void QueryUrlTextBox_OnTextChanged(object sender, TextChangedEventArgs e) { if (Uri.TryCreate(QueryUrlTextBox.Text, UriKind.Absolute, out var uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) { - Installer.ContentWindow!.NextBtn.IsEnabled = true; CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; Configuration.CustomQueryUrl = QueryUrlTextBox.Text; } else { - Installer.ContentWindow!.NextBtn.IsEnabled = false; CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; } + EnableNextBtnValidation(); } private void ControlPanelSwitch_OnClick(object sender, RoutedEventArgs e) @@ -164,45 +184,87 @@ private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChang switch (CopilotProviderBox.SelectedIndex) { case 0: - Configuration.Provider = AiProvider.Copilot; + Configuration.AiProvider = AiProvider.Copilot; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 1: - Configuration.Provider = AiProvider.ChatGPT; + Configuration.AiProvider = AiProvider.ChatGPT; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 2: - Configuration.Provider = AiProvider.Gemini; + Configuration.AiProvider = AiProvider.Gemini; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 3: - Configuration.Provider = AiProvider.GitHub_Copilot; + Configuration.AiProvider = AiProvider.GitHub_Copilot; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 4: - Configuration.Provider = AiProvider.Grok; + Configuration.AiProvider = AiProvider.Grok; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 5: - Configuration.Provider = AiProvider.Custom; + Configuration.AiProvider = AiProvider.Custom; CustomAiPanel.Visibility = Visibility.Visible; break; } + EnableNextBtnValidation(); } - private void QueryProviderTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + private void WeatherProviderBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + switch (WeatherProviderBox.SelectedIndex) + { + case 0: + Configuration.WeatherProvider = WeatherProvider.Default; + CustomWeatherPanel.Visibility = Visibility.Collapsed; + break; + case 1: + Configuration.WeatherProvider = WeatherProvider.WeatherCom; + CustomWeatherPanel.Visibility = Visibility.Collapsed; + break; + case 2: + Configuration.WeatherProvider = WeatherProvider.AccuWeather; + CustomWeatherPanel.Visibility = Visibility.Collapsed; + break; + case 3: + Configuration.WeatherProvider = WeatherProvider.Custom; + CustomWeatherPanel.Visibility = Visibility.Visible; + break; + } + EnableNextBtnValidation(); + } + + private void QueryAiProviderTextBox_OnTextChanged(object sender, TextChangedEventArgs e) { // Test if the URL is valid - if (Uri.TryCreate(QueryProviderTextBox.Text, UriKind.Absolute, out var uriResult) + if (Uri.TryCreate(QueryAiProviderTextBox.Text, UriKind.Absolute, out var uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) { - CustomUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; - Configuration.CustomProviderUrl = QueryProviderTextBox.Text; + CustomAiUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomAiProviderUrl = QueryAiProviderTextBox.Text; } else { - CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + CustomAiUrlStatus.Symbol = SymbolRegular.ErrorCircle24; + } + EnableNextBtnValidation(); + } + + private void QueryWeatherProviderTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + // Test if the URL is valid + if (Uri.TryCreate(QueryWeatherProviderTextBox.Text, UriKind.Absolute, out var uriResult) + && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)) + { + CustomWeatherUrlStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CustomWeatherProviderUrl = QueryWeatherProviderTextBox.Text; + } + else + { + CustomWeatherUrlStatus.Symbol = SymbolRegular.ErrorCircle24; } + EnableNextBtnValidation(); } } } From 2a32b10ddd89b9e10975399fe3a4055850c17c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Fri, 20 Dec 2024 20:23:54 +0100 Subject: [PATCH 46/80] Added Microsoft Copilot --- GoAwayEdge/App.xaml.cs | 4 +- GoAwayEdge/Common/Configuration.cs | 55 +++++++++++++++++-- .../Common/Installation/InstallRoutine.cs | 22 ++++++++ GoAwayEdge/Common/Runtime/ArgumentParse.cs | 18 +++++- GoAwayEdge/Common/Runtime/UrlParse.cs | 34 ++---------- .../ResourceDictionary.de-DE.xaml | 4 +- .../Pages/CopilotSettings.xaml.cs | 18 ++++-- .../CopilotDock/CopilotDock.xaml.cs | 39 +++++-------- .../Setup/Pages/Settings.xaml.cs | 17 ++++-- 9 files changed, 138 insertions(+), 73 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index b58d430..bbe450e 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -93,7 +93,7 @@ public void Application_Startup(object sender, StartupEventArgs e) { Configuration.InitialEnvironment(); - if (Configuration.AiProvider != AiProvider.Copilot) + if (Configuration.AiProvider != AiProvider.Default) { DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.AiProvider}' (Triggered with argument) ..."); @@ -104,7 +104,7 @@ public void Application_Startup(object sender, StartupEventArgs e) { IsDebug = true; DebugMessage.DisplayDebugMessage("GoAwayEdge", - "You cannot open the Copilot dock if your AI provider is Copilot."); + "You cannot open the Copilot dock if your AI provider is set to default"); Environment.Exit(1); } } diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 02cf3e2..0215f06 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -10,25 +10,55 @@ namespace GoAwayEdge.Common { public enum SearchEngine { + [Description("https://www.google.com/search?q=")] Google, + + [Description("https://www.bing.com/search?q=")] Bing, + + [Description("https://duckduckgo.com/?q=")] DuckDuckGo, + + [Description("https://search.yahoo.com/search?p=")] Yahoo, + + [Description("https://yandex.com/search/?text=")] Yandex, + + [Description("https://www.ecosia.org/search?q=")] Ecosia, + + [Description("https://www.ask.com/web?q=")] Ask, + + [Description("https://qwant.com/?q=")] Qwant, + + [Description("https://www.perplexity.ai/search?copilot=false&q=")] Perplexity, + Custom } public enum AiProvider { + Default, + + [Description("https://copilot.microsoft.com/")] Copilot, + + [Description("https://chatgpt.com/")] ChatGPT, + + [Description("https://gemini.google.com/")] Gemini, + + [Description("https://github.com/copilot")] GitHub_Copilot, + + [Description("https://x.com/i/grok")] Grok, + Custom } @@ -72,6 +102,12 @@ internal class Configuration Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "valnoxy", "GoAwayEdge"); + + public static string UserDir = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "valnoxy", + "GoAwayEdge"); + public static ShellManager? ShellManager { get; set; } public static bool AppBarIsAttached { get; set; } @@ -226,7 +262,7 @@ public static List GetSearchEngines() public static List GetAiProviders() { var list = (from aiProvider in (AiProvider[])Enum.GetValues(typeof(AiProvider)) - where aiProvider != AiProvider.Custom + where aiProvider != AiProvider.Custom && aiProvider != AiProvider.Default select aiProvider.ToString().Replace("_", " ")).ToList(); try @@ -240,19 +276,30 @@ public static List GetAiProviders() list.Add("Custom"); } + try + { + var resourceValueDefault = + (string)Application.Current.MainWindow!.FindResource("Default"); + list.Insert(0, !string.IsNullOrEmpty(resourceValueDefault) ? resourceValueDefault : "Default"); + } + catch + { + list.Insert(0, "Default"); + } + return list; } /// - /// Get a list of all available AI Providers. + /// Get a list of all available Weather Services. /// /// - /// List of AI Providers. + /// List of Weather Services. /// public static List GetWeatherProviders() { var list = (from weatherProvider in (WeatherProvider[])Enum.GetValues(typeof(WeatherProvider)) - where (weatherProvider != WeatherProvider.Custom && weatherProvider != WeatherProvider.Default) + where weatherProvider != WeatherProvider.Custom && weatherProvider != WeatherProvider.Default select weatherProvider.ToString().Replace("_", " ")).ToList(); try diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index 404935e..c150eb9 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -290,6 +290,28 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) return; } + // Remove user directory + try + { + if (Directory.Exists(Configuration.UserDir)) + { + var dir = new DirectoryInfo(Configuration.UserDir); + dir.Delete(true); + } + } + catch (Exception ex) + { + Logging.Log("Failed to delete user directory: " + ex, Logging.LogLevel.ERROR); + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("FailedUninstallation", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); + Environment.Exit(1); + return; + } + // Remove Ifeo & Uri handler from registry try { diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 6db5651..39f644d 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.IO; +using System.Text.RegularExpressions; using GoAwayEdge.Common.Debugging; namespace GoAwayEdge.Common.Runtime @@ -40,6 +41,20 @@ public static void Parse(string[] args) } else if (isApp) { + const string pattern = @"--app-id=([^\s]+)"; + const string copilotAppId = "khiogjgiicnghciboipemonlmgelhblf"; + var match = Regex.Match(argumentJoin, pattern); + if (match.Success) + { + var appId = match.Groups[1].Value; + Logging.Log($"Opening PWA App with ID {appId}"); + if (appId == copilotAppId) + { + DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.AiProvider}' (PWA) ..."); + UserInterface.CopilotDock.InterfaceManager.ShowDock(); + return; + } + } StartProcess(FileConfiguration.NonIfeoPath, singleArgument, $"Opening PWA Application with following arguments: '{singleArgument}'."); } } @@ -198,13 +213,14 @@ public static AiProvider ParseAiProvider(string argument) { return argument.ToLower() switch { + "default" => AiProvider.Default, "copilot" => AiProvider.Copilot, "chatgpt" => AiProvider.ChatGPT, "gemini" => AiProvider.Gemini, "github_copilot" => AiProvider.GitHub_Copilot, "grok" => AiProvider.Grok, "custom" => AiProvider.Custom, - _ => AiProvider.Copilot // Fallback provider + _ => AiProvider.Default // Fallback provider }; } diff --git a/GoAwayEdge/Common/Runtime/UrlParse.cs b/GoAwayEdge/Common/Runtime/UrlParse.cs index 5e5c81e..29906e2 100644 --- a/GoAwayEdge/Common/Runtime/UrlParse.cs +++ b/GoAwayEdge/Common/Runtime/UrlParse.cs @@ -29,8 +29,12 @@ public static string Parse(string encodedUrl) // Decode Url encodedUrl = encodedUrl.Contains("redirect") ? DotSlash(encodedUrl) : DecodeUrlString(encodedUrl); + // Get new URL + var definedEngineUrl = Configuration.Search == SearchEngine.Custom + ? Configuration.CustomQueryUrl : Configuration.GetEnumDescription(Configuration.Search); + // Replace Search Engine - encodedUrl = encodedUrl.Replace("https://www.bing.com/search?q=", DefineEngine(Configuration.Search)); + encodedUrl = encodedUrl.Replace("https://www.bing.com/search?q=", definedEngineUrl); #if DEBUG var uriMessageUi = new MessageUi("GoAwayEdge", @@ -41,34 +45,6 @@ public static string Parse(string encodedUrl) return uri.ToString(); } - private static string DefineEngine(SearchEngine engine) - { - var customQueryUrl = string.Empty; - try - { - customQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); - } - catch - { - // ignore; not an valid object - } - - return engine switch - { - SearchEngine.Google => "https://www.google.com/search?q=", - SearchEngine.Bing => "https://www.bing.com/search?q=", - SearchEngine.DuckDuckGo => "https://duckduckgo.com/?q=", - SearchEngine.Yahoo => "https://search.yahoo.com/search?p=", - SearchEngine.Yandex => "https://yandex.com/search/?text=", - SearchEngine.Ecosia => "https://www.ecosia.org/search?q=", - SearchEngine.Ask => "https://www.ask.com/web?q=", - SearchEngine.Qwant => "https://qwant.com/?q=", - SearchEngine.Perplexity => "https://www.perplexity.ai/search?copilot=false&q=", - SearchEngine.Custom => customQueryUrl, - _ => "https://www.google.com/search?q=" - }; - } - private static string DecodeUrlString(string url) { string newUrl; diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index a53b3b2..7f5c64b 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -83,8 +83,8 @@ GoAwayEdge wurde auf diesem System erfolgreich aktiviert. GoAwayEdge konnte auf diesem System nicht deaktiviert werden: {0} KI Anbieter - Wechseln Sie den Anbieter Ihrer bevorzugten KI (oder zu Ihrer bevorzugten Webseite). + Wechsel den Anbieter Ihrer bevorzugten KI (oder zu Ihrer bevorzugten Webseite). Benutzerdefinierter KI Anbieter - Bitte geben Sie die URL des KI-Anbieters (oder einer Webseite) ein. + Bitte gebe die URL des KI-Anbieters (oder einer Webseite) ein. Die Einstellungen konnten nicht übernommen werden: {0} diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs index a85c7eb..641fc18 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -32,6 +32,10 @@ public CopilotSettings() { CopilotProviderBox.SelectedItem = Configuration.AiProvider.ToString(); } + + if (Configuration.AiProvider == AiProvider.Default) + CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("Default"); + } private void FlushSettings() @@ -65,26 +69,30 @@ private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChang switch (CopilotProviderBox.SelectedIndex) { case 0: - Configuration.AiProvider = AiProvider.Copilot; + Configuration.AiProvider = AiProvider.Default; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 1: - Configuration.AiProvider = AiProvider.ChatGPT; + Configuration.AiProvider = AiProvider.Copilot; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 2: - Configuration.AiProvider = AiProvider.Gemini; + Configuration.AiProvider = AiProvider.ChatGPT; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 3: - Configuration.AiProvider = AiProvider.GitHub_Copilot; + Configuration.AiProvider = AiProvider.Gemini; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 4: - Configuration.AiProvider = AiProvider.Grok; + Configuration.AiProvider = AiProvider.GitHub_Copilot; CustomSearchPanel.Visibility = Visibility.Collapsed; break; case 5: + Configuration.AiProvider = AiProvider.Grok; + CustomSearchPanel.Visibility = Visibility.Collapsed; + break; + case 6: Configuration.AiProvider = AiProvider.Custom; CustomSearchPanel.Visibility = Visibility.Visible; break; diff --git a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs index 46ae52d..0f30e48 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/CopilotDock.xaml.cs @@ -41,28 +41,13 @@ private async Task InitializeWebViewAsync() var webView2Environment = await CoreWebView2Environment.CreateAsync(userDataFolder: userProfilePath); await WebView.EnsureCoreWebView2Async(webView2Environment); - switch (Configuration.AiProvider) + var providerUrl = Configuration.AiProvider == Custom + ? Configuration.CustomAiProviderUrl : Configuration.GetEnumDescription(Configuration.AiProvider); + if (providerUrl != null) WebView.Source = new Uri(providerUrl); + else { - case ChatGPT: - WebView.Source = new Uri("https://chatgpt.com/"); - break; - case Gemini: - WebView.Source = new Uri("https://gemini.google.com/"); - break; - case GitHub_Copilot: - WebView.Source = new Uri("https://github.com/copilot"); - break; - case Grok: - WebView.Source = new Uri("https://x.com/i/grok"); - break; - case Custom: - if (Configuration.CustomAiProviderUrl != null) - WebView.Source = new Uri(Configuration.CustomAiProviderUrl); - break; - case Copilot: - default: - Logging.Log($"Failed to load AiProvider! AiProvider Value '{Configuration.AiProvider}' in invalid!"); - throw new ArgumentOutOfRangeException(); + Logging.Log($"Failed to load AiProvider! AiProvider Value '{Configuration.AiProvider}' in invalid!"); + throw new ArgumentOutOfRangeException(); } } catch (Exception ex) @@ -73,8 +58,12 @@ private async Task InitializeWebViewAsync() private void CloseButton_OnClick(object sender, RoutedEventArgs e) { - Configuration.ShellManager.AppBarManager.SignalGracefulShutdown(); - Configuration.ShellManager.Dispose(); + if (Configuration.ShellManager != null) + { + Configuration.ShellManager.AppBarManager.SignalGracefulShutdown(); + Configuration.ShellManager.Dispose(); + } + Environment.Exit(0); } @@ -84,13 +73,13 @@ private void DockButton_OnClick(object sender, RoutedEventArgs e) { DockButton.Icon = new SymbolIcon(SymbolRegular.Pin28); RegistryConfig.SetKey("CopilotDockState", "Detached", userSetting: true); - this.AppBarMode = AppBarMode.None; + AppBarMode = AppBarMode.None; } else { DockButton.Icon = new SymbolIcon(SymbolRegular.PinOff28); RegistryConfig.SetKey("CopilotDockState", "Docked", userSetting: true); - this.AppBarMode = AppBarMode.Normal; + AppBarMode = AppBarMode.Normal; } Configuration.AppBarIsAttached = !Configuration.AppBarIsAttached; } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index c394df4..c6eb1dc 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -53,6 +53,9 @@ public Settings() ? SymbolRegular.CheckmarkCircle24 : SymbolRegular.ErrorCircle24; } + if (Configuration.AiProvider == AiProvider.Default) + CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("Default"); + // Weather Provider foreach (var weatherProvider in Configuration.GetWeatherProviders()) { @@ -184,26 +187,30 @@ private void CopilotProviderBox_OnSelectionChanged(object sender, SelectionChang switch (CopilotProviderBox.SelectedIndex) { case 0: - Configuration.AiProvider = AiProvider.Copilot; + Configuration.AiProvider = AiProvider.Default; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 1: - Configuration.AiProvider = AiProvider.ChatGPT; + Configuration.AiProvider = AiProvider.Copilot; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 2: - Configuration.AiProvider = AiProvider.Gemini; + Configuration.AiProvider = AiProvider.ChatGPT; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 3: - Configuration.AiProvider = AiProvider.GitHub_Copilot; + Configuration.AiProvider = AiProvider.Gemini; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 4: - Configuration.AiProvider = AiProvider.Grok; + Configuration.AiProvider = AiProvider.GitHub_Copilot; CustomAiPanel.Visibility = Visibility.Collapsed; break; case 5: + Configuration.AiProvider = AiProvider.Grok; + CustomAiPanel.Visibility = Visibility.Collapsed; + break; + case 6: Configuration.AiProvider = AiProvider.Custom; CustomAiPanel.Visibility = Visibility.Visible; break; From 1492a02c97681974da28bebd8afe75be653a67c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sun, 22 Dec 2024 23:10:16 +0100 Subject: [PATCH 47/80] Added Copilot Key Settings --- GoAwayEdge/Common/Configuration.cs | 27 +++++-- GoAwayEdge/Common/Runtime/Weather.cs | 4 +- .../Localization/ResourceDictionary.xaml | 8 +++ .../ControlPanel/Pages/CopilotSettings.xaml | 70 +++++++++++++++++++ .../Pages/CopilotSettings.xaml.cs | 47 ++++++++++++- 5 files changed, 144 insertions(+), 12 deletions(-) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index 0215f06..f9d7f5b 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -1,6 +1,7 @@ using System.ComponentModel; using System.IO; using System.IO.Pipes; +using System.Runtime.InteropServices; using System.Windows; using GoAwayEdge.Common.Debugging; using ManagedShell; @@ -10,10 +11,10 @@ namespace GoAwayEdge.Common { public enum SearchEngine { - [Description("https://www.google.com/search?q=")] + [Description("https://google.com/search?q=")] Google, - [Description("https://www.bing.com/search?q=")] + [Description("https://bing.com/search?q=")] Bing, [Description("https://duckduckgo.com/?q=")] @@ -25,16 +26,16 @@ public enum SearchEngine [Description("https://yandex.com/search/?text=")] Yandex, - [Description("https://www.ecosia.org/search?q=")] + [Description("https://ecosia.org/search?q=")] Ecosia, - [Description("https://www.ask.com/web?q=")] + [Description("https://ask.com/web?q=")] Ask, [Description("https://qwant.com/?q=")] Qwant, - [Description("https://www.perplexity.ai/search?copilot=false&q=")] + [Description("https://perplexity.ai/search?copilot=false&q=")] Perplexity, Custom @@ -77,7 +78,7 @@ public enum WeatherProvider [Description("https://weather.com/{country-code}/weather/today/l/{latitude},{longitude}")] WeatherCom, - [Description("https://www.accuweather.com/{short-country-code}/search-locations?query={latitude},{longitude}")] + [Description("https://accuweather.com/{short-country-code}/search-locations?query={latitude},{longitude}")] AccuWeather, Custom @@ -85,6 +86,10 @@ public enum WeatherProvider internal class Configuration { + [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int SetCurrentProcessExplicitAppUserModelID(string appID); + + public static EdgeChannel Channel { get; set; } public static SearchEngine Search { get; set; } public static AiProvider AiProvider { get; set; } @@ -110,6 +115,8 @@ internal class Configuration public static ShellManager? ShellManager { get; set; } public static bool AppBarIsAttached { get; set; } + public static string? CopilotExternalApp { get; set; } + public static string? CopilotExternalAppArgument { get; set; } /// @@ -152,6 +159,8 @@ public static bool InitialEnvironment(bool setupRunning = false) Search = Runtime.ArgumentParse.ParseSearchEngine(RegistryConfig.GetKey("SearchEngine")); AiProvider = Runtime.ArgumentParse.ParseAiProvider(RegistryConfig.GetKey("AiProvider", userSetting: true)); WeatherProvider = Runtime.ArgumentParse.ParseWeatherProvider(RegistryConfig.GetKey("WeatherProvider", userSetting: true)); + CopilotExternalApp = RegistryConfig.GetKey("ExternalApp", userSetting: true); + CopilotExternalAppArgument = RegistryConfig.GetKey("ExternalAppArgs", userSetting: true); if (Search == SearchEngine.Custom) { CustomQueryUrl = RegistryConfig.GetKey("CustomQueryUrl"); @@ -178,6 +187,12 @@ public static bool InitialEnvironment(bool setupRunning = false) Logging.Log($"Value of CustomQueryUrl: {CustomQueryUrl}"); Logging.Log($"Value of CustomAiProviderUrl: {CustomAiProviderUrl}"); Logging.Log($"Value of CustomWeatherProviderUrl: {CustomWeatherProviderUrl}"); + Logging.Log($"Value of CopilotExternalApp: {CopilotExternalApp}"); + Logging.Log($"Value of CopilotExternalAppArgument: {CopilotExternalAppArgument}"); + + // Test AUMID + int result = SetCurrentProcessExplicitAppUserModelID("dev.valnoxy.GoAwayEdge"); + Logging.Log($"Result of AUMID: {result}"); return true; } catch (Exception ex) diff --git a/GoAwayEdge/Common/Runtime/Weather.cs b/GoAwayEdge/Common/Runtime/Weather.cs index 4649552..b045b10 100644 --- a/GoAwayEdge/Common/Runtime/Weather.cs +++ b/GoAwayEdge/Common/Runtime/Weather.cs @@ -1,6 +1,4 @@ -using System.Buffers.Text; -using System.Globalization; -using System.Security.Policy; +using System.Globalization; using System.Text; using System.Web; using Newtonsoft.Json; diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 1a7d5b8..8e5db0b 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -74,6 +74,14 @@ Change the service to your favorite Weather website. Custom Weather Service Please enter the URL from the Weather Service. + Copilot Key + External Program + ??? + Path to Application + Select the application you want to run. + Arguments + Define the arguments of your application. + No source selected Initialization failed: {0} diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml index c05335c..6f2b5e8 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml @@ -63,6 +63,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs index 641fc18..78c2d3a 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml.cs @@ -1,4 +1,5 @@ -using System.Windows; +using System.IO; +using System.Windows; using System.Windows.Controls; using GoAwayEdge.Common; using Wpf.Ui.Controls; @@ -36,22 +37,39 @@ public CopilotSettings() if (Configuration.AiProvider == AiProvider.Default) CopilotProviderBox.SelectedItem = LocalizationManager.LocalizeValue("Default"); + if (Configuration.CopilotExternalApp != null) ExternalAppTextBox.Text = Configuration.CopilotExternalApp; + if (Configuration.CopilotExternalAppArgument != null) ExternalAppArgsTextBox.Text = Configuration.CopilotExternalAppArgument; } - private void FlushSettings() + private static void FlushSettings() { try { - RegistryConfig.SetKey("AiProvider", Configuration.AiProvider.ToString(), userSetting: true); + // Ai Provider if (Configuration.AiProvider == AiProvider.Custom) { if (Configuration.CustomAiProviderUrl != null) + { + RegistryConfig.SetKey("AiProvider", Configuration.AiProvider.ToString(), userSetting: true); RegistryConfig.SetKey("CustomAiProviderUrl", Configuration.CustomAiProviderUrl, userSetting: true); + } } else { + RegistryConfig.SetKey("AiProvider", Configuration.AiProvider.ToString(), userSetting: true); RegistryConfig.RemoveKey("CustomAiProviderUrl", userSetting: true); } + + // External App + if (Configuration.CopilotExternalApp != null) + RegistryConfig.SetKey("ExternalApp", Configuration.CopilotExternalApp, userSetting: true); + else + RegistryConfig.RemoveKey("ExternalApp", userSetting: true); + + if (Configuration.CopilotExternalAppArgument != null) + RegistryConfig.SetKey("ExternalAppArgs", Configuration.CopilotExternalAppArgument, userSetting: true); + else + RegistryConfig.RemoveKey("ExternalAppArgs", userSetting: true); } catch (Exception ex) { @@ -115,5 +133,28 @@ private void QueryProviderTextBox_OnTextChanged(object sender, TextChangedEventA CustomUrlStatus.Symbol = SymbolRegular.ErrorCircle24; } } + + private void ExternalAppTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + // Test if the file exists + if (File.Exists(ExternalAppTextBox.Text)) + { + ExternalAppStatus.Symbol = SymbolRegular.CheckmarkCircle24; + Configuration.CopilotExternalApp = ExternalAppTextBox.Text; + FlushSettings(); + } + else + { + ExternalAppStatus.Symbol = SymbolRegular.ErrorCircle24; + } + } + + private void ExternalAppArgsTextBox_OnTextChanged(object sender, TextChangedEventArgs e) + { + if (ExternalAppStatus.Symbol != SymbolRegular.CheckmarkCircle24) return; + + Configuration.CopilotExternalAppArgument = ExternalAppArgsTextBox.Text; + FlushSettings(); + } } } From f695c602aba7cdcefcf7036d9d27e85ce25b6571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Sun, 22 Dec 2024 23:11:33 +0100 Subject: [PATCH 48/80] Removed AUMID test --- GoAwayEdge/Common/Configuration.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/GoAwayEdge/Common/Configuration.cs b/GoAwayEdge/Common/Configuration.cs index f9d7f5b..ab5982f 100644 --- a/GoAwayEdge/Common/Configuration.cs +++ b/GoAwayEdge/Common/Configuration.cs @@ -86,10 +86,6 @@ public enum WeatherProvider internal class Configuration { - [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - private static extern int SetCurrentProcessExplicitAppUserModelID(string appID); - - public static EdgeChannel Channel { get; set; } public static SearchEngine Search { get; set; } public static AiProvider AiProvider { get; set; } @@ -189,10 +185,6 @@ public static bool InitialEnvironment(bool setupRunning = false) Logging.Log($"Value of CustomWeatherProviderUrl: {CustomWeatherProviderUrl}"); Logging.Log($"Value of CopilotExternalApp: {CopilotExternalApp}"); Logging.Log($"Value of CopilotExternalAppArgument: {CopilotExternalAppArgument}"); - - // Test AUMID - int result = SetCurrentProcessExplicitAppUserModelID("dev.valnoxy.GoAwayEdge"); - Logging.Log($"Result of AUMID: {result}"); return true; } catch (Exception ex) From 20692241eaef3177302544570ec8f9308a427c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Mon, 23 Dec 2024 01:57:46 +0100 Subject: [PATCH 49/80] Added Helper project for intercepting Copilot Key See issue #35 --- .../GoAwayEdge.Helper.Package.wapproj | 180 ++++++++++++++++++ .../Images/BadgeLogo.scale-100.png | Bin 0 -> 190 bytes .../Images/BadgeLogo.scale-125.png | Bin 0 -> 211 bytes .../Images/BadgeLogo.scale-150.png | Bin 0 -> 218 bytes .../Images/BadgeLogo.scale-200.png | Bin 0 -> 390 bytes .../Images/BadgeLogo.scale-400.png | Bin 0 -> 672 bytes .../Images/LargeTile.scale-100.png | Bin 0 -> 7979 bytes .../Images/LargeTile.scale-125.png | Bin 0 -> 10380 bytes .../Images/LargeTile.scale-150.png | Bin 0 -> 13463 bytes .../Images/LargeTile.scale-200.png | Bin 0 -> 19569 bytes .../Images/LargeTile.scale-400.png | Bin 0 -> 59215 bytes .../Images/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Images/SmallTile.scale-100.png | Bin 0 -> 2136 bytes .../Images/SmallTile.scale-125.png | Bin 0 -> 2795 bytes .../Images/SmallTile.scale-150.png | Bin 0 -> 3420 bytes .../Images/SmallTile.scale-200.png | Bin 0 -> 4618 bytes .../Images/SmallTile.scale-400.png | Bin 0 -> 11134 bytes .../Images/SplashScreen.scale-100.png | Bin 0 -> 8677 bytes .../Images/SplashScreen.scale-125.png | Bin 0 -> 11246 bytes .../Images/SplashScreen.scale-150.png | Bin 0 -> 14184 bytes .../Images/SplashScreen.scale-200.png | Bin 0 -> 21419 bytes .../Images/SplashScreen.scale-400.png | Bin 0 -> 59401 bytes .../Images/Square150x150Logo.scale-100.png | Bin 0 -> 3451 bytes .../Images/Square150x150Logo.scale-125.png | Bin 0 -> 4453 bytes .../Images/Square150x150Logo.scale-150.png | Bin 0 -> 5521 bytes .../Images/Square150x150Logo.scale-200.png | Bin 0 -> 7983 bytes .../Images/Square150x150Logo.scale-400.png | Bin 0 -> 19143 bytes ...go.altform-lightunplated_targetsize-16.png | Bin 0 -> 736 bytes ...go.altform-lightunplated_targetsize-24.png | Bin 0 -> 1193 bytes ...o.altform-lightunplated_targetsize-256.png | Bin 0 -> 20680 bytes ...go.altform-lightunplated_targetsize-32.png | Bin 0 -> 1674 bytes ...go.altform-lightunplated_targetsize-48.png | Bin 0 -> 2821 bytes ...x44Logo.altform-unplated_targetsize-16.png | Bin 0 -> 736 bytes ...44Logo.altform-unplated_targetsize-256.png | Bin 0 -> 20680 bytes ...x44Logo.altform-unplated_targetsize-32.png | Bin 0 -> 1674 bytes ...x44Logo.altform-unplated_targetsize-48.png | Bin 0 -> 2821 bytes .../Images/Square44x44Logo.scale-100.png | Bin 0 -> 1760 bytes .../Images/Square44x44Logo.scale-125.png | Bin 0 -> 2355 bytes .../Images/Square44x44Logo.scale-150.png | Bin 0 -> 2966 bytes .../Images/Square44x44Logo.scale-200.png | Bin 0 -> 4166 bytes .../Images/Square44x44Logo.scale-400.png | Bin 0 -> 9159 bytes .../Images/Square44x44Logo.targetsize-16.png | Bin 0 -> 580 bytes .../Images/Square44x44Logo.targetsize-24.png | Bin 0 -> 907 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1193 bytes .../Images/Square44x44Logo.targetsize-256.png | Bin 0 -> 15529 bytes .../Images/Square44x44Logo.targetsize-32.png | Bin 0 -> 1233 bytes .../Images/Square44x44Logo.targetsize-48.png | Bin 0 -> 2055 bytes .../Images/StoreLogo.backup.png | Bin 0 -> 1451 bytes .../Images/StoreLogo.scale-100.png | Bin 0 -> 2841 bytes .../Images/StoreLogo.scale-125.png | Bin 0 -> 3652 bytes .../Images/StoreLogo.scale-150.png | Bin 0 -> 4541 bytes .../Images/StoreLogo.scale-200.png | Bin 0 -> 6430 bytes .../Images/StoreLogo.scale-400.png | Bin 0 -> 16283 bytes .../Images/Wide310x150Logo.scale-100.png | Bin 0 -> 3689 bytes .../Images/Wide310x150Logo.scale-125.png | Bin 0 -> 4743 bytes .../Images/Wide310x150Logo.scale-150.png | Bin 0 -> 5915 bytes .../Images/Wide310x150Logo.scale-200.png | Bin 0 -> 8677 bytes .../Images/Wide310x150Logo.scale-400.png | Bin 0 -> 21419 bytes .../Package.appxmanifest | 49 +++++ GoAwayEdge.Helper/Common/Configuration.cs | 98 ++++++++++ GoAwayEdge.Helper/Common/Debugging/Logging.cs | 88 +++++++++ GoAwayEdge.Helper/GoAwayEdge.Helper.csproj | 19 ++ GoAwayEdge.Helper/Program.cs | 31 +++ GoAwayEdge.sln | 59 +++++- TODO.md | 83 -------- 65 files changed, 517 insertions(+), 90 deletions(-) create mode 100644 GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj create mode 100644 GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/LargeTile.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/LargeTile.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/LargeTile.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/LargeTile.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/LargeTile.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/LockScreenLogo.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/SmallTile.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/SmallTile.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/SmallTile.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/SmallTile.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/SmallTile.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/SplashScreen.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/SplashScreen.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/SplashScreen.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/SplashScreen.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/SplashScreen.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-16.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-256.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-32.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-48.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-16.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-24.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-256.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-32.png create mode 100644 GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-48.png create mode 100644 GoAwayEdge.Helper.Package/Images/StoreLogo.backup.png create mode 100644 GoAwayEdge.Helper.Package/Images/StoreLogo.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/StoreLogo.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/StoreLogo.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/StoreLogo.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/StoreLogo.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-100.png create mode 100644 GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-125.png create mode 100644 GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-150.png create mode 100644 GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-200.png create mode 100644 GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-400.png create mode 100644 GoAwayEdge.Helper.Package/Package.appxmanifest create mode 100644 GoAwayEdge.Helper/Common/Configuration.cs create mode 100644 GoAwayEdge.Helper/Common/Debugging/Logging.cs create mode 100644 GoAwayEdge.Helper/GoAwayEdge.Helper.csproj create mode 100644 GoAwayEdge.Helper/Program.cs delete mode 100644 TODO.md diff --git a/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj b/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj new file mode 100644 index 0000000..44f45b1 --- /dev/null +++ b/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj @@ -0,0 +1,180 @@ + + + + 15.0 + + + + Debug + x86 + + + Release + x86 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + Debug + AnyCPU + + + Release + AnyCPU + + + + $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\ + + + + 6b1c2331-6097-4559-9d50-62d3e906e2e6 + 10.0.26100.0 + 10.0.14393.0 + de-DE + True + $(NoWarn);NU1702 + E302D41D12FF036DBD37FA03D5C85F376EDF659B + ..\GoAwayEdge.Helper\GoAwayEdge.Helper.csproj + False + http://timestamp.digicert.com + SHA256 + False + False + True + x64|arm64 + 0 + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + en-US + Always + + + + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-100.png b/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..9e02d3d3dc8a95789b8c0af678186414678965e1 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9F5he4R}c>anMpkRTg zi(^Q|oaDp>h6xL2v;J>v5ad{qsIe(h=Y`Of4GfY8bQer}T^Pl{bcI8$#5h3bK)OZM zhlfGkdVUw!cRXTM>+`kslNT_WG9fBw-=cUs2X=+)0m?TYZE1+AOnT6i@gmB>^G5Pz jYo6weD@}pi9&8N884jV+KhM1d+RfnU>gTe~DWM4fJsm*y literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-125.png b/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed111a1dd615bb39870e0ee7e5a4ae9d3eab02d GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{3oCO|{#S9F5he4R}c>anMpkS+~ zi(^Q|oVQa?ay1z6xQPDxzkkhF0nSJT!ON^^>z002^UkzZTdB*qZ`ZkXTob1nU22^qcuHW9h+rd@0tcdec*#9Hcs1K7IDM5peX+qEsbk*Hz)s zzH0IFrj|~3I$`izNBjT-^BkuCKh>+_vO{?c4lv}i?qfVAkPy4;&U_i5gBUzr{an^L HB{Ts5tujs3 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-150.png b/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..8b51e1665ad2764bf451d877f887743203971d62 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBI14-?iy0XB4ude`@%$AjK*1hQ z7srr_Id89CrT^Uk9 PcQJUn`njxgN@xNA)zejp literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-200.png b/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..d7175db78f2a8038ec013736553000a69c74a712 GIT binary patch literal 390 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC&H|6fVg?4j!ywFfJby(B0|TRl zr;B4q#hka(FY+B$;Bei(=9y&auDS>S#x=oi;#HH)9JVcE{<51@ z*XG^!$XRR-wTth6TCz4jt-p}@i`v#UW!v|xg^Uv#t&i=zQO9$IndgC_esAj$CkErQ z{mD^}Vud8p{4xMM=Q-*cgIAAltUjYU+4A(&wOmMDyZGkfn_?=m%f=SCu6Bw`zp00i_>zopr0ErEpKmY&$ literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-400.png b/GoAwayEdge.Helper.Package/Images/BadgeLogo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..7a26f49d70c2ff76ba28132c11653aa9459f0f49 GIT binary patch literal 672 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9F5he4R}c>anM1_q`e zPZ!6KiaBp*UCcYIAaEdT<^TVuqt$skT{Ar&9GGy!Kk{~<#q&OqiaO3yliwY<8_3YZ zlpw;em_dT|fChsbqd_}s&3=#T{o=K|Hk+9mYH^*A{`+OtpXcUo?kW*YRz)sNNXnmW zVW?-WdGoUOB3XQ7X7!tRr`VNSpPoH1G^GJ#z$ z_Bvbr`m-zQ+zO%&T)g{F>K?1^s=F#BYMhtfurE3A#pctdv&&v=ymI2GcYxf7i_d!( zZCYnD0 ztxL0R3T=_q(cM)x??qhGqT4m*7rt1jKKdkCuw~BLuy3na1YSSe%wBp*NF{X_r$V;j z$Gux;Fd9r3GWfJoyDN{W%C`5yagRljM$B%W1@1Y5QF$F%j3t^c{{EeQd&>KR-zMZ< z*;9NoS#$4+%?nd~Ulgf7c3XG)P3qxqdl%>C{NJy>km*IG;#bB0zdyRaEUte4{N|Q& zS;r2BPd)XW)Bf#|4xg91_HnL|!C~3`R?}y+gaadut6`u)X-b)0G+Z3@RzT7Fw@0 Ry@5%N!PC{xWt~$(69E5+8FT;u literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/LargeTile.scale-100.png b/GoAwayEdge.Helper.Package/Images/LargeTile.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..a1de9a300848685d37a35def1e8c34177d3e6897 GIT binary patch literal 7979 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 Mm5yqivUTMD0|df@C;$Ke literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/LargeTile.scale-125.png b/GoAwayEdge.Helper.Package/Images/LargeTile.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..f103ecc1ae142c838087ba585c14e54d14ec160a GIT binary patch literal 10380 zcmeHtS6I_c^EN61q7hmspNkJi~{OpOESxC;#!nGU@$J~oOZvbdw z!hd8XW1dl6?(&k1YIBs0-TOF>>pCyhg7z%f44K)IY%ksu*%+R%GE%;<=>G z^Onc?HN`U;U7D7)Z7g;dyNjwQ4dajHz~+@_J^QwP{=)CZ#DpQO2?kt+VPd7AsQRNV zOF>cX$-_uNK@~|sAwfe)@mh_Cg5t*IOBBx;X(%Y(s8Ue;LwT8^>wjJThs*yVgMei+P3WtJpN2hojDFqrs70$#ZFVv;Ge&9hXp4^?e%?1A5`X;U3k@Zu z7rqS->a}7Y8Sv5;!faiQlpfbdiLFf7NzBAGOuq6WU14v(PB{7G#T4X0dHJ$*nBCmc zC)B%x+O1?i+R&R+slK#V9c2TAr)R>e*ejbJKPvS_Yd2j}6uW#WvX*1Z&oV8{p~zXn z!cI``s+N#kdTXbW&)2y(oNSS=yEsUyb6Og7baj5Vws&v5<4@lP)|c#0O+Z(3W+KnM&6avawbSn{KPpU>zzC3;3%ib>wT_79YzIImO(HUoRi6 z5#qxRZM`pj*dYu2ketp*`@m^coQV1@+p!%X#2WwL9(4V4rYKYk5jykgCe1%7aHaj; zs!ymNhS$pvw{67otLNuFv0XZymKQpNC0A%6q7|Fx6{0r_`>an!AK{uJX503cv`3;x z>P7Vg!a5I^HTuNavHUMiHF&A}g{G*UE=wEYo&^t_`ZtvOMYm@mSd9 zD&nkKm9Bn7^7`kf7gm&DXTm|4D{LY*b-0i8p0+CAU_XN1sjBw)S+3`x9u^7QL&C<^ z*uVaB?~Va*FKYeZO8#C&EWyJ9nl%PnPG+CZTYj~vqFEU_BX*OfEQ5u1CwIiD$7|Lz z=@fG>e<)-jI+JgK*#kmDX*TTZ5%X->GwsBCS;8l#|8IA`@#og-5>YW~|0g!yh+>KV z;m}X;M0pr(4EWqdz4vK5NO#nFaV0@F{pg{HWOEN`C*# zgXDXyDBpeDp8E07_9bH(miRRg?!rd!*534&DvoX^d&Q?@bj&$si11y*3&hEKV#nre z*!MluvS0h8#2tfOX>(A8`%>G1GneAHXE*+%>T7Y@6ZLdt;Pdk_pM$EFDfw|&S7Ic& zxiV?WbCy+-=KG+HzwWP3UerN1C@-HamCZed)t*IUgd*FzrV4i2Lk z&3$ympz_g!NrBn5-T+_>gH!$WFQOu*=ktc$WFsg`}2+cQi$_PGjd*N zhCG5iKbrv>>+9F@+f+DK!XqacJLL_>JDpZs@n zbpx4IIbd(2#>2I=nAjaW-TsM3fswZ7d3+>{k8v^H1FiE^M0h8)*XfphvjtiO>oRzk z@n7WxznZ!VU2aD_wiwY5f%lN2XuI~QuPFuFeMGPBFiA{b3*5OMyrZI^nO*Rsa-c6AH zuVRL|!OwT!3tyxODK{i~Sj#X_)L9On|6JYgcdF}uS-T5Aec6(Ky>*twS4F*82!@{2 z62q0j7X@)JY`sR@TfVrS!Z=Mn+URe7^IZo*ANp%_`DFOgZ>;%n^lgS>$8SgQP19@} zkumA>1;>3C`JPMDLy$5guEk>Z=v^c(jV9|nNFOSbadUm4ky>Ie^NQ^JyW(|^^G{@oG9gRGFLdl)esZJiTnb;@Tx(f{M_6;QkeEh6|)`m z+$=G}v^Q>d%l_4^dOkZjU-yHK;`{cj3xg^{cO)EHpg6VB-%zL!3Ij?eSbYJg(tVDSnL&jaCZ-+OewB#h^T2Jbe>~D)d%L9qn z*%+u0BI3-ubs~ex7D6&sAeb|3_8fT$*4H=ZCmc6k{$=AH&vp5%F5+zH8@}83^Ld{O zy)=tVzAFA*tdoAl^vJx#drtxTQFw8c6*4b4Wtg-Y-d^v!tZHb#!8FvfEV*J#CWC@3h@`@bm`RtcU7Vxv0Ga$6=&wP}+TnEb z@CeZ0-PT+iRqvkrPBtFENsBOpaap-G1Pdk@amO zxyLh?ib$bv!a=~?9rnN;*Hc&Io_?zC5nO&>@<^(U@9JMG*;HU^g-9*-jrXRbpJC!x?I zB8on+B{B&+05$T_qj>VI@$?>-%y<3dJ{h->Uk(kJDyDi|{oWlFw-vlZ_@2h;MgiNj z%Tx38P4+wb;`U#_L9=b*jo|NNlzq5(+XNNf4 zhab)86;-^0_8C9dO~X!8=a03O+8Jv-f=#c1cVt38B%XHd-oco_sR(Ph)XzU#yT`M! zrq<^Dbn!u=pgLpO5s0Qr`@zi#|CwNvTyDt5jflbXe-!7fBOR5#L+@=1=><@h`oB@GA5dtvu`UR&Izf=wfPt zi1x-!%yKJeuS0%INF(Xm&4OB-aPr1ldfsDENQJ3+oB8ZT3znQtponB1c%|~e?IF6_ z;t&;bxa7w12lo8t^7n_X1RCsNG1i*13sc2#h#x%ieu<~8655)2|2NPkFk`cVSAF3csLd z=4BxrYQe!D4V1!bZvl*z>cSHYIu3)KGS>0&Ba<=oSzH#`!M8Dm?Bb90wQwr>pyOYh zR_z6*vJvZpU9#UoV~z(i9~z7-G|ihmJ))m3fBEz0+-|fzn@cnf=tKszPVpeNrU815Yla}-b6Wh7wx{Yt0SMwk4 z%PL16_}%5hfm4teJ$vYV(f(X5pUx_teqa}fob)+{#;ln6F$E587Mk%xGn2EW%8NAx z?7-0JM#4rSL@{vY+ZW8(=}uwx#f~KLxCv5pTXARtX{e$wO2}63cm@kJZg8%P)2fIw zBsoSW-L@hpQ^Mq=u9hRyL24jRU2sZN$Jt*Y2v<%VIv>HJ?++a1gC5&yZ7V&B!Q}Xi z2H1k}*ARzIkf|DK1ElffmW}s?QFWmkb`4 zHBeFyRwBiTbu3*vU#cCULM6s}!Ckudz5GQ7?cVyy-jgH4K{hG~tzYrY*7Yi3%X&V0 zZ^5wYbCcFqSiX|bmtGd7!$I2feMp+i9&~H6^!?qjGWlly{JAgLT%r2QS^3lH%HY=> z{=FO#Yx{Ez8_|HQhQ5_9lw@N8N~Gmz%|uTyMe^keZ18WQ98W%*wej-Rxs^rf{n>~*uf{ z>lO6Tsdb|54K=#raCBLwsda>>wF;aD(Uzv@fZST7TMS~HC_A>6i|fl-5Bsxa2#f*t!)fiXj7tz&SCrNq4x$(wo-r1!86?BH?=wvayP*0lcH4)4ox*B$B55AdDi{*j9> z0-y+8!ucPY9r>20x>caBE+G;Zt=3L1zZ63R1fkP`{rGp)lb`_?sOWzGTQ-l@E?3t- zERhr-#~l};6}j7l#)cz}q*Fs};g$M>3@`@eGjIhm5lDDku+`yPL63GQl$Y%m&T*#q z+XDTnOJ#>k{;4a6+2aK%S9@epEb%@4;>k;}_xo%8b)ocqk$<76FscS?_>J>3qKjfA ze7*<9Ijl`RgpkY+4NOk)4TKF-t-;CpWd@1-__rd_qJ5roB{f7pr?%Yjx53(1^>6Qh zo_p>d1#(*9ol1WP7Rjbo&bZADB8y>0f0s?B4nUb{ldg~Ufn`upU8>Tud0&?2P@=Q(Ew@hIC3O(l{f2_G0c5{ZksBov5~#m%!Ch#EPWSZ(W>u(FOGoV zM&dyLE!5b|S{V`g!)phTdCga=9jpCeV*KCWl(oOTKWI&@Uv)fL9}u+RaEQ+A??kwN z8dg~1*-@~c>{@Rx$Z&-nfrB$di;v(^~8d5q$Q0e|4n6{-Z!{fmqtGX-cin~15W zZG`V_j~1qZ9^RtK`ey^zMdo!nTA`KN{;!`Ej;bTx%{K=7P1)+!`#As| z`aX(@`HSK_a$dxGlqMk#QcTaVz)SbZLCe`dU)bNZG|c}1I8*7$O^nK%;|6QSY|B3l z(+fR~E9S#zeZ7`oSOJwS-t_rl&3(Gt{&xJD*A8cHR$ZS3C!}kVw`m8bga}BjB5j#S zH+=}K`(mM6KF<~9h!3h;VJ7i0GQNFzB7H6z&3CiC!^M5^0dh83Rjde<;8k&u#IE3l#_BMn*wcdeu%>K7^&_w#Y#0Ie8&L+E_Qn8;v zGPMOq;v4d1HjOHFvc7iLyRq<78QNp6%p6(o+N*ejkm7*tZ!*h&@4h}A45FJfVnWIq zqCo2)LRm#c1#_ZRvHu4Q$z#{^g>H$+(D^S=;9fcPW^xQ2Y$H$B_0^HB;Rai<3e>33 zn2t{0>z^MoQ>ObVw!G7NLQMZENMT`{TA6XJMHXY0U)(c*<_O@a4Dm10l%6c>DA`o% z+%2jr!H%U*Zn)2z2XbsR~?m*N6oRf?f~!1{5k zU>!ZWp2$A`%#|Hs;*|F#XO9$rvBU_o35K(_H`+O9eoQ-YAH|qf>oi%z-x&)QZf1dd z3XPSH{j#}ih-~`Y)u9u1 z?v(n*86Ma<`H@lv8_V!5THtw~wsu`7 z6?pol^xMR097hW$+q(~oisXD{pw$p=Uz+n^eB9guty7dC^O9qs#V51lEY^~x(^-(i z#JdE(%_rE7dV;(d@KwN7P#p{6Z>=&Zsh42N;yO07?v!rKf%*@>4c@L`@~+0_ zH@RbWxZ>U_J5;^7c_-ks2)>cSu;bjXZ+7=)d_}9QyL!Pq5?tW(-8^w3TJ~|_Tz-fK zo&Hce-hV3Jf_?*6SNsx|o_I46XTW*lT1^c*gg3cFk-SC}29d`~phoL}i+5&1%P^V0}VlHyxx8Fo`8AN zKOJzU!WfDRG7PqAz;P})Y1p8jV)3ul%_lHBNS%f``lMM*Vfkk*#y@>ew11UT)V2jk zy`$_ZF*Gfvh3{+XJS#f%*c}5 zU-!k#Mu&eys#V7U%;azLX*Vo;t`#yZFn?E6(wKujhJ|*vn3ucnttu!#c-S|;f-j9< zwom%>^)m(V8s&~+;0MduNnA8wD-|aU2o8)pxV9>kmzHKKc&8}fYPc3pS8$Nrq^S?> zZNe@W^xn-l|7v?eY@1aO0M_BV@c4Z1vuS@8lZ$7Se;5^$^hNpVT2f9gYP0*|l1>mO z#zT2nIY``pGt0d9#q4Gf%wn#%31zyuxnru3E$b+@357~k)mV`)?8ecG4KC(QO?w9H zGkN}D5-P1*5AJVTQ?0Q#21$KqZA%hesRfD+{0F6r)yb_HgWet9A3|aFzGB_hYqO&> zU)j*%8W_axE89>~Oh5SOSUj{Xru5q{ zN!`Txlf6DY?~ZN^vcwd940b%dsZ;qIabYAvZ4$y0Jwfahzo=y3 zlCTv$idAds7QZ9`n`I)eQ>-0K&GSqy&Vop3;afbEy_ei|m z_*JBG8KPt?uE%{aahqhNnb!~hhy_%yFh`Of3~5TYO()O`s;=bJ#q9b~h*C6N?t_S> zuTA;c^WLS?PUj@d@Z=uoJazbD%#+x2Re+(K^UYC=R@x?Lo-rQzQK(VHrXtns#B86x z$G!ivDP@$ZDvt;g4W3b``3S-dwXhas2DCM*k>3c?7aE@oAnUg8Y?_+ip3q*8jj3r0miC_&(Qi- zU{WfA2+g0S#^*db#J9z$7knA;%7R025o!rVR)Ewp|1i0+NIV-IDJ$dk*J{qo>O4G* zuh8{zH6}uoY;l4%00-b!TdnUKgA)>W;IOacVRW)nIX?+MF|I5V_KvG%b3lPW-L&!N z08-+8_MOAl2gNakOaTd$+YFd{kIKT^4X>v)xE{{z#bwC9(RRIcl1snIaqse_OJwt= zh?O2oZSg_tZ6rnJ;#v(C9a5g%KTN)`tZ2=*D1eZDz9O#Nl+?RFHnbz%0AM&jyN);u zJ_zW6D1E`42gZt>4L(#@Zoa}2ulWuwLSVqs-8}!($p#hX20)wYrS8Zw{Vd_og4mjI zS4Epv<~}L@*G#Hy{;3iAZ%8<6tIwMxjz$*fwQ^}zWL6b@#4744VprU7>w|n4_J>BW z`FE#P;lfYVVhURpk{=F>vbiU(s$3+$IzBxip2fy&)H~pj86|Oq(c1*kP)qZ3*I3r} zTH~XkqDhkpl_$(%sl)hC{~Y;{pLfZGBfkmz{z)s32$s0h{OaODklf1m#f;{waYQeQ+BPdIw6)G4M`@-C}u%|`W%RRu;6?9&zyS^2hT~K^+P*ERUPWQ$yrQUEeC=-t-4S$ zajX;@WZc$$hY)A^%9S_>iE;?y7VQN&4z)eZ4lUtX*iF{VgwHvKCvP$V`d6=SYUACe zPzFkMFLLw3Jl{+QII%#hjQzLnMc?&e4Eb(`c6CElnlIisTg?8grWm^RUvxxD=M>qW z%P|jl#ONGc=Z&5(J#-`R?|8Zhuhd#$=AbG{4ZvU#5~ycBhVbr*o_?UOH1fXQuk8}z z+e}I{pIPaB@y_C~d`y{&%6VFtySSiPg?1L9cIX^EW|3OKM0ZE2qrd$^EB=5o=;D&X z8$qD?16f9o0sj9?UwwTOp9l^(vjQVn)@+F*kAmVFl0+2mDsq_K1;REFR5(G|)dTsX zRX?lTL3e<&PBhZ=N<(ttSlRF0p;sxV_Pv|!rF$j}eL|uUqQjuW7{d!S`RusKtEU1D zgL|1?!~ey z1XfeOvVGj5>3y0-vhB_0kC)A@dCbw~zBxlrwj}xF@dRx=E_Rqt%NowGlMtxR(3Qatf-&P2^V;ZTV~~&HqrqKpF6}wW-QT@bQb#KVrd~zv(WN za6}f!$kO7G4lOz(eJHe_hAQ&)bGfAy5rG|aubU>~fg-(kQGW76BrCam;I--sUo_gs z&XrKp=tRj~5iHWvPS@Vz6FD*dFVo9{a{^3&ZraXwpI-;=iM&OF`{=BAD9A+=HH+g# zk4|5mc29P_6?<3J-2b3q@iU(!BH%0g8_t{L5Emi~KT&$4EOg7;IaB^^-gCDXe}}!4 z*I|{7O9;>nx&eG>BQHu9Ne&f;o*@W_gO9*9r{|E-_~E1(xFLyNT%%F zH^4tKY~VFaAw#$*haQTTr@Y8;EG7S?K^6o2xhu0; zbo=3cbW7UR7zIt58{}FIW)3Lht6YTQ(Rv3d+#feMr8FUJ7~hh|`_4HOtLW=kqoD-?|ai*_{Mu zeDriD|D5vduhl!)2WCI#aye>HwF~TCu#YhvisM7wi3zHzU-F0}SNwMkF+vd(Gw*Kx luj1-|m1zH;<#)>$6!SBAW@a`J@<0lTXHN~DRH;9Y`hSizN*@3K literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/LargeTile.scale-150.png b/GoAwayEdge.Helper.Package/Images/LargeTile.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..2a92acbcc29874f0f070c5eca7102aeee5fb3cdb GIT binary patch literal 13463 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�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 yGvCsSX*m literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/SmallTile.scale-100.png b/GoAwayEdge.Helper.Package/Images/SmallTile.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..63ed1b4c80d1a462d66d0f2b947922df788ee5cb GIT binary patch literal 2136 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/SmallTile.scale-150.png b/GoAwayEdge.Helper.Package/Images/SmallTile.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..2c14b2a7c47033bc66d6b254d60d0f61b4b8e03a GIT binary patch literal 3420 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 YusV9?^l5JPs}2AoeRDm;9hc|-2Sw>fYybcN literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/SplashScreen.scale-125.png b/GoAwayEdge.Helper.Package/Images/SplashScreen.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..dd3c95c0cd1b9a56db16f74c3dde713c33dcc9a2 GIT binary patch literal 11246 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-100.png b/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..3469b022206ce4eb11ecca766fdb8b6ef433dcf1 GIT binary patch literal 3451 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 BZOH%t literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-125.png b/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..1632d2b5158df7064275ba334121f7c1c15088c1 GIT binary patch literal 4453 zcmds5=Tj3}um?j^nw`)RlqMaNfCz#}2Pu~>#n7Z1Kzaf}x)iTek*?H)7K)fq0wFX( zB1%UfGzq;IDFGh$`}+spn>l-Sc6ZL6o!$L?*o`wX&|U=<*ZLJCs_}NGHh+Wz}FAxp1i=2 ze!r-*yM&yO7V?p{d55%8mU;Xu8D{(pXc9`2h66^y5d1OF3e~ zZ|Ua5{b|+D^MOIvuK*06+Ry0RV^O*s9WMM?dQ0FYLtYe-kZSaQ-zX;$T!Vqv%}pNU(MN5m-E>R#38RO=e4uu0UcsU^K?1*g##^wik%LA%gQz zs}nWQgbhe38?V57c>!MbJ>O%MxN=mC9WsqG?n~CmajFb?gi`mvmz3(-8Y(!>RBD@v zO_`;WGRZq0Q;Z@#4=2q&Q#`>fXsC_Jg$qsqw9iXcp>Th?O0d?bPsSa6vOfRoli)2U z(`ClvO^;sej{(OStp<-$ims;OhR>0hWTNmRH9##^gS2;vY;57Ix*pEsT`x%t!3Bxa5LWi6<2oebIQxfZ^fiPGjKc@~KpWc>W!JG0Sv+?xkcCgJo1s)Wt zvbkbY`$YA$S4+>Fe>z4pp@J9b#1?e%Db3cFf+HKU);Oy&6OmW9T8ZQHqMMuU; z`}uh(S{I#=c~vKX5X9Q$A>uEw5EBm8h)DbAe&&|~CqaB1b;!?I^Ji_B$Irx3;}zpx zR)C6b@4}JU&tK*+k{=fuK z>BUgYIPb)LAs^^^?(CJNt)+#Q-9Na2K=S}Ly`Pdq(Sa`%8+YR{Ujs54^Imrl-WN7> zVwNLYip2GlQS?MxWN_?@^0WLjS@&s+6^GuN02Q|UiR8D%^>hMg-S)BcH!NN~KEJ0ZYrL)Krgol7dwSVa0vW@;li5Y! z;D8)=(l^O|y&<*CIh6FnDM{BQiR8SmxCk~1^L+kc_I1OIf76T~OH1}M>BE$?^31MI z0>@|U8lb_s!A`h^sfQ*1+Lo(0TYip)?^raa3H77#t*7bJtg+&Evib_@RN~a8F7qs{ zM4ka)7lB05ca`!I{19*o?QH>KZlNk|ME+&<0=s37CO;JmkmC89amP?hy8 z^wo>^X2X3WwMNWh@06MLs`J-2I&6rL~r5xLr9r}%N>;#{at&< zG#f~YBdX2a*UoxvkFV>MCdq~RC;vYWTo=_Wx4P%lu$l;g2qW&|nmZF>&25|{XO7j5 zdkbzK+OkmxHv`nzhKUP)i6-oQfi!i_TpR#sRMBUs$*>RNx@P|4>+j}sk|IvLEcY1M zPdgc_3hYKA5npmRo?&?AqI5-=0;Au{K{S+72 zdG`4Pim&0iBF56h1MseIDLZ zeOlG7Dd9pb6)Yc}f$8&OLQSa(ra93!b zZNA?eHv8-B1Ur=>Fy!?97Xx&itzkNn##TP;ItV#W=k8G^LzR{_?+4a%K@9)Y$47)q z5sM!dh~9U`I?>I~_k{z^Uj*HjYr(R=$Ap2|r{TO@`>=%c-O}YvCNT_A5uR{f2Id$GZ+e&T1@EQHFwa0O$567?y&dKB-$0`PG}@GZIi?(<8YRY!MKtn##g+YzAum{>r@1XZYE?92Ryth zV5YZ3a=yfdeqAjHIqqfC=}N8wg)Ghqg}}=2%7=wg&9U8b>sl_o^kIBXk{n}rG$0+` zjy#L|2nuq%>fv=+_2=rFf+AlI1ITvQz)X~Y+eMpSoSr1%l(hcCQ`d9GL3#%0{AhLo5bz!lFsq%`hDgkwLsxVw&~jt{Jc zW<3*1h|$eo2n}o9=iggZJ?qgAi&zC&VpKl%hje^C1%JZ>f^2J**{bDTdEW|FZwB3b zVW^K3Y5QcutP-Aa?>A(_0poNTw#05A*aPRlpov7LOH2r*BY^iI6bO0kR(*?sJTTKT(w2~= zz(FRbcWG%g$+&bCMf`n4e(>hGL@8_+ZgaT3zgs;wi%lBZ^s)(94gE_-C9a0G(2BJ_ z@(7#cVvYIGLR!cmDH-zw&m8z zFLqa8o?`({lLYQ^q1?iQYDp!R>l;vIZk3=NHK#}jrL_Dko@P!*7X514#eyJ`?#IfyH}@96ZvkL%S`e6W*3E-kKn zzq5-ZK8$Uq}_-sPmbwLfS2lbQGi;$dtT#6PAaCXs*PW2z1@ttWOl8mo_`}SoE$d2 zwb6~+)^lWMXfMj*1L3wELN_qfOv8V}9D68SL59#fP zz~#x?6~O__jdyDbeAfoK+bONBHttd88nVf9{ie6~8c56is^$6P@vMr5pHw%GZ~pdm z9YXC?IDP;IG1nGok_hj!=+ky8kq>!@KYj?no}XR^H7w}vdIA_6pByhF^tY=Sz9Jg7 z`qo!2rU(Qt{n2a3AO7e*JlX|+E;*~1yhTr$dB+8L7ilhbQC()j6Z<0+_0LB0eM$7s2sa zo^u{;%A0HZ`>bQ&<@TMhiMQz)&$^+u5XSmhJ`mnf0TkrG-?E=7ytOaJF%z%xAVJwB zaGC~0ow}{mPz;!D6be!T`SK}(9GMGBxU`Ds@Wofmx|;gml5SiticgLl`4yHq z&F3Kg*t?-`Jk3%x8sg<+e4%$5MXNP(h5x4xBt2 z2A|~D)nDS+_F2i3PsT^kk?$h)^$YG3Zj&#P^;v5$WxvZ@rBv1-K%F~OC~|fuY|#g? zNBgQUI3|1^e#pK#5(@wyWa_brQdM1Bt_JKm_f6!osVJqJq2vvVEe@@TVzkd{(e)z4u*2JS4fZ#HZ3@y zb0Wa?)D?EbH(` z#my~1FKM|a!^go)~tGqHb{RFt7BkCysm j{y)v-|J#b;objKqy}<@+eVdED35|}1fqKIyo literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-150.png b/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..ced5999414dc2747a29738aa7ad432a91a459f7c GIT binary patch literal 5521 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-200.png b/GoAwayEdge.Helper.Package/Images/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..72add25b6ad3f53a338f91c885463ab7dc6722cf GIT binary patch literal 7983 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png new file mode 100644 index 0000000000000000000000000000000000000000..935f3b2d685142263b505a57fb113e587f4f31ec GIT binary patch literal 736 zcmV<60w4W}P)pHl1W5CRCt_ilS@ccVHC&z_c`xr9G&dplvASQA__tfEf?*oO}J2s6`+|M7s#2b}ifqm93KqizsXCVbB8|A32WRdC$Gy_jSHID#V?0;oke5 z`<>r8-~XJeW7Co^vfasOcv9H4px{iPfhnq{sHU%!$>mS|Jl*_R`gD1_KAkz1HG}u7 zrkQjKHk7*CW0IrIp|U zWrxGI9mE5g8<;CGsH%pbsX-8gGgf?cF;(3LxW+|MKJsN7sU{tlkEd|BEkXeT=}aDD zuQN!m)X-%5As8=hg>3@_=Y?`jV1HD_=$UbNVvq*0+m_igh z0LDe3W;663Fc9{ss4^-&Z=p;_>2BYRfX~3l$$c0ep9f>edjSs58z#qzL%Xmu9>daF z0e2>UVb!YO$)zU5LVlzYAw&tDvzQlPGj8qB6&!4hf^&|=)pdNMGjpLL7Bt*FQ(sqH zK}kw4KsvJp2eS(s=9mMAQZ0t$>6p3aAu7 z6Gsp^!X;k+rjmwXMZ)MJQRQAQ0BqT*6xZB;VKY$K8Zud+OOo$JYB^ipiu(uji8C+B S30a~50000pJTS-JgRCt`7Rb5ORRTTbaW@lz+c85hEP>NVAwvZNyt*J?^)%yEj z`d|~I*2KmqYvNmt8lQbJ602{<8g0_VXpIk=G^sUht)WpAQ9>~^6{tWFSOk{+nf;l$ z_j>N^vM#hstv8v>y>st5-}%0C?wJtQjJ;er4zYAfg#xj5|As?A(V`A#$>kHh zkJZ0gxfQBhw4P3F6Hera=Q9XB{GWWU4DJ(3wD!oRQ-6OnvA^N+bpWsb^w-NN6Ng>y zg85lMy(RyW1vJA#cZ>CDw14))cXn+!ww6K99d*&D8=rw<-KzHz22a9nY~Hyvo9v$0|P&dekPzc2{`-_Ifz38Tm!spC zlPdG+MjJRmHU7js#RN+bIo^7v8(TMw<7EE~KDclVPFTYu+nY$&6y`HzE!({Cs{?Sx z)7qdc5Q1ezk7AXS)G;0o6= zRRI)D%Mi`HqJ&JzLQw>2Z4(Jk;OpPh&Fh|*wB5ppH zHp26eHbVKT0A^h}C-TNHRZ<7{R-L=)Q1zfyk61IYRfhiny|pCFG!JG)00000NkvXX Hu0mjf8o4VH literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png new file mode 100644 index 0000000000000000000000000000000000000000..474e3eeacedf53755106ce68c157234826e0a8b2 GIT binary patch literal 20680 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 X;Lxdh#(*qz00000NkvXXu0mjfZ!5_y literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png new file mode 100644 index 0000000000000000000000000000000000000000..74fb84782eeb6126c8debcad2e4d35c532c3ee8a GIT binary patch literal 1674 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 XEWLv3#o(B200000NkvXXu0mjfa<5@O literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-16.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-16.png new file mode 100644 index 0000000000000000000000000000000000000000..935f3b2d685142263b505a57fb113e587f4f31ec GIT binary patch literal 736 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 X;Lxdh#(*qz00000NkvXXu0mjfZ!5_y literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-32.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.altform-unplated_targetsize-32.png new file mode 100644 index 0000000000000000000000000000000000000000..74fb84782eeb6126c8debcad2e4d35c532c3ee8a GIT binary patch literal 1674 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 XEWLv3#o(B200000NkvXXu0mjfa<5@O literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-100.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..9164c71286574079e9bb60825afee8ec0cf1f550 GIT binary patch literal 1760 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 M07*qoM6N<$f;eG~Pyhe` literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-200.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..5165244748df061fc8f0ebce6aad9f42cd99d6c9 GIT binary patch literal 4166 zcmV-M5V`M(P)pU_(?=TRCt{2TnUsM#d-d!yXT(S*`2+$(ypYHtQA75Gw1+C5*CMI zWC)1M9Clua3B(SOgJYh9c!bDG;yl1SlqWk*;s^*rK@oPq$g*q+SqBIS9SC#*y3gI& zYwqdk?n+hn%(B{ZcBk9S=FRtZX6NdvzrXqWKdVMU0hU7gq6PT>jsn3Jqd>65C=hHh z3Itn>0>KueK(NIq5Nt6D1Y3*(!4|_(g6C{*p6T%Vp3xL_DpgW8N}w++vM#x zm7KC-4$BBu)c8tgpu{V;v~!iQYMPv&wI*OME%wUE`LK=k;e5eU6-|AE%^RFEQ)uVv#iW5y(N9Xe-%zx~VO z_IT69jYXB!3zejd1~CC876fq*6LQm_sUW0c@2#TUajWF8Bit0(^3+H4=4Y-Zsa(d* znP69$Z=B8TUKj~BGkc~QFLKA07ZL9uz+{%=%v7)&5k%OW?&}lLOXJx)IXS+Z36`MR z)Rc_j$7p|`P?eN^Zn=(>Gr=iU5#0V#P?n}C$v87-a(;(q{ehhWk?fEhE_Mn8vDRqL zUOIOtN5pU<65hqX^>|bsr$MZsYEEYB3j+})2#7VgJj$nfc*)K!*D-S@_@C#DV#45B z{&@Zi2Ua=!fxlq+eXhfPA+UK%knCuEecNMGzh%~#rpCd{H$((7d@Tf*T@ZzwwYDov zPBchZcXh+m-*K@CXvoYl%_W%94(=%Qhr^6z!fh_Er&5}~8muwlsHO{P=CHpPaE0Kq zYxzttAzHXI*%*f4vh#B=b4+thghC@3g3Z-pa^=I$q0O6v$Gu#30VIEIFcE|>RTaYw z=W_0(^A4(}A*Co#6jguBAuuvTk)^Ye2uTtQ`%fJA6)?PHtRQ&>EA`6qeBv(x4CN9@v1Zp9d=`u% zP~wNgG9M#c%u*JLq@p2z2_{-BPT@`vPH;cxWCZla9e0M!Ev;xQ7xBcBX_zv)d`NS< zop#(YyB;@B9f{SOkK*O`FT&+3fy-gfQj-b)GU9|t@gWJ&2h2^Ct47Ar)*53jxip(| z;!Z0V4C2nl0G_;kS}$f`@bED6@c5D`m|9nYBDSSfIbOzN=E-4h9L%-g*}YLi8~Xf+j^oGDpp>R9Vorr_pZNKo=1G))9_iN`;80?wD@=^xbfET{-??>12HS)em7Wt$-k8 zYUthN)2}*HLo^Qa31%T|pFKJDa*8DkBpJrjx6fiBr!oD-mJaMVbP`8SH=!*O)8k-K z6yRhwxhmkpq%l>PHL;dm=FTCBv~cn$+<#3I*6eLXd1*iwvM0X+cXFnt$sDE=O!aaf z=}kZMlWJ@4z6eRx%W|D_`b8?hvwZc+S zpCDt|EmQFJdq?o2|Ji{*S^NjMYe6GKq4)OJyvDKm|Bh$^>$V=i!_U5shnLL3P1iIG zN~|J}6Sq#S#_F9-aFhko8r+@c;h@13y$i|CCB!cOd#2Z5_mR_hcKuHL+v7_yrfQ&s z!hoL<^vzpl<14c#;;|Qh4w;#nC37bYO14FlYw)w3=b&j+?_TtjeHakTwSX&c*SM1y zK|EY+wqmD&nDk6u&e$GWHP$NekUVq#q-#?_Q%eeAgEVpJDN2+AqF zZqcJz=di#;@UDiI_95y193z)&u%yX&aDH~NZ-_ay@BHLf*nTPjcVGlY zl)KVj7=h2{Lz3Cx%S^M6oDE{`Rkc}5Co$uzF$L%}VZ0BgCmD=jbr?huj9jCu(bYk- z$MHlGUn+NEQtiMtQ&Cksw(1vX9AAe^P|y??yV!KYa@s`pnqb4Fw!sy@I$|<&aOsGp zlVoJp)#X3IY{)QGKW`i989uuPWm!gTsVl2R6VLtkHcT2_iH8)$zmn`SlWtsx%!j<0ZI&*cP)i@fMMUN{`V z{Q6>y9k4KOKxG=b>g_{txc$1uUXcj#r)r9CCWsF1YzKzv1Sg3avr&OBv2^NMVps^+ zBng)~BFx#TOdG{Mk3V*%8Bcya9eOb$?w&gqzkB&0{60@-Z<%YagQW1pA76v)_JB}) z|3A0k&}9`BRi4ZOlP>S;SC~vhYHBxw!+aa8XmQvmZyOnvnRF<`i|Oavk~kj>V^l?P zuZK3Zg&FyT#mJw(zj)?YT)+Diww-E6MQO2NYIp}2BA)->efXQ(rm+a4_whK6pKZcF zuHS=qPQ+1BS)Eqg-YO*|u4%;7VmpWV8tg5JOUY=QU53S-mm!m%SI2@$VE3_$eG=T< z9)(@HQoH%(yz;(TxaavTxY!X!!0*#F(B<~x?ISHL`S=wUG*n>bxC)Fc^TEZOUQAYS zt~rEVM=#->qd~+3FVox+hH2pFUJ%yTM9{dZi1|yjBM^~13@$Zk!!#97j6DNZT$^*rG4F*a}%aN3m*zi#ZukUN-U2VO_ zz>+;ERD|Skqo||?r8XP7r|(@M7;Wv?SJWAa{U-5{f$0RlarfQYHGjV&n(oqef`?T; zuLrw6JBNLroX7O>H9d}XyBr9|df(W?o!M*47UIdZd$8&7Ww=>Z=W#n>w>wc<#;uWI zR}B+F^jnI3Svt}bAh0!+ZayEp8YCMu4<Yb z^Zj_`yFCf6VwxIBq|nOJ-#{1McB@? z_~p$9@xTpJt~idLe6iPw-G|R$@vOe5?y)9^p(zNIRpJM4e2A-R zOEF`@$SXeb)oUkV-Ijy>5}Y249bcy3x=!3ZY~wYChhE%_^I^(twv>6Xr(Bx33$HV< zhG2qT+eU`7V}Q3r&u_B+@L4!j^%5% zVaJIWsz=lq@oyi;F$-pTn#^I5iO~AoN|0Iq?(_Q4-l5`w=QrcWk1XiaWNy1x{Mlms z)e9R?S5<r1?LllkbPmgIn}La=t1##4(Rgv$QY`=JFR^L& zQ9OG4bxflNF6?}K@*%E@U=8}t@TR=&B^5#ai*Y!ea2MC0BE3?G(q2~X^ffmzx*39Ie#>4zA1el>n%HHx(IB$V zt|eMVoZIDw+wC??N%~Uf6=fgOTxPm^9y_FsH^$}{jhbI<=di}f32M}6!3^=7b#&X* zLNc2L2dAL}L0_h*D$s=7H-7g9O9)nZ+Nq|}yMG3=S)(7AUWUm)(Az~!(qW{*DIrQF zRVIRD&-)#0<%&ET-c20QIBC`sPcu;=@p<#Z7~p-GDA#dZ!$2zH<&p-^Xn z5?;QtVg~a-4HZs!V&?A6$iNbU!!(j`QfG{GD_Q0zc%nffiFQZAiqS10_^9@wGKDVG zd-Qp4BJ_Kj+W)UJ75vov@h$stP`;fw>pg&9B)EK=7i_@%07*qoM6N<$g7R!M9smFU literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-400.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..be75f303aecdff6377b6282a08281b148c1033bf GIT binary patch literal 9159 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-16.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-16.png new file mode 100644 index 0000000000000000000000000000000000000000..c21a652d7d9ccc4ee270f9792ff902ee213b3a01 GIT binary patch literal 580 zcmV-K0=xZ*P)pG_DMuRRCt`Nlg(=rK^TXBvomWpo7L1-jV%QHf@mpb_A1@l-5a4E|!g8v$q{j}N ziG2^mA_D*o4%2ord;epyG1e??P!Hj8$?Fu$TdA0A_9k zM0#tbYh^h!!2?3{%)@up>_`S~hl3d!rw(P2v{Bm%z$HOm#t1rY_1RAIPYxI*0gqxF zvm7RMaC zsei|->Q}t~;-c$u*yMMFLjZ@0e#aG9e7%9&v*WmX^&~Epwoz|(v6=ux;>TpHp9+X2 z?b}T8CvP`1-?n?WaBMG5Ozek}8lT!6RLh9-$WNCT>3|wqWvwih*L^J4JZRm7f`NUx zBvR!o8H&H85CuLl*@ljI!AgYbUyqSMLd6_f%9cVQ{R(T3=6A-M#6Q%of8$S0zT)S1 Sg0`gq0000pIJxN4CRCt`-l}%_=R}{zp_kGO!m>HiYCTX>?p?*X#2ti6KjTBp4 z6e@1SMMbLH>Ov4)x^Uq}UAPcb+$iqE3QFllq0}m&RMCDc)JcLdPBNH|wWakc<}WVnk`f8Xhs)#-#b&dm#uihlk6?eRTaY9l;sy?NYms74X$*u-xGtIOBl zJbMdpd{fW#$jQ4E)9D(Cyl~EcTEaxq6q!sxQ($N;JChVZp=2Rw)W*LY$5SF1sSJO8@I=b5KXsgqv6vCB4A|mTNNpN`U z3herHB@{N7k0jyv>8}}_xH*M@>nK_hf{SK;0GF;HKoG__@Wpa$TU*BXvsu`dffe0L zC_)uGhF7A?)^O;@ad0k4N4U8GbSrKY3-p=-Lp>TI!O*j;gnGlny@!(+Ue{08!mwqq z4qOeu+oVUXU>p|29J$`eq$I z?lN)pZWSd%MNhc^O$or`7$V_bZh#_0OY#T_bnL(I0H=0ufT3`DiZOP6wkn&gwvU6C z9w3M%Y|57kmLCu$N=p$Dx2Srmq_+3`pV+p337o&?_e2q-RrY>7D80D6VER`jl+<;g#16{Etm`1%) zW-X&^sYsiWJ?Fvem5~f&BvYN-fJVXgyCYGdp0G;BVaFi<8%$>uftXBnas#H0eicpu h!}D6sIo|!B{wvo=a6w{#!i4|;002ovPDHLkV1j>GrfvWL literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000000000000000000000000000000000..cb2f2d5ef7bbef29d72ce2a6040896d717981cc3 GIT binary patch literal 1193 zcmV;a1XlZrP)pJTS-JgRCt`7Rb5ORRTTbaW@lz+c85hEP>NVAwvZNyt*J?^)%yEj z`d|~I*2KmqYvNmt8lQbJ602{<8g0_VXpIk=G^sUht)WpAQ9>~^6{tWFSOk{+nf;l$ z_j>N^vM#hstv8v>y>st5-}%0C?wJtQjJ;er4zYAfg#xj5|As?A(V`A#$>kHh zkJZ0gxfQBhw4P3F6Hera=Q9XB{GWWU4DJ(3wD!oRQ-6OnvA^N+bpWsb^w-NN6Ng>y zg85lMy(RyW1vJA#cZ>CDw14))cXn+!ww6K99d*&D8=rw<-KzHz22a9nY~Hyvo9v$0|P&dekPzc2{`-_Ifz38Tm!spC zlPdG+MjJRmHU7js#RN+bIo^7v8(TMw<7EE~KDclVPFTYu+nY$&6y`HzE!({Cs{?Sx z)7qdc5Q1ezk7AXS)G;0o6= zRRI)D%Mi`HqJ&JzLQw>2Z4(Jk;OpPh&Fh|*wB5ppH zHp26eHbVKT0A^h}C-TNHRZ<7{R-L=)Q1zfyk61IYRfhiny|pCFG!JG)00000NkvXX Hu0mjf8o4VH literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-256.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-256.png new file mode 100644 index 0000000000000000000000000000000000000000..d2d5a20115562d5df76a2ad246fd5d2cdd960ded GIT binary patch literal 15529 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 Q_89Ot$~5SI04B2j>;M1& literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-32.png b/GoAwayEdge.Helper.Package/Images/Square44x44Logo.targetsize-32.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd09990fde6091c8fcf81149cdf958fb876f0b0 GIT binary patch literal 1233 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/StoreLogo.backup.png b/GoAwayEdge.Helper.Package/Images/StoreLogo.backup.png new file mode 100644 index 0000000000000000000000000000000000000000..7385b56c0e4d3c6b0efe3324aa1194157d837826 GIT binary patch literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-100.png b/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..ea7aea176a5e47249c03158b461ea5663ae7609f GIT binary patch literal 2841 zcmV+!3+D8RP)pP%Sl8*RCt`tnt5y-)g8ybbL_p|UGLgn)=mOWLLdiD6cZ>;AqfeQ zAfcs|3W78QDo~4Bgj7*LltZBWQPLu{5oZw*LKLNiq(zDXC4t;hZ#h*004Q8xE|f+Ei}5TyDTky9XACPS0C{AVQQhKq`C6cO;C~ldG(r$~SM^Gtjzk zNo8xP(PgzV46K)B5$fO|T_)kX({l`Bq*Ji?d|(>Z)7Mp{#+C$W+BMiH*`2G@NEB?6 zAxxn)`P!1xdD|k=<4?{ z$E(FS|8?}RJdoeDoNctoj`^@2b;aoxC%qetX}fOTt%+LcPGRdlM8F=KLcEhB=!y;M!u6t$1* zIQn=Vh$~V1T&16_-{02vro~o~! zFZ)YtzeL8+^-JvNS>d{9sy6V*EHPc^c=0?U2~qxbsogwRXm>@69V-e#4iz;$hJ8OQ zlF>yB7du)ML@%)%}6rxpb$26b1{3^ZL?jVIn~!)JXl1iY?-mfte_lKZq=| z1k?4jAX%)VNjL`w*JHB^Zx8-!eRa=vvxp zm?ix9KvJ3`VG%Wju7)+2gI^t<>=TheY`kmsML`US({9Dawbx?ZUk~DBOhJXyHo`J| zP1;^c5>j&9Ac7G~La@6`o;cn;@(?wwjg+L6%xlZE- z$q2=5)2x|q1_1>tEI9pbFMOo?Gxx42t5{u?7r$S-0x$n_ANIC=jhp7rC^^19=*4uu z6&*1ZPV10*X531YI%Yx7pF@|A_@Q-oYTI+7U)(pYL zWKY{Etl!#-lTi!Y9xrVX0Vj?`VAJAw;M+mWtP7M{7H%qC3?r3OzEF3_P_#TL3j(v0 z7qX#HKq95$np!8WxuUx0DZ7rGzX8=S~OudK8@MiIfFV)Ql^zj1I`^ za4{CiUIlY5hIA^8`atm#O{@CvJ=Xph@ME{oRp+(HxP~Ey4lmr?>AlL z$Gfc&1pOI>VzD@Wy>dGI9%s?zy3a@O{FbAzy1bdpk=a}3@&+!-N9bh6vK)-eEmIjD zMuHNab5x1m**yS%h0}CwE)T7ogB{2BQgTdF*0#b<5oq`Evsie!2lHp}Y(E?<3|+&g zZJqeT2gh(W?Sju^Hyf#8JvfOm@vS8=A#6^VwJ`7QPWNeO`MMi7&YL!3Y=kNr4mu>E zKm}f0vjD%`)PkttgU97S%effVzH$(AFLR*2#s#;#KKT+KAM3^0h=!Cdnu(9UB-;H`TsoFq9YDzM!b_ii1FPMU z@exx5-W&0xIPvgnXnKr4r5fg7rVq%jN<6)}1zR7lhRd0$vuY{IB-1L+_C?Ikxx%}@ zM}NEk58tZdKW7HeaV~=XSlSH5SB5IkaCyM2emA_|OhH2$FcYQg;a8uK+;-u?7* zyt=Cs)xlcxG1;&PW_KvjMV&B6N-z?#Zs>w2OS$`&@7XH94?8>h@X*UU@#hDZQWUe} zwi{;SXvZ0BJ8&GU7tbv<^$7Xbfp$E*LdfYtvKYKO)HPKu-W`?&VOoM3D?3jd zuF>r-w@giS6?Sy=2NQE(*u@ueuHno3$jwYugUvPun}- z4qQf2Q7q8rnyaO#)0=qpYrvAA(mg3ca232;LyJ~d1#lu7!HWQEm|2S-HcTfU7}>KN`RX(_Zu<W3Ng6w;4S*r1w-AUvG!-6o3M>CM$ zR8lVR;b@9DgiJe8 zM#@`+A(g36E)57@mGVfz2cWq!77$64ZRY={CjZeWML}Ad!6?({k7a9#+B<4|a3#h2 rN>-v@|9^-eNuad{L?*snZtVX6;P~mb_6^LX00000NkvXXu0mjfslHzI literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-125.png b/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..07c8bfe085b3b625c5a591bace0279cd7b46d251 GIT binary patch literal 3652 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 bPd@xVcVQONkDICH00000NkvXXu0mjfDv$jk literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-200.png b/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..4321d0f894239e8f79737e519099c38585098430 GIT binary patch literal 6430 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 literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-400.png b/GoAwayEdge.Helper.Package/Images/StoreLogo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..31a892125a66c561f33147c5d6cc73de01b80d20 GIT binary patch literal 16283 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 YusV9?^l5JPs}2AoeRDm;9hc|-2Sw>fYybcN literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-400.png b/GoAwayEdge.Helper.Package/Images/Wide310x150Logo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..27ffbe80658f975f6c66d41b3f57f739e1ed8e14 GIT binary patch literal 21419 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 + + + + + + + GoAwayEdge Helper + Jonas Günner + Images\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GoAwayEdge.Helper/Common/Configuration.cs b/GoAwayEdge.Helper/Common/Configuration.cs new file mode 100644 index 0000000..1144d6d --- /dev/null +++ b/GoAwayEdge.Helper/Common/Configuration.cs @@ -0,0 +1,98 @@ +using GoAwayEdge.Helper.Common.Debugging; +using Microsoft.Win32; + +namespace GoAwayEdge.Helper.Common +{ + internal class Configuration + { + public static string? CopilotExternalApp { get; set; } + public static string? CopilotExternalAppArgument { get; set; } + + /// + /// Initialize the current environment. + /// + /// + /// Boolean status of the initialization. + /// + public static bool InitialEnvironment(bool setupRunning = false) + { + // Check if Edge is installed + try + { + Logging.Log("Initialize environment ..."); + Logging.Log("Fetching settings from registry ..."); + + try + { + CopilotExternalApp = RegistryConfig.GetKey("ExternalApp", userSetting: true); + CopilotExternalAppArgument = RegistryConfig.GetKey("ExternalAppArgs", userSetting: true); + } + catch (Exception ex) + { + Logging.Log("An error has occurred while reading the registry: " + ex.Message, Logging.LogLevel.ERROR); + } + Logging.Log($"Value of CopilotExternalApp: {CopilotExternalApp}"); + Logging.Log($"Value of CopilotExternalAppArgument: {CopilotExternalAppArgument}"); + return true; + } + catch (Exception ex) + { + Logging.Log($"Error while initializing environment: {ex.Message}", Logging.LogLevel.ERROR); + return false; + } + } + } + + public class RegistryConfig + { + private const string Company = "valnoxy"; + private const string Product = "GoAwayEdge"; + private const string RegistryPath = @$"SOFTWARE\{Company}\{Product}"; + public const string UninstallGuid = "{DC021E0D-1809-4102-8888-506D3121F1E9}"; + private const string UninstallRegistryPath = @$"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{UninstallGuid}"; + + /// + /// Retrieves the value of a key from the Registry. + /// + /// Name of the key. + /// Use the Uninstall Registry key instead. + /// Use the CurrentUser Registry key instead. + /// The value of the key if it exists, otherwise null. + public static string GetKey(string option, bool isUninstall = false, bool userSetting = false) + { + try + { + RegistryKey? key; + if (userSetting) + { + key = Registry.CurrentUser.OpenSubKey(RegistryPath); + } + else if (isUninstall) + { + key = Registry.LocalMachine.OpenSubKey(UninstallRegistryPath); + } + else + { + key = Registry.LocalMachine.OpenSubKey(RegistryPath); + } + if (key != null) + { + var value = key.GetValue(option); + if (value != null) + { + return value.ToString()!; + } + Logging.Log($"Value for key '{option}' not found in the registry.", Logging.LogLevel.ERROR); + return ""; + } + } + catch (Exception ex) + { + Logging.Log($"An error has occurred while reading the registry: {ex.Message}", Logging.LogLevel.ERROR); + return ""; + } + Logging.Log($"Registry key '{RegistryPath}' not found.", Logging.LogLevel.ERROR); + return ""; + } + } +} diff --git a/GoAwayEdge.Helper/Common/Debugging/Logging.cs b/GoAwayEdge.Helper/Common/Debugging/Logging.cs new file mode 100644 index 0000000..ee0352e --- /dev/null +++ b/GoAwayEdge.Helper/Common/Debugging/Logging.cs @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Exploitox Team + * + * Module Name: + * Logging.cs + * + * Description: + * This class is responsible for initializing the logging system. + * + * Author: + * Jonas Günner (valnoxy) 20-Sep-2021 + * + * Notes: + * Backported from: https://git.heydu.net/valnoxy/xorieos/-/blob/main/srv03rtm/base/ntsetup/winnt32/modernsetup/common/logging.cs + */ + +using System.Diagnostics; +using System.Reflection; + +namespace GoAwayEdge.Helper.Common.Debugging +{ + internal class Logging + { + private static readonly string LogPath = Path.Combine(Path.GetTempPath(), "GoAwayEdge", "Logs"); + private static string? _logFile; + + internal enum LogLevel { INFO, ERROR, WARNING } + + public static void Initialize() + { + // Ensure the log directory exists + if (!Directory.Exists(LogPath)) + { + Directory.CreateDirectory(LogPath); + } + + // Fetching the current log file + _logFile = Path.Combine(LogPath, $"helper_log_{DateTime.Now:yyyy-MM-dd}.txt"); + if (!File.Exists(_logFile)) + { + var version = Assembly.GetExecutingAssembly().GetName().Version!; + Log($"GoAwayEdge Helper {version.Major}.{version.Minor}.{version.Build} (Build {version.Revision})"); + Log("Logging system initialized"); + } + + // Delete old log files + DeleteOldLogFiles(); + } + + public static void Log(string message, LogLevel level = LogLevel.INFO) + { + if (string.IsNullOrEmpty(_logFile)) + throw new Exception("Logging class not initialized!"); + + // Get calling method information + var stackTrace = new StackTrace(); + var callingMethod = stackTrace.GetFrame(1)?.GetMethod(); + var callingClass = callingMethod?.DeclaringType?.FullName ?? "UnknownClass"; + var methodName = callingMethod?.Name ?? "UnknownMethod"; + + // Construct the log message with calling class and method + var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {level} - {callingClass}.{methodName} - {message}"; + + using (var fileStream = new FileStream(_logFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) + using (var writer = new StreamWriter(fileStream)) + { + writer.WriteLine(logMessage); + } + + // Output log message to Debug console + System.Diagnostics.Debug.WriteLine(logMessage); + } + + private static void DeleteOldLogFiles() + { + var logFiles = Directory.GetFiles(LogPath, "log_*.txt"); + foreach (var logFile in logFiles) + { + var creationTime = File.GetCreationTime(logFile); + if (creationTime < DateTime.Now.AddDays(-7)) + { + File.Delete(logFile); + Log("Deleted old log file: " + logFile); + } + } + } + } +} \ No newline at end of file diff --git a/GoAwayEdge.Helper/GoAwayEdge.Helper.csproj b/GoAwayEdge.Helper/GoAwayEdge.Helper.csproj new file mode 100644 index 0000000..bbe8d2e --- /dev/null +++ b/GoAwayEdge.Helper/GoAwayEdge.Helper.csproj @@ -0,0 +1,19 @@ + + + Exe + net8.0-windows10.0.18362.0 + enable + enable + false + true + GoAwayEdge Helper + GoAwayEdge + Exploitox + valnoxy + 1.0.0.0 + https://github.com/valnoxy/GoAwayEdge + https://github.com/valnoxy/GoAwayEdge + ARM64;x64;x86 + win-x86;win-x64;win-arm64 + + \ No newline at end of file diff --git a/GoAwayEdge.Helper/Program.cs b/GoAwayEdge.Helper/Program.cs new file mode 100644 index 0000000..85c538a --- /dev/null +++ b/GoAwayEdge.Helper/Program.cs @@ -0,0 +1,31 @@ +namespace GoAwayEdge.Helper +{ + internal class Program + { + static void Main(string[] args) + { + Console.WriteLine("GoAwayEdge Helper"); + Console.WriteLine("Helper Application for intercepting the Copilot Key"); + Console.WriteLine(); + Common.Debugging.Logging.Initialize(); + var resultEnvironment = Common.Configuration.InitialEnvironment(); + if (!resultEnvironment) + return; + + var quotedArgs = args.Select(arg => arg.Contains(" ") ? $"\"{arg}\"" : arg); + var argumentJoin = string.Join(" ", quotedArgs); + Console.WriteLine("[i] Args: " + argumentJoin); + Console.WriteLine("[i] Opening defined external application ..."); + var p = new System.Diagnostics.Process(); + var startInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = "cmd.exe", + Arguments = $"/c \"{Common.Configuration.CopilotExternalApp}\" {Common.Configuration.CopilotExternalAppArgument}", + WorkingDirectory = Path.GetDirectoryName(Common.Configuration.CopilotExternalApp) + }; + p.StartInfo = startInfo; + p.Start(); + Console.ReadKey(); + } + } +} diff --git a/GoAwayEdge.sln b/GoAwayEdge.sln index 31316e2..ba8f399 100644 --- a/GoAwayEdge.sln +++ b/GoAwayEdge.sln @@ -1,20 +1,65 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33020.496 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GoAwayEdge", "GoAwayEdge\GoAwayEdge.csproj", "{95F3960E-372B-45F3-85D8-CD06F4D8B271}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoAwayEdge.Helper", "GoAwayEdge.Helper\GoAwayEdge.Helper.csproj", "{A1CB967D-9105-47AF-BBB1-F2BA694014F1}" +EndProject +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "GoAwayEdge.Helper.Package", "GoAwayEdge.Helper.Package\GoAwayEdge.Helper.Package.wapproj", "{6B1C2331-6097-4559-9D50-62D3E906E2E6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|Any CPU.Build.0 = Release|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|ARM64.Build.0 = Debug|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|x64.ActiveCfg = Debug|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|x64.Build.0 = Debug|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|x86.ActiveCfg = Debug|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Debug|x86.Build.0 = Debug|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|ARM64.ActiveCfg = Release|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|ARM64.Build.0 = Release|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|x64.ActiveCfg = Release|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|x64.Build.0 = Release|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|x86.ActiveCfg = Release|Any CPU + {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|x86.Build.0 = Release|Any CPU + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|ARM64.Build.0 = Debug|Any CPU + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x64.ActiveCfg = Debug|x64 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x64.Build.0 = Debug|x64 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x86.ActiveCfg = Debug|x86 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x86.Build.0 = Debug|x86 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|ARM64.ActiveCfg = Release|Any CPU + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|ARM64.Build.0 = Release|Any CPU + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x64.ActiveCfg = Release|x64 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x64.Build.0 = Release|x64 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x86.ActiveCfg = Release|x86 + {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x86.Build.0 = Release|x86 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|ARM64.Build.0 = Debug|ARM64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x64.ActiveCfg = Debug|x64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x64.Build.0 = Debug|x64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x64.Deploy.0 = Debug|x64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x86.ActiveCfg = Debug|x86 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x86.Build.0 = Debug|x86 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x86.Deploy.0 = Debug|x86 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|ARM64.ActiveCfg = Release|ARM64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|ARM64.Build.0 = Release|ARM64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|ARM64.Deploy.0 = Release|ARM64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x64.ActiveCfg = Release|x64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x64.Build.0 = Release|x64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x64.Deploy.0 = Release|x64 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x86.ActiveCfg = Release|x86 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x86.Build.0 = Release|x86 + {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 8a9ac5b..0000000 --- a/TODO.md +++ /dev/null @@ -1,83 +0,0 @@ -
- - -
-
- GoAwayEdge Banner - -
- - [![Version][version-shield]][version-url] - [![Download Counter][downloads-shield]][downloads-url] - [![License][license-shield]][license-url] - [![Weblate][weblate-shield]][weblate-url] -
- -[version-shield]: https://img.shields.io/github/v/release/valnoxy/GoAwayEdge?color=9565F6 -[version-url]: https://github.com/valnoxy/GoAwayEdge/releases - -[weblate-shield]: http://translate.valnoxy.dev/widget/goawayedge/svg-badge.svg -[weblate-url]: https://translate.valnoxy.dev/engage/goawayedge/ - -[downloads-shield]: https://img.shields.io/github/downloads/valnoxy/GoAwayEdge/total.svg?color=431D93 -[downloads-url]: https://github.com/valnoxy/GoAwayEdge/releases - -[license-shield]: https://img.shields.io/github/license/valnoxy/GoAwayEdge?color=9565F6 -[license-url]: https://img.shields.io/github/license/valnoxy/GoAwayEdge - -
-

GoAwayEdge

-

-

Don't like Microsoft Edge? Me neither. Redirect all Edge calls to your favorite browser!

- Download now - · - Report Bug - · - Discussions - · - Help me translate -
-
-

-
- ---- - -# TODO list for Version 2.0 - -## Features -- [ ] Settings Menu -- [ ] Change functionality of Copilot key / taskbar icon -- [ ] Change Weather service -- [ ] Silent App Updater - -## Quality of Life -- [ ] Redesigned parsing engine -- [ ] Redesigned logging system - -# Development Notes - -### Search Bar Arguments (search term: "hallo") -``` -"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument microsoft-edge:?url=https%3A%2F%2Fwww.bing.com%2Fsearch%3Fq%3Dhallo%26form%3DWSBEDG%26qs%3DAS%26cvid%3D12fe0e3529de48c0815fa6882e348e59%26pq%3DHallo%26cc%3DDE%26setlang%3Dde-DE%26nclid%3DF1C9E841B291A09001E0E245264AC67E%26ts%3D1722019735480%26nclidts%3D1722019735%26tsms%3D480%26wsso%3DModerate×tamp=1722019735480&source=WindowsSearchBox&campaign=addedgeprot&medium=AutoSuggest -``` - -### Copilot PWA Arguments -``` -"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --app-id=khiogjgiicnghciboipemonlmgelhblf --app-fallback-url=https://copilot.microsoft.com/?dpwa=1 --display-mode=standalone --windows-store-app --ip-proc-id=41940 --ip-binding --mojo-named-platform-channel-pipe=41940.41536.15380779445885585744 --ip-aumid=Microsoft.Copilot_8wekyb3d8bbwe!App -``` - -### Copilot Taskbar (with Size) -``` -"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument microsoft-edge:///?ux=copilot&tcp=1&source=taskbar&invocationx=1888&invocationy=1056 -``` - -### Copilot Hotkey (WIN+C & Copilot Key) -``` -"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument microsoft-edge:///?ux=copilot&tcp=1&source=hotkey -``` - -### PDF file -``` -"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument "C:\Users\jonas\Downloads\test.pdf" -``` \ No newline at end of file From e6f620088e075257d00524f1795d18ff23d4c33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 21:07:34 +0100 Subject: [PATCH 50/80] Finalized new menu page --- .../GoAwayEdge.Helper.Package.assets.cache | Bin 0 -> 582 bytes .../GoAwayEdge.Helper.Package.wapproj.user | 18 ++++++ GoAwayEdge.sln | 12 ---- GoAwayEdge/App.xaml.cs | 12 ++-- GoAwayEdge/Common/Debugging/Logging.cs | 10 ++- GoAwayEdge/Common/Installation/Removal.cs | 20 +++++- GoAwayEdge/Common/Installation/Updater.cs | 57 ++++++++++++------ GoAwayEdge/Common/Localization.cs | 22 ++++++- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 2 +- GoAwayEdge/Common/Runtime/Weather.cs | 12 ++-- GoAwayEdge/GoAwayEdge.csproj | 2 +- .../ResourceDictionary.de-DE.xaml | 4 ++ .../Localization/ResourceDictionary.xaml | 4 ++ .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../CopilotDock/InterfaceManager.cs | 4 +- .../Setup/Pages/RedirectOrRemove.xaml.cs | 27 ++++++--- .../Setup/Pages/Settings.xaml.cs | 6 ++ 17 files changed, 147 insertions(+), 67 deletions(-) create mode 100644 GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.assets.cache create mode 100644 GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj.user diff --git a/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.assets.cache b/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.assets.cache new file mode 100644 index 0000000000000000000000000000000000000000..ac9ed90602234fb882f8317c938d8ceeb96d12e4 GIT binary patch literal 582 zcmWIWc6a1qU|=}%n)9!fU$N}|zPYuzmb;glnLjt}(NsK^61OP~h zf^TMWQGRiLT8UnGW?o8ud9hxwi?^OrX=YAJNPd1!F~|&%LIXky^$iX54D^i53=ItQ z49!i9SV2000Hm1-h?#+y1&Bf7Y(UHo#2i4(3B(|Id1tGb(Bjmh;+U-byu{)dy}Z)& z)RLHj#N_P6^wi=Qpb`dmpqhZ9{Pd#4Tm`qxoYZ0kRU?ZE3o}(C%NV%(6v8r#OA~Vx zf=fzMGV^1CGZKqZQ)2u|-BU{fpoW3W!Ued15-fg+xv2z$hCK}E+RXesel(v8dlq}< z7UX0mXO`qtx}>IM=B1{vx+Ufmr*Z_P7U$=brKYfi6qTm31SFPZlwf#C1Lz@5lDrd> Z3y;KdXe1V=Wa}k?BC!M%i7{v{1OOvKp7a0! literal 0 HcmV?d00001 diff --git a/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj.user b/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj.user new file mode 100644 index 0000000..b3cb3d6 --- /dev/null +++ b/GoAwayEdge.Helper.Package/GoAwayEdge.Helper.Package.wapproj.user @@ -0,0 +1,18 @@ + + + + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + C:\Users\jonas\Pictures\GoAwayEdge.png + SideloadOnly + False + x64|arm64 + False + + \ No newline at end of file diff --git a/GoAwayEdge.sln b/GoAwayEdge.sln index ba8f399..6beb6e7 100644 --- a/GoAwayEdge.sln +++ b/GoAwayEdge.sln @@ -31,34 +31,22 @@ Global {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|x86.ActiveCfg = Release|Any CPU {95F3960E-372B-45F3-85D8-CD06F4D8B271}.Release|x86.Build.0 = Release|Any CPU {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|ARM64.Build.0 = Debug|Any CPU {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x64.ActiveCfg = Debug|x64 - {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x64.Build.0 = Debug|x64 {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x86.ActiveCfg = Debug|x86 - {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Debug|x86.Build.0 = Debug|x86 {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|ARM64.ActiveCfg = Release|Any CPU - {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|ARM64.Build.0 = Release|Any CPU {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x64.ActiveCfg = Release|x64 - {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x64.Build.0 = Release|x64 {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x86.ActiveCfg = Release|x86 - {A1CB967D-9105-47AF-BBB1-F2BA694014F1}.Release|x86.Build.0 = Release|x86 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|ARM64.Build.0 = Debug|ARM64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|ARM64.Deploy.0 = Debug|ARM64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x64.ActiveCfg = Debug|x64 - {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x64.Build.0 = Debug|x64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x64.Deploy.0 = Debug|x64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x86.ActiveCfg = Debug|x86 - {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x86.Build.0 = Debug|x86 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Debug|x86.Deploy.0 = Debug|x86 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|ARM64.ActiveCfg = Release|ARM64 - {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|ARM64.Build.0 = Release|ARM64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|ARM64.Deploy.0 = Release|ARM64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x64.ActiveCfg = Release|x64 - {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x64.Build.0 = Release|x64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x64.Deploy.0 = Release|x64 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x86.ActiveCfg = Release|x86 - {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x86.Build.0 = Release|x86 {6B1C2331-6097-4559-9D50-62D3E906E2E6}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index bbe450e..9f9355c 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -50,7 +50,7 @@ public void Application_Startup(object sender, StartupEventArgs e) IsDebug = true; if (IsAdministrator() == false) { - ElevateAsAdmin(); + ElevateAsAdmin(); Environment.Exit(0); return; } @@ -70,7 +70,7 @@ public void Application_Startup(object sender, StartupEventArgs e) { if (IsAdministrator() == false) { - ElevateAsAdmin(string.Join(" ", args)); + ElevateAsAdmin(string.Join(" ", args)); Environment.Exit(0); return; } @@ -124,7 +124,7 @@ public void Application_Startup(object sender, StartupEventArgs e) if (IsAdministrator() == false) { - ElevateAsAdmin(string.Join(" ", args)); + ElevateAsAdmin(string.Join(" ", args)); Environment.Exit(0); return; } @@ -191,7 +191,7 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") - ElevateAsAdmin("--update"); + ElevateAsAdmin("--update"); Environment.Exit(0); } @@ -207,7 +207,7 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") - ElevateAsAdmin("--update"); + ElevateAsAdmin("--update"); Environment.Exit(0); } @@ -226,7 +226,7 @@ public void Application_Startup(object sender, StartupEventArgs e) Environment.Exit(0); } - private void ElevateAsAdmin(string arguments = null) + private static void ElevateAsAdmin(string? arguments = null) { // Restart program and run as admin var exeName = Process.GetCurrentProcess().MainModule?.FileName; diff --git a/GoAwayEdge/Common/Debugging/Logging.cs b/GoAwayEdge/Common/Debugging/Logging.cs index d4b7c83..b58f51b 100644 --- a/GoAwayEdge/Common/Debugging/Logging.cs +++ b/GoAwayEdge/Common/Debugging/Logging.cs @@ -37,12 +37,10 @@ public static void Initialize() // Fetching the current log file _logFile = Path.Combine(LogPath, $"log_{DateTime.Now:yyyy-MM-dd}.txt"); - if (!File.Exists(_logFile)) - { - var version = Assembly.GetExecutingAssembly().GetName().Version!; - Log($"GoAwayEdge {version.Major}.{version.Minor}.{version.Build} (Build {version.Revision})"); - Log("Logging system initialized"); - } + + var version = Assembly.GetExecutingAssembly().GetName().Version!; + Log($"GoAwayEdge {version.Major}.{version.Minor}.{version.Build} (Build {version.Revision})"); + Log("Logging system initialized"); // Delete old log files DeleteOldLogFiles(); diff --git a/GoAwayEdge/Common/Installation/Removal.cs b/GoAwayEdge/Common/Installation/Removal.cs index b778fbb..f728b61 100644 --- a/GoAwayEdge/Common/Installation/Removal.cs +++ b/GoAwayEdge/Common/Installation/Removal.cs @@ -139,6 +139,8 @@ public static bool RemoveMsEdge() } var edgeUpdateDevKey = Registry.LocalMachine.CreateSubKey($@"SOFTWARE{node}\Microsoft\EdgeUpdateDev"); edgeUpdateDevKey.SetValue("AllowUninstall", 1, RegistryValueKind.DWord); + var edgeUpdateKey = Registry.LocalMachine.CreateSubKey($@"SOFTWARE{node}\Microsoft\EdgeUpdate"); + edgeUpdateKey.SetValue("AllowUninstall", 1, RegistryValueKind.DWord); } } } @@ -233,19 +235,28 @@ public static bool RemoveMsEdge() timeoutStopwatch.Stop(); if (timeoutStopwatch.Elapsed.TotalSeconds >= 60) + { + Logging.Log("Removal of Edge Updater failed: Timeout after 60 seconds."); return false; // Timeout + } + if (proc.ExitCode != 0 && proc.ExitCode != 19) + { + Logging.Log($"Removal of Edge Updater failed: Unknown error has occurred (exited with error code {proc.ExitCode})"); return false; // Unknown error? + } } using (var proc = new Process()) // Remove Edge via setup file { + const string removalArgs = "--uninstall --msedge --system-level --verbose-logging --force-uninstall"; var psi = new ProcessStartInfo { FileName = edgeSetupPath, - Arguments = "--uninstall --msedge --system-level --verbose-logging --force-uninstall", + Arguments = removalArgs, RedirectStandardOutput = true }; + Logging.Log($"Executing \"{edgeSetupPath}\" {removalArgs}"); proc.StartInfo = psi; proc.Start(); proc.WaitForExit(); @@ -259,9 +270,16 @@ public static bool RemoveMsEdge() timeoutStopwatch.Stop(); if (timeoutStopwatch.Elapsed.TotalSeconds >= 60) + { + Logging.Log("Removal of Edge failed: Timeout after 60 seconds."); return false; // Timeout + } + if (proc.ExitCode != 0 && proc.ExitCode != 19) + { + Logging.Log($"Removal of Edge via Setup file failed: Unknown error has occurred (exited with error code {proc.ExitCode})"); return false; // Unknown error? + } } } } diff --git a/GoAwayEdge/Common/Installation/Updater.cs b/GoAwayEdge/Common/Installation/Updater.cs index 3fc89f5..d57f734 100644 --- a/GoAwayEdge/Common/Installation/Updater.cs +++ b/GoAwayEdge/Common/Installation/Updater.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.IO; using System.Net; +using System.Net.Http; using System.Reflection; using System.Security.Cryptography; using Microsoft.Toolkit.Uwp.Notifications; @@ -13,14 +14,14 @@ internal class Updater { public class GitHubRelease { - public string tag_name { get; set; } - public List assets { get; set; } + public string? tag_name { get; set; } + public List? assets { get; set; } } public class GitHubAsset { - public string browser_download_url { get; set; } - public string name { get; set; } + public string? browser_download_url { get; set; } + public string? name { get; set; } } @@ -143,15 +144,18 @@ public static void ModifyIfeoBinary(ModifyAction action) var appVersion = Assembly.GetExecutingAssembly().GetName().Version!; var currentVersion = new Version(appVersion.Major, appVersion.Minor, appVersion.Build); - using var client = new WebClient(); - client.Headers.Add("User-Agent", $"GoAwayEdge/{currentVersion} valnoxy.dev"); - var json = client.DownloadString(url); + using var client = new HttpClient(); + client.DefaultRequestHeaders.UserAgent.ParseAdd($"GoAwayEdge/{currentVersion} valnoxy.dev"); + + var response = client.GetAsync(url).Result; + response.EnsureSuccessStatusCode(); + var json = response.Content.ReadAsStringAsync().Result; var releases = JsonConvert.DeserializeObject(json); if (releases is { Length: > 0 }) { var tagName = Convert.ToString(releases[0].tag_name); - var tagVersion = tagName[1..]; + var tagVersion = tagName![1..]; var latestVersion = new Version(tagVersion); if (currentVersion < latestVersion) @@ -165,7 +169,7 @@ public static void ModifyIfeoBinary(ModifyAction action) return null; } } - + /// /// Download and run the new version of GoAwayEdge. /// @@ -178,29 +182,42 @@ public static bool UpdateClient() var appVersion = Assembly.GetExecutingAssembly().GetName().Version!; var currentVersion = new Version(appVersion.Major, appVersion.Minor, appVersion.Build); - using var client = new WebClient(); - client.Headers.Add("User-Agent", $"GoAwayEdge/{currentVersion} valnoxy.dev"); - var json = client.DownloadString(url); + using var client = new HttpClient(); + client.DefaultRequestHeaders.UserAgent.ParseAdd($"GoAwayEdge/{currentVersion} valnoxy.dev"); + + var response = client.GetAsync(url).Result; + response.EnsureSuccessStatusCode(); + var json = response.Content.ReadAsStringAsync().Result; var releases = JsonConvert.DeserializeObject(json); if (releases is { Length: > 0 }) { var assetUrl = string.Empty; - foreach (var asset in releases[0].assets.Where(asset => asset.name == "GoAwayEdge.exe")) + foreach (var asset in releases[0].assets!.Where(asset => asset.name == "GoAwayEdge.exe")) { assetUrl = asset.browser_download_url; } - - var tempFolder = Path.GetTempPath(); + if (string.IsNullOrEmpty(assetUrl)) { return false; } - if (File.Exists(Path.Combine(tempFolder, "GoAwayEdge.exe"))) - File.Delete(Path.Combine(tempFolder, "GoAwayEdge.exe")); - client.DownloadFile(assetUrl, Path.Combine(tempFolder, "GoAwayEdge.exe")); - Process.Start(Path.Combine(tempFolder, "GoAwayEdge.exe")); + var tempFolder = Path.GetTempPath(); + var tempFilePath = Path.Combine(tempFolder, "GoAwayEdge.exe"); + + if (File.Exists(tempFilePath)) + { + File.Delete(tempFilePath); + } + + using (var downloadStream = client.GetStreamAsync(assetUrl).Result) + using (var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + downloadStream.CopyTo(fileStream); + } + + Process.Start(new ProcessStartInfo(tempFilePath) { UseShellExecute = true }); return true; } } @@ -208,9 +225,11 @@ public static bool UpdateClient() { return false; } + return false; } + private static string CalculateMd5(string filename) { using var md5 = MD5.Create(); diff --git a/GoAwayEdge/Common/Localization.cs b/GoAwayEdge/Common/Localization.cs index 38cfea4..81dbfc6 100644 --- a/GoAwayEdge/Common/Localization.cs +++ b/GoAwayEdge/Common/Localization.cs @@ -57,7 +57,16 @@ public static string LocalizeValue(string value) try { var localizedValue = (string)Application.Current.Resources[value]!; - return string.IsNullOrEmpty(localizedValue) ? value : localizedValue; + + if (string.IsNullOrEmpty(localizedValue)) + return value; + + if (localizedValue.Contains("\\n")) + { + return localizedValue.Replace("\\n", "\n"); + } + + return localizedValue; } catch (Exception ex) { @@ -70,11 +79,17 @@ public static string LocalizeValue(string value, params object[]? args) { var localizedValue = LocalizeValue(value); - if (args is not { Length: > 0 }) return localizedValue; - + if (args is not { Length: > 0 }) + return localizedValue; + try { localizedValue = string.Format(localizedValue, args); + + if (localizedValue.Contains("\\n")) + { + localizedValue = localizedValue.Replace("\\n", "\n"); + } } catch (FormatException ex) { @@ -84,5 +99,6 @@ public static string LocalizeValue(string value, params object[]? args) return localizedValue; } + } } \ No newline at end of file diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index 39f644d..d28b3a3 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -48,7 +48,7 @@ public static void Parse(string[] args) { var appId = match.Groups[1].Value; Logging.Log($"Opening PWA App with ID {appId}"); - if (appId == copilotAppId) + if (appId == copilotAppId && Common.Configuration.AiProvider != AiProvider.Default) { DebugMessage.DisplayDebugMessage("GoAwayEdge", $"Opening AI Provider '{Configuration.AiProvider}' (PWA) ..."); UserInterface.CopilotDock.InterfaceManager.ShowDock(); diff --git a/GoAwayEdge/Common/Runtime/Weather.cs b/GoAwayEdge/Common/Runtime/Weather.cs index b045b10..2e1e1fd 100644 --- a/GoAwayEdge/Common/Runtime/Weather.cs +++ b/GoAwayEdge/Common/Runtime/Weather.cs @@ -9,11 +9,11 @@ public class Weather { public class GeoData { - public string L { get; set; } // City - public string R { get; set; } // Region - public string C { get; set; } // Country - public string I { get; set; } // Short Country code - public string G { get; set; } // Country code (lowercase) + public string? L { get; set; } // City + public string? R { get; set; } // Region + public string? C { get; set; } // Country + public string? I { get; set; } // Short Country code + public string? G { get; set; } // Country code (lowercase) public double X { get; set; } // longitude public double Y { get; set; } // latitude } @@ -42,7 +42,7 @@ public class GeoData var placeholders = new Dictionary { { "country-code", language }, - { "short-country-code", locObject.I }, + { "short-country-code", locObject.I! }, { "latitude", lat }, { "longitude", lon } }; diff --git a/GoAwayEdge/GoAwayEdge.csproj b/GoAwayEdge/GoAwayEdge.csproj index b70bedb..9c60563 100644 --- a/GoAwayEdge/GoAwayEdge.csproj +++ b/GoAwayEdge/GoAwayEdge.csproj @@ -12,7 +12,7 @@ GoAwayEdge Exploitox valnoxy - 2.0.0.257 + 2.0.0.258 Copyright © 2018 - 2025 Exploitox. All rights reserved. https://github.com/valnoxy/GoAwayEdge https://github.com/valnoxy/GoAwayEdge diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 7f5c64b..46a2194 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -6,6 +6,8 @@ Ja Nein Standard + Warnung + Abbrechen Willkommen Das Installationsprogramm führt alle notwendigen Schritte durch, um GoAwayEdge auf Ihrem System zu installieren. Nach der Installation werden alle Edge-Aufrufe an Ihren Browser weitergeleitet. Bitte wählen Sie die gewünschte Option, um fortzufahren. @@ -35,6 +37,8 @@ Bitte geben Sie die Anfrage-URL der Suchmaschine ein. Microsoft Edge (Stabil) entfernen Entferne Microsoft Edge vollständig von Ihrem System. + Das Entfernen von Microsoft Edge kann zu schwerwiegenden Systemproblemen führen, da es tief in Windows integriert ist und für viele Funktionen, einschließlich Updates, Hilfedateien und einige Anwendungen, unerlässlich ist. Das Löschen kann zu Instabilität oder defekten Funktionen führen.\n\nFahren Sie nur fort, wenn Sie sich der Risiken bewusst sind und über eine zuverlässige Sicherung oder einen Wiederherstellungspunkt verfügen. + Microsoft Edge entfernen Installation läuft ... Bitte warten Sie, bis die Installation abgeschlossen ist. diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 8e5db0b..8250d6c 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -8,6 +8,8 @@ Yes No Default + Warning + Cancel Welcome @@ -43,6 +45,8 @@ Remove Microsoft Edge completely from the system. Install Control Panel Install the Control Panel to configure GoAwayEdge more easily. + Removing Microsoft Edge can cause serious system issues, as it’s deeply integrated into Windows and essential for many features, including updates, help files, and some apps. Deleting it could result in instability or broken functionality.\n\nOnly proceed if you fully understand the risks and have a reliable backup or restore point in place. + Remove Microsoft Edge Installation in progress ... diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index c610a64..95c27a5 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-08-13T17:39:30.3814052Z;True|2024-08-13T19:35:07.3638159+02:00;True|2024-08-13T01:10:27.4137217+02:00;True|2024-08-13T01:06:17.9215774+02:00;True|2024-08-13T00:56:54.4657665+02:00;True|2024-08-13T00:49:21.1156303+02:00;True|2024-08-13T00:45:56.3970427+02:00;True|2024-08-13T00:25:23.5481220+02:00;True|2024-08-12T22:11:19.4188626+02:00;True|2024-08-12T22:10:38.2923046+02:00;True|2024-08-12T22:08:45.6517147+02:00;True|2024-07-30T00:22:22.2984409+02:00;True|2024-07-30T00:18:17.4366719+02:00;True|2024-07-30T00:17:49.8084336+02:00;True|2024-07-22T18:41:59.8117684+02:00;True|2024-06-18T00:28:22.3138517+02:00;True|2024-06-18T00:16:46.9788815+02:00;True|2024-06-09T20:14:23.6305404+02:00;True|2024-06-09T19:02:49.2570274+02:00;True|2024-06-09T18:47:29.9573023+02:00;True|2024-06-09T18:46:39.8011527+02:00;False|2024-06-09T18:46:05.6633541+02:00;False|2024-06-09T18:45:59.2563619+02:00;True|2024-02-18T17:16:27.0408261+01:00;True|2024-02-18T17:15:41.3961034+01:00;True|2024-02-18T17:11:58.7761728+01:00;True|2024-02-18T17:08:57.9390623+01:00;True|2024-02-18T17:08:26.6377454+01:00;True|2024-02-18T17:07:45.2050537+01:00;True|2024-02-18T17:05:12.7495146+01:00;True|2024-02-18T17:02:32.4549017+01:00;True|2024-02-18T16:48:25.3074382+01:00;True|2023-10-19T00:00:28.0962969+02:00;True|2022-11-13T02:33:03.7406004+01:00;True|2022-11-13T02:19:07.9073988+01:00;True|2022-11-13T02:18:35.3043045+01:00;True|2022-11-12T20:05:07.6366825+01:00;False|2022-11-12T20:04:52.3576134+01:00;True|2022-11-12T19:36:12.8480978+01:00; + True|2024-12-25T16:22:09.8471194Z||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs index 123209a..c7dcb2f 100644 --- a/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs +++ b/GoAwayEdge/UserInterface/CopilotDock/InterfaceManager.cs @@ -48,7 +48,7 @@ public static void ShowDock() Logging.Log($"Message received: {message}"); if (message.Contains("BringToFront")) { - WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, mode); // Dummy data + WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager!, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, mode); // Dummy data } }; @@ -57,7 +57,7 @@ public static void ShowDock() Logging.Log($"Error occurred: {ex.Message}", Logging.LogLevel.ERROR); }; - WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager, + WindowManager.ShowCopilotDockAsync(Common.Configuration.ShellManager!, AppBarScreen.FromPrimaryScreen(), AppBarEdge.Right, 500, // temporary size diff --git a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs index f7195c1..3160bc6 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/RedirectOrRemove.xaml.cs @@ -1,4 +1,5 @@ using System.Windows; +using GoAwayEdge.Common; using GoAwayEdge.Common.Debugging; using Wpf.Ui; using Wpf.Ui.Controls; @@ -18,6 +19,8 @@ public RedirectOrRemove() private void InstallBtn_Click(object sender, RoutedEventArgs e) { + Configuration.UninstallEdge = false; + Installer.SettingPage = new Settings(); Installer.ContentWindow!.FrameWindow.Content = Installer.SettingPage; Installer.ContentWindow!.NextBtn.IsEnabled = true; } @@ -26,21 +29,27 @@ private async void UninstallBtn_Click(object sender, RoutedEventArgs e) { var contentDialogService = new ContentDialogService(); contentDialogService.SetDialogHost(Installer.ContentWindow!.RootContentDialogPresenter); + var warningTitle = LocalizationManager.LocalizeValue("Warning"); + var cancelBtn = LocalizationManager.LocalizeValue("Cancel"); + var removeBtn = LocalizationManager.LocalizeValue("SettingsUninstallEdgeBtn"); + var contentValue = LocalizationManager.LocalizeValue("SettingsUninstallEdgeWarningDescription"); + var result = await contentDialogService.ShowSimpleDialogAsync( new SimpleContentDialogCreateOptions { - Title = "Warning", - Content = "Removing Microsoft Edge can cause serious system issues, as it’s deeply integrated into Windows and essential for many features, including updates, help files, and some apps. Deleting it could result in instability or broken functionality.\n\nOnly proceed if you fully understand the risks and have a reliable backup or restore point in place.", - PrimaryButtonText = "Remove Microsoft Edge", - CloseButtonText = "Cancel" + Title = warningTitle, + Content = contentValue, + PrimaryButtonText = removeBtn, + CloseButtonText = cancelBtn } ); - - if (result == ContentDialogResult.Primary) - { - Logging.Log("User pressed 'Remove Microsoft Edge'"); - } + if (result != ContentDialogResult.Primary) return; + + Logging.Log("User pressed 'Remove Microsoft Edge'"); + Configuration.UninstallEdge = true; + Installer.SettingPage = new Settings(); + Installer.ContentWindow!.FrameWindow.Content = Installer.SettingPage; } } } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs index c6eb1dc..3c6628e 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Settings.xaml.cs @@ -86,6 +86,12 @@ public Settings() Configuration.Uninstall = false; Configuration.InstallControlPanel = true; ControlPanelSwitch.IsChecked = true; + + if (Configuration.UninstallEdge) + { + CopilotStackPanel.IsEnabled = false; + WeatherStackPanel.IsEnabled = false; + } } private void EnableNextBtnValidation() From 21303a5f29650c6849dced59fbe7244c1a030aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 21:24:56 +0100 Subject: [PATCH 51/80] Hide copilot key setting Will be re-enabled with version 2.1.0 --- GoAwayEdge/Localization/ResourceDictionary.xaml | 2 +- .../UserInterface/ControlPanel/Pages/CopilotSettings.xaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index 8250d6c..b71241c 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -80,7 +80,7 @@ Please enter the URL from the Weather Service. Copilot Key External Program - ??? + Run an external application when you press the Copilot key. Path to Application Select the application you want to run. Arguments diff --git a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml index 6f2b5e8..c8c56e1 100644 --- a/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml +++ b/GoAwayEdge/UserInterface/ControlPanel/Pages/CopilotSettings.xaml @@ -64,8 +64,8 @@ - - + + From ea36614b4982da4c9e0f043b5e1f66f838ba65a6 Mon Sep 17 00:00:00 2001 From: valnoxy Date: Wed, 25 Dec 2024 20:14:50 +0000 Subject: [PATCH 52/80] Translated using Weblate (German) Currently translated at 94.6% (88 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/de/ --- GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index 46a2194..dcd56fd 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -91,4 +91,10 @@ Benutzerdefinierter KI Anbieter Bitte gebe die URL des KI-Anbieters (oder einer Webseite) ein. Die Einstellungen konnten nicht übernommen werden: {0} + Copilot Key + Externe Anwendung + Pfad zur Anwendung + Wählen Sie die Anwendung, die Sie ausführen möchten. + Argumente + Definieren Sie die Argumente Ihrer Anwendung. From 117c732b2702bda5f61e33f98895f6b77beccefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 23:37:55 +0000 Subject: [PATCH 53/80] Translated using Weblate (Italian) Currently translated at 100.0% (93 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/it/ --- .../ResourceDictionary.it-IT.xaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml index 383cc59..9ca5234 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml @@ -77,4 +77,25 @@ Impossibile abilitare GoAwayEdge su questo sistema: {0} Impossibile disattivare GoAwayEdge su questo sistema: {0} Impossibile applicare le impostazioni: {0} + Volete reindirizzare tutte le chiamate da Edge a un altro browser o rimuovere completamente Edge? + La rimozione di Microsoft Edge può causare seri problemi al sistema, poiché è profondamente integrato in Windows ed è essenziale per molte funzioni, tra cui gli aggiornamenti, i file di guida e alcune app. L'eliminazione potrebbe causare instabilità o interruzioni di funzionalità.\n\nProcedere solo se si conoscono bene i rischi e se si dispone di un backup affidabile o di un punto di ripristino. + Avvertenze + Annullamento + Reindirizzare o rimuovere? + Reindirizzare tutto + Reindirizza tutte le chiamate da Edge al vostro browser preferito. + Rimuovere Microsoft Edge + Servizio meteo + Cambiate il servizio con il vostro sito meteo preferito. + Servizio meteo personalizzato + Inserire l'URL del servizio meteorologico. + Chiave del copilota + Programma esterno + Eseguire un'applicazione esterna quando si preme il tasto Copilot. + Percorso di applicazione + Selezionare l'applicazione che si desidera eseguire. + Argomenti + Definire gli argomenti dell'applicazione. + Nessuna sorgente selezionata + Predefinito From 1b9aeb1edd4e32b9475022fa5268d8b24df30627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 23:47:31 +0000 Subject: [PATCH 54/80] Translated using Weblate (Korean) Currently translated at 61.2% (57 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/ko/ --- .../ResourceDictionary.ko-KR.xaml | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml b/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml index e86f0bd..79af1a1 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml @@ -56,4 +56,46 @@ 생성 성공 Edge의 대체 시작 파일이 성공적으로 생성되었습니다. 이 버전 건너뛰기 + 제어판 설치 + 제어판을 설치하면 GoAwayEdge를 더 쉽게 구성할 수 있습니다. + 경고 + 취소 + 맞춤형 AI 제공업체 + AI 제공업체(또는 즐겨찾는 웹사이트)의 URL을 입력하세요. + 기상 서비스 + Microsoft Edge는 Windows에 깊이 통합되어 있고 업데이트, 도움말 파일 및 일부 앱을 비롯한 많은 기능에 필수적이므로 제거하면 심각한 시스템 문제가 발생할 수 있습니다. 삭제하면 시스템이 불안정해지거나 기능이 손상될 수 있습니다.\n\n위험을 완전히 이해하고 신뢰할 수 있는 백업 또는 복원 지점이 있는 경우에만 진행하세요. + Microsoft Edge 제거 + GoAwayEdge 제어판 + Microsoft Edge + Windows 코파일럿 + 검색 엔진 등을 관리합니다. + 단축키 등 관리하기. + GoAwayEdge 활성화/비활성화 + 다른 브라우저로 검색 쿼리 전달을 비활성화합니다. + GoAwayEdge 활성화 + GoAwayEdge 비활성화 + AI 제공업체 + 제공업체를 즐겨찾는 AI(또는 즐겨찾는 웹사이트)로 변경하세요. + 즐겨 찾는 날씨 웹사이트로 서비스를 변경합니다. + 사용자 지정 날씨 서비스 + 기상청의 URL을 입력하세요. + 부조종사 키 + 외부 프로그램 + GoAwayEdge에 오신 것을 환영합니다 + Copilot 키를 누르면 외부 애플리케이션을 실행합니다. + 신청 경로 + 실행하려는 애플리케이션을 선택합니다. + 인수 + 애플리케이션의 인수를 정의합니다. + 선택한 소스 없음 + 이 시스템에서 GoAwayEdge가 성공적으로 활성화되었습니다. + 이 시스템에서 GoAwayEdge가 성공적으로 비활성화되었습니다. + 이 시스템에서 GoAwayEdge를 활성화할 수 없습니다: {0} + 이 시스템에서 GoAwayEdge를 비활성화할 수 없습니다: {0} + 설정을 적용할 수 없습니다: {0} + 기본값 + 리디렉션 또는 제거? + Edge에서 다른 브라우저로 모든 호출을 리디렉션하거나 Edge를 완전히 제거하시겠습니까? + 모든 것을 리디렉션 + 모든 통화를 Edge에서 즐겨 사용하는 브라우저로 리디렉션하세요. From 6b8e2ea84d38be071e6c1648f7a84a9c3a67fadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 20:31:26 +0000 Subject: [PATCH 55/80] Translated using Weblate (Spanish) Currently translated at 100.0% (93 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/es/ --- .../ResourceDictionary.es-ES.xaml | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml index c4bf41c..8014003 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml @@ -33,14 +33,14 @@ Instalación en curso ... Espere a que finalice la instalación. - Instalación finalizada. + Instalación finalizada! Simplemente abre este Instalador, si quieres personalizar GoAwayEdge de nuevo. - Desinstalación completada. + Desinstalación completada! GoAwayEdge ha sido eliminado con éxito del sistema. Donar a través de PayPal Error de inicialización: {0} - Error de instalación: {0} + Instalación fallida: {0} Error de desinstalación: {0} Actualización fallida: {0} Error de instalación. Por favor, inténtelo de nuevo. @@ -56,4 +56,46 @@ Creación con éxito La versión no IEFO de Edge se ha creado correctamente. Saltar esta versión + Cambia el servicio a tu sitio web meteorológico favorito. + GoAwayEdge se ha desactivado correctamente en este sistema. + No se ha podido activar GoAwayEdge en este sistema: {0} + No se ha podido desactivar GoAwayEdge en este sistema: {0} + No se ha podido aplicar la configuración: {0} + Desactivar GoAwayEdge + Eliminar Microsoft Edge puede causar graves problemas en el sistema, ya que está profundamente integrado en Windows y es esencial para muchas funciones, como las actualizaciones, los archivos de ayuda y algunas aplicaciones. Si lo eliminas, podrías provocar inestabilidad o una funcionalidad dañada.\n\n Solo procede si conoces bien los riesgos y tienes una copia de seguridad fiable o un punto de restauración. + Advertencia + Cancelar + ¿Quieres redirigir todas las llamadas de Edge a otro navegador o eliminar Edge por completo? + Redirige todas las llamadas de Edge a tu navegador favorito. + Panel de control de GoAwayEdge + Llave Copiloto + Programa externo + Ejecuta una aplicación externa al pulsar la tecla Copilot. + Camino a la aplicación + Seleccione la aplicación que desea ejecutar. + Argumentos + Defina los argumentos de su aplicación. + Ninguna fuente seleccionada + Eliminar Microsoft Edge + GoAwayEdge se ha activado correctamente en este sistema. + Instalar el panel de control + Proveedor de AI + Cambia el proveedor a tu IA favorita (o a tu sitio web favorito). + Por defecto + ¿Redirigir o eliminar? + Redirigir todo + Instala el Panel de Control para configurar GoAwayEdge más fácilmente. + Microsoft Edge + Windows Copilot + Gestione los motores de búsqueda y mucho más. + Gestiona las teclas de acceso rápido y mucho más. + Activar/Desactivar GoAwayEdge + Desactivar el reenvío de consultas de búsqueda a otros navegadores. + Bienvenido a GoAwayEdge + Activar GoAwayEdge + Proveedor de IA personalizada + Introduzca la URL del proveedor de AI (o su sitio web favorito). + Servicio Meteorológico + Servicio Meteorológico Personalizado + Introduzca la URL del Servicio Meteorológico. From 9073e302ddbcc68b8b981628d3e5e5af5b3bee53 Mon Sep 17 00:00:00 2001 From: DeepL Date: Wed, 25 Dec 2024 23:51:18 +0000 Subject: [PATCH 56/80] Translated using Weblate (Dutch) Currently translated at 0.0% (0 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/nl/ --- .../ResourceDictionary.nl-NL.xaml | 100 +++++++++++++++++- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml b/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml index 8e1d2a0..cf6c97a 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml @@ -1,5 +1,95 @@ - - \ No newline at end of file + + GoAwayEdge-installateur + Volgende + Terug + Ga naar + Welkom bij GoAwayEdge + Microsoft Edge + Windows Copiloot + Beheer zoekmachines en meer. + Sneltoetsen beheren en meer. + GoAwayEdge inschakelen/uitschakelen + Het doorsturen van zoekopdrachten naar andere browsers uitschakelen. + GoAwayEdge inschakelen + Ja + Geen + Welkom + GoAwayEdge uitschakelen + Installatie mislukt: {0} + De optie voor het uitvoeren van afbeeldingsbestanden voor '{0}' is niet geregistreerd. Probeer het opnieuw. + AI-aanbieder + Het installatieprogramma voert alle noodzakelijke stappen uit om GoAwayEdge op je systeem te installeren. Na de installatie worden alle Edge-oproepen omgeleid naar je browser. Selecteer de gewenste optie om verder te gaan. + Installeer + Installeer en configureer GoAwayEdge op uw systeem. + verwijderen + Wijzig de provider naar je favoriete AI (of naar je favoriete website). + AI-aanbieder op maat + Voer de URL in van de AI-provider (of je favoriete website). + Verwijder GoAwayEdge en herstel de Edge-functionaliteit. + Gebruik het installatieprogramma om GoAwayEdge te verwijderen. + Licentie + Lees de volgende licentie. U moet de voorwaarden van de licentie accepteren voordat u doorgaat met de installatie. + Waarschuwing + Annuleren + Ik wijs deze licentie af. + Omleiden of verwijderen? + Wil je alle oproepen van Edge omleiden naar een andere browser of Edge helemaal verwijderen? + Alles omleiden + Stuur alle oproepen vanuit Edge door naar je favoriete browser. + Instellingen + Randkanaal + Selecteer het geïnstalleerde Microsoft Edge-kanaal. + Zoekmachine + Selecteer je favoriete zoekmachine. + Aangepast + Aangepaste zoekmachine + Voer de URL van de zoekmachine in. + Microsoft Edge (Stabiel) verwijderen + Verwijder Microsoft Edge volledig uit het systeem. + Configuratiescherm installeren + Installeer het configuratiescherm om GoAwayEdge eenvoudiger te configureren. + Het verwijderen van Microsoft Edge kan ernstige systeemproblemen veroorzaken, omdat het diep in Windows is geïntegreerd en essentieel is voor veel functies, waaronder updates, helpbestanden en sommige apps. Het verwijderen kan resulteren in instabiliteit of gebroken functionaliteit. Ga alleen verder als je de risico's volledig begrijpt en een betrouwbare back-up of herstelpunt hebt. + Microsoft Edge verwijderen + Installatie bezig ... + Wacht tot de installatie is voltooid. + Installatie voltooid! + Open gewoon deze Installer als u GoAwayEdge opnieuw wilt aanpassen. + De-installatie voltooid! + GoAwayEdge is succesvol verwijderd van het systeem. + Doneer via PayPal + GoAwayEdge Bedieningspaneel + Weerservice + Voer de URL van de weerdienst in. + Sleutel copiloot + Extern programma + Pad naar toepassing + Selecteer de toepassing die je wilt uitvoeren. + Argumenten + Definieer de argumenten van je toepassing. + Geen bron geselecteerd + Initialisatie mislukt: {0} + De-installatie mislukt: {0} + Update mislukt: {0} + Installatie mislukt! Probeer het opnieuw. + De verwijdering van Microsoft Edge is mislukt! Probeer het opnieuw. + Er is een nieuwe versie van GoAwayEdge (v{0}) beschikbaar. Deze update bevat nieuwe functies en bugfixes en waarborgt de functionaliteit van deze applicatie. + Microsoft Edge is bijgewerkt en GoAwayEdge moet het alternatieve opstartbestand bijwerken om de Edge-functionaliteit te garanderen. + Het alternatieve opstartbestand van Edge ontbreekt en moet worden gekopieerd om de functionaliteit van Edge te garanderen. Nu kopiëren? + Update installeren + Herinner me later + Deze versie overslaan + Update succesvol + Het alternatieve opstartbestand van Edge is succesvol bijgewerkt. + Succesvolle creatie + Het alternatieve opstartbestand van Edge is met succes gemaakt. + GoAwayEdge is met succes ingeschakeld op dit systeem. + GoAwayEdge is met succes uitgeschakeld op dit systeem. + Kan GoAwayEdge niet inschakelen op dit systeem: {0} + Kan GoAwayEdge niet uitschakelen op dit systeem: {0} + Kon de instellingen niet toepassen: {0} + Standaard + Ik accepteer deze licentie. + Een externe toepassing uitvoeren wanneer je op de Copilot-toets drukt. + Wijzig de service naar uw favoriete weerwebsite. + Aangepaste weerdienst + From fd618a9fa03184e9603d1e53fc82c92cb37b665f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 23:41:37 +0000 Subject: [PATCH 57/80] Translated using Weblate (Polish) Currently translated at 98.9% (92 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pl/ --- .../ResourceDictionary.pl-PL.xaml | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml b/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml index 2983743..68849e2 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml @@ -56,4 +56,46 @@ Tworzenie zakończone sukcesem Wersja Edge bez IFO została pomyślnie utworzona. Pomiń tę wersję + Czy chcesz przekierować wszystkie połączenia z Edge do innej przeglądarki lub całkowicie usunąć Edge? + Dostawca AI + Uruchomienie zewnętrznej aplikacji po naciśnięciu przycisku Copilot. + Usunięcie przeglądarki Microsoft Edge może spowodować poważne problemy systemowe, ponieważ jest ona głęboko zintegrowana z systemem Windows i niezbędna dla wielu funkcji, w tym aktualizacji, plików pomocy i niektórych aplikacji. Usunięcie go może spowodować niestabilność lub uszkodzenie funkcji.\n\nKontynuuj tylko wtedy, gdy w pełni rozumiesz ryzyko i masz niezawodną kopię zapasową lub punkt przywracania. + Wprowadź adres URL z serwisu pogodowego. + GoAwayEdge został pomyślnie włączony w tym systemie. + Wybierz aplikację, którą chcesz uruchomić. + Argumenty + Zdefiniuj argumenty swojej aplikacji. + Nie wybrano źródła + Funkcja GoAwayEdge została pomyślnie wyłączona w tym systemie. + Instalacja panelu sterowania + Zainstaluj Panel sterowania, aby łatwiej skonfigurować GoAwayEdge. + Zmień dostawcę na swojego ulubionego AI (lub na swoją ulubioną stronę internetową). + Dostawca niestandardowej sztucznej inteligencji + Domyślny + Ostrzeżenie + Anuluj + Przekierować czy usunąć? + Przekieruj wszystko + Przekieruj wszystkie połączenia z Edge do swojej ulubionej przeglądarki. + Usuń Microsoft Edge + Panel sterowania GoAwayEdge + Witamy w GoAwayEdge + Microsoft Edge + Windows Copilot + Zarządzanie wyszukiwarkami i nie tylko. + Zarządzanie skrótami klawiszowymi i nie tylko. + Włączanie/wyłączanie GoAwayEdge + Dezaktywacja przekazywania zapytań wyszukiwania do innych przeglądarek. + Włącz GoAwayEdge + Wyłącz GoAwayEdge + Wprowadź adres URL z dostawcy AI (lub swojej ulubionej strony internetowej). + Serwis pogodowy + Zmień usługę na swoją ulubioną witrynę pogodową. + Niestandardowa usługa pogodowa + Copilot Key + Program zewnętrzny + Ścieżka do aplikacji + Nie można włączyć GoAwayEdge w tym systemie: {0} + Nie można wyłączyć GoAwayEdge w tym systemie: {0} + Nie można zastosować ustawień: {0} From 37008b1fca37e3077464271c0340893243c268fb Mon Sep 17 00:00:00 2001 From: DeepL Date: Wed, 25 Dec 2024 23:50:23 +0000 Subject: [PATCH 58/80] Translated using Weblate (Romanian) Currently translated at 0.0% (0 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/ro/ --- .../ResourceDictionary.ro-RO.xaml | 100 +++++++++++++++++- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml b/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml index 8e1d2a0..6bfcf02 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml @@ -1,5 +1,95 @@ - - \ No newline at end of file + + Furnizor AI + Instalator GoAwayEdge + Următorul + Canal de margine + Selectați canalul Microsoft Edge instalat. + Motor de căutare + Avertisment + Anulează + Eliminarea Microsoft Edge poate cauza probleme grave de sistem, deoarece este profund integrat în Windows și esențial pentru multe caracteristici, inclusiv actualizări, fișiere de ajutor și unele aplicații. Ștergerea acestuia ar putea duce la instabilitate sau funcționalitate întreruptă.\n\nApoi continuați numai dacă înțelegeți pe deplin riscurile și aveți o copie de rezervă sau un punct de restaurare de încredere. + Instalare finalizată! + Dezinstalare finalizată! + Eliminați Microsoft Edge + Înapoi + Ieșire + Da + Nu + Bine ați venit + Instalați + Selectați motorul de căutare preferat. + Personalizat + Motor de căutare personalizat + Vă rugăm să introduceți URL-ul de interogare de la motorul de căutare. + Eliminați Microsoft Edge (Stabil) + Eliminați Microsoft Edge complet din sistem. + Instalarea panoului de control + Instalați Panoul de control pentru a configura mai ușor GoAwayEdge. + Schimbați furnizorul la AI-ul dvs. preferat (sau la site-ul dvs. preferat). + Furnizor de AI personalizat + Vă rugăm să introduceți URL-ul de la furnizorul de AI (sau site-ul dvs. preferat). + Pur și simplu deschideți acest program de instalare, dacă doriți să personalizați GoAwayEdge din nou. + GoAwayEdge a fost eliminat cu succes din sistem. + Donați prin PayPal + Panou de control GoAwayEdge + Bine ați venit la GoAwayEdge + Nu s-a putut dezactiva GoAwayEdge pe acest sistem: {0} + Nu s-a putut aplica setările: {0} + Dezactivați redirecționarea interogărilor de căutare către alte browsere. + Dezactivați GoAwayEdge + Serviciul meteorologic + Actualizare reușită + Fișierul de pornire alternativ al Edge a fost actualizat cu succes. + Creație de succes + Fișierul de pornire alternativ al Edge a fost creat cu succes. + GoAwayEdge a fost activat cu succes pe acest sistem. + GoAwayEdge a fost dezactivat cu succes pe acest sistem. + Nu s-a putut activa GoAwayEdge pe acest sistem: {0} + Schimbați serviciul la site-ul Weather preferat. + Serviciul meteorologic personalizat + Vă rugăm să introduceți URL-ul de la Serviciul meteorologic. + Cheie copilot + Program extern + Calea către cerere + Selectați aplicația pe care doriți să o rulați. + Argumente + Definiți argumentele aplicației dumneavoastră. + Nicio sursă selectată + Inițializarea a eșuat: {0} + Instalarea a eșuat: {0} + Dezinstalarea a eșuat: {0} + Instalarea a eșuat! Vă rugăm să încercați din nou. + Eliminarea Microsoft Edge a eșuat! Vă rugăm să încercați din nou. + Nu s-a reușit înregistrarea opțiunii de execuție a fișierului imagine pentru '{0}'. Vă rugăm să încercați din nou. + O nouă versiune a GoAwayEdge (v{0}) este disponibilă. Această actualizare include caracteristici noi, remedieri de erori și asigură funcționalitatea acestei aplicații. + Microsoft Edge a fost actualizat și GoAwayEdge trebuie să actualizeze fișierul de pornire alternativ pentru a asigura funcționalitatea Edge. + Fișierul de pornire alternativ al Edge lipsește și trebuie copiat pentru a asigura funcționalitatea Edge. Copiați acum? + Instalați actualizarea + Amintește-mi mai târziu + Sari peste această versiune + Rulați o aplicație externă atunci când apăsați tasta Copilot. + Implicit + Programul de instalare va efectua toți pașii necesari pentru a instala GoAwayEdge pe sistemul dvs. După instalare, toate apelurile Edge vor fi redirecționate către browserul dumneavoastră. Vă rugăm să selectați opțiunea dorită pentru a continua. + Instalați și configurați GoAwayEdge pe sistemul dvs. + Dezinstalare + Dezinstalați GoAwayEdge și restabiliți funcționalitatea Edge. + Vă rugăm să utilizați programul de instalare pentru a dezinstala GoAwayEdge. + Licență + Vă rugăm să citiți următoarea licență. Trebuie să acceptați termenii licenței înainte de a continua cu instalarea. + Accept această licență. + Refuz această licență. + Redirecționare sau eliminare? + Doriți să redirecționați toate apelurile din Edge către un alt browser sau să eliminați complet Edge? + Redirecționați totul + Redirecționați toate apelurile din Edge către browserul dvs. preferat. + Setări + Actualizarea a eșuat: {0} + Instalare în curs ... + Vă rugăm să așteptați până la finalizarea instalării. + Microsoft Edge + Windows Copilot + Gestionați motoarele de căutare și multe altele. + Gestionați comenzile rapide și multe altele. + Activare/Dezactivare GoAwayEdge + Activați GoAwayEdge + From 2152f991d28f915665a5968134766033839845f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 20:34:37 +0000 Subject: [PATCH 59/80] Translated using Weblate (Danish) Currently translated at 100.0% (93 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/da/ --- .../ResourceDictionary.da-DK.xaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml index b01462f..502dac2 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml @@ -71,4 +71,25 @@ Brugerdefineret AI-udbyder Indtast venligst URL'en fra AI-udbyderen (eller din foretrukne hjemmeside). Kunne ikke anvende indstillingerne: {0} + Kør et eksternt program, når du trykker på Copilot-tasten. + Fjernelse af Microsoft Edge kan forårsage alvorlige systemproblemer, da det er dybt integreret i Windows og afgørende for mange funktioner, herunder opdateringer, hjælpefiler og nogle apps. Hvis du sletter den, kan det resultere i ustabilitet eller ødelagt funktionalitet.\n\nFortsæt kun, hvis du forstår risikoen fuldt ud og har en pålidelig sikkerhedskopi eller et gendannelsespunkt på plads. + Advarsel + Annuller + Fjern Microsoft Edge + Vejrtjeneste + Skift tjeneste til dit foretrukne vejr-websted. + Brugerdefineret vejrtjeneste + Indtast venligst URL'en fra vejrtjenesten. + Kopilot-nøgle + Eksternt program + Vejen til ansøgning + Vælg det program, du vil køre. + Argumenter + Definer argumenterne for din applikation. + Ingen kilde valgt + Standard + Omdirigere eller fjerne? + Vil du omdirigere alle opkald fra Edge til en anden browser eller helt fjerne Edge? + Omdiriger alting + Omdiriger alle opkald fra Edge til din yndlingsbrowser. From 29574f2f5a1b0a48c368aa36ee4d80c7a25dfed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 20:28:54 +0000 Subject: [PATCH 60/80] Translated using Weblate (German) Currently translated at 100.0% (93 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/de/ --- GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index dcd56fd..caa3765 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -97,4 +97,6 @@ Wählen Sie die Anwendung, die Sie ausführen möchten. Argumente Definieren Sie die Argumente Ihrer Anwendung. + Führe beim Drücken der Copilot-Taste eine externe Anwendung aus. + Keine Quelle ausgewählt From 7eb3769eaf4a3301a65facc3444784c6310aac0a Mon Sep 17 00:00:00 2001 From: DeepL Date: Wed, 25 Dec 2024 23:51:30 +0000 Subject: [PATCH 61/80] Translated using Weblate (Portuguese (Portugal)) Currently translated at 0.0% (0 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pt_PT/ --- .../ResourceDictionary.pt-PT.xaml | 100 +++++++++++++++++- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml index 8e1d2a0..1dfc14b 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml @@ -1,5 +1,95 @@ - - \ No newline at end of file + + Instalador GoAwayEdge + Seguinte + Executar uma aplicação externa quando se prime a tecla Copilot. + Voltar + Sair + Sim + Não + Bem-vindo + O instalador executará todos os passos necessários para instalar o GoAwayEdge no seu sistema. Após a instalação, todas as chamadas do Edge serão redireccionadas para o seu browser. Por favor, selecione a opção desejada para continuar. + Instalar + Instale e configure o GoAwayEdge no seu sistema. + Desinstalar + Desinstalar o GoAwayEdge e restaurar a funcionalidade do Edge. + Selecione o canal Microsoft Edge instalado. + Motor de busca + Selecione o seu motor de busca preferido. + Personalizado + Instale o Painel de Controle para configurar o GoAwayEdge com mais facilidade. + Instalação em curso ... + Aguarde até que a instalação seja concluída. + Aviso + Cancelar + Criação bem sucedida + O arquivo de inicialização alternativo do Edge foi criado com sucesso. + O GoAwayEdge foi ativado com sucesso neste sistema. + Não foi possível ativar o GoAwayEdge neste sistema: {0} + Não foi possível desativar o GoAwayEdge neste sistema: {0} + Não foi possível aplicar as definições: {0} + O GoAwayEdge foi desativado com êxito neste sistema. + Altere o fornecedor para a sua IA favorita (ou para o seu sítio Web favorito). + Fornecedor de IA personalizado + Fornecedor de IA + A inicialização falhou: {0} + A instalação falhou! Por favor, tente novamente. + Instalar a atualização + Utilize o Instalador para desinstalar o GoAwayEdge. + Licença + Aceito esta licença. + Motor de pesquisa personalizado + Introduza o URL de consulta do motor de busca. + Remover Microsoft Edge (Estável) + Remover o Microsoft Edge completamente do sistema. + Instalar o painel de controlo + Por favor, leia a seguinte Licença. O utilizador deve aceitar os termos da licença antes de continuar com a instalação. + Definições + Canal de borda + Instalação concluída! + A remoção do Microsoft Edge pode causar problemas graves no sistema, uma vez que está profundamente integrado no Windows e é essencial para muitas funcionalidades, incluindo actualizações, ficheiros de ajuda e algumas aplicações. A sua eliminação pode resultar em instabilidade ou quebra de funcionalidade.\n\nSó prossiga se compreender totalmente os riscos e tiver uma cópia de segurança ou ponto de restauro fiável. + Basta abrir este Instalador, se quiser personalizar o GoAwayEdge novamente. + Desinstalação concluída! + O GoAwayEdge foi removido com sucesso do sistema. + Doar através de PayPal + Painel de controlo GoAwayEdge + Bem-vindo ao GoAwayEdge + Microsoft Edge + Copiloto do Windows + Gerir motores de busca e muito mais. + Gerir teclas de atalho e muito mais. + Ativar/desativar o GoAwayEdge + Desativar o reencaminhamento de consultas de pesquisa para outros navegadores. + Ativar o GoAwayEdge + Desativar o GoAwayEdge + Introduza o URL do fornecedor de IA (ou do seu sítio Web preferido). + Serviço meteorológico + Altere o serviço para o seu sítio Web de meteorologia favorito. + Serviço meteorológico personalizado + Introduza o URL do serviço meteorológico. + Chave do copiloto + Programa externo + Caminho para a aplicação + Selecione a aplicação que pretende executar. + Argumentos + Defina os argumentos da sua aplicação. + Nenhuma fonte selecionada + A instalação falhou: {0} + A desinstalação falhou: {0} + A atualização falhou: {0} + A remoção do Microsoft Edge falhou! Por favor, tente novamente. + Falha ao registar a Opção de Execução de Ficheiro de Imagem para '{0}'. Por favor, tente novamente. + Está disponível uma nova versão do GoAwayEdge (v{0}). Esta atualização inclui novas caraterísticas, correcções de erros e assegura a funcionalidade desta aplicação. + O Microsoft Edge foi atualizado e o GoAwayEdge precisa atualizar o arquivo de inicialização alternativo para garantir a funcionalidade do Edge. + O ficheiro de arranque alternativo do Edge está em falta e tem de ser copiado para garantir a funcionalidade do Edge. Copiar agora? + Lembrar-me mais tarde + Saltar esta versão + Atualização bem sucedida + O ficheiro de arranque alternativo do Edge foi atualizado com êxito. + Predefinição + Recuso esta licença. + Redirecionar ou remover? + Pretende redirecionar todas as chamadas do Edge para outro navegador ou remover completamente o Edge? + Redirecionar tudo + Redirecionar todas as chamadas do Edge para o seu browser favorito. + Remover Microsoft Edge + From bf60b228f54d5bd5e2b66baf57f3f5402aadffa7 Mon Sep 17 00:00:00 2001 From: DeepL Date: Wed, 25 Dec 2024 23:51:45 +0000 Subject: [PATCH 62/80] Translated using Weblate (Japanese) Currently translated at 0.0% (0 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/ja/ --- .../ResourceDictionary.ja-JP.xaml | 100 +++++++++++++++++- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml b/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml index 8e1d2a0..0ada2ff 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml @@ -1,5 +1,95 @@ - - \ No newline at end of file + + バック + 出口 + はい + いいえ + ようこそ + インストール + GoAwayEdgeをシステムにインストールし、設定します。 + GoAwayEdgeをアンインストールし、Edgeの機能を復元します。 + GoAwayEdgeをアンインストールするには、インストーラーをご利用ください。 + 以下のライセンスをお読みください。インストールを続行する前に、ライセンス条項に同意する必要があります。 + 私はこのライセンスに同意する。 + 私はこのライセンスを辞退する。 + Edgeからのすべての通話をお気に入りのブラウザにリダイレクト。 + 設定 + 検索エンジン + お好きな検索エンジンを選択してください。 + カスタム + カスタム検索エンジン + Microsoft Edge(安定版)を削除する + Microsoft Edgeをシステムから完全に削除する。 + コントロールパネルのインストール + GoAwayEdgeをより簡単に設定するためにコントロールパネルをインストールしてください。 + Microsoft EdgeはWindowsに深く統合されており、アップデート、ヘルプファイル、一部のアプリなど、多くの機能に不可欠なため、削除するとシステムに深刻な問題が発生する可能性があります。削除すると、動作が不安定になったり、機能が壊れたりする可能性があります。リスクを十分に理解し、信頼できるバックアップや復元ポイントがある場合にのみ実行してください。 + Microsoft Edgeを削除する + インストール中 ... + インストールが完了するまでお待ちください。 + 設置完了! + GoAwayEdgeを再度カスタマイズしたい場合は、このインストーラーを開くだけです。 + アンインストールが完了しました! + GoAwayEdgeはシステムから正常に削除されました。 + PayPalで寄付する + GoAwayEdgeコントロールパネル + GoAwayEdgeへようこそ + マイクロソフト・エッジ + ウィンドウズ・コパイロット + 検索エンジンの管理など。 + GoAwayEdgeの有効化/無効化 + 他のブラウザへの検索クエリの転送を無効にする。 + GoAwayEdgeを有効にする + GoAwayEdgeを無効にする + GoAwayEdgeインストーラー + 次のページ + ウェザー・サービス + お好きなウェザーサイトにサービスを変更してください。 + カスタム気象サービス + 気象庁のURLを入力してください。 + コパイロット・キー + 外部プログラム + 応募への道 + 実行したいアプリケーションを選択します。 + 論争 + アプリケーションの引数を定義する。 + ソースが選択されていない + Microsoft Edgeの削除に失敗しました!もう一度お試しください。 + {0}' の画像ファイル実行オプションの登録に失敗しました。もう一度お試しください。 + 警告 + キャンセル + ライセンス + リダイレクトか削除か? + Edgeからのすべての通話を別のブラウザにリダイレクトさせたいですか、それともEdgeを完全に削除したいですか? + すべてをリダイレクト + エッジ・チャンネル + インストールされているMicrosoft Edge Channelを選択します。 + 検索エンジンからのクエリーURLを入力してください。 + Copilotキーを押したときに外部アプリケーションを実行する。 + ホットキーの管理など。 + このシステムでGoAwayEdgeを有効にできませんでした:{0} + プロバイダーをお気に入りのAIに変更する(またはお気に入りのウェブサイトに変更する)。 + GoAwayEdge の新バージョン (v{0}) がリリースされました。このアップデートには、新機能、バグ修正が含まれ、このアプリケーションの機能を保証します。 + Microsoft Edgeが更新され、GoAwayEdgeはEdgeの機能を確保するために代替スタートアップファイルを更新する必要があります。 + Edgeの代替スタートアップファイルが見つからないため、Edgeの機能を確保するためにコピーする必要があります。今すぐコピーしますか? + 後で思い出す + このバージョンをスキップする + 更新成功 + Edgeの代替スタートアップファイルが正常に更新されました。 + 創造に成功 + Edgeの代替スタートアップファイルが正常に作成されました。 + GoAwayEdgeはこのシステムで正常に有効化されました。 + GoAwayEdgeはこのシステムで正常に無効化されました。 + このシステムでGoAwayEdgeを無効にできませんでした:{0} + 設定を適用できませんでした:{0} + カスタムAIプロバイダー + AIプロバイダー(またはお好きなウェブサイト)のURLを入力してください。 + 初期化に失敗した:{0} + インストールに失敗した:{0} + アンインストールに失敗しました:{0} + アップデートに失敗した:{0} + インストールに失敗しました!もう一度お試しください。 + アップデートのインストール + AIプロバイダー + インストーラは、GoAwayEdgeをシステムにインストールするために必要なすべての手順を実行します。インストール後、すべてのEdgeコールがブラウザにリダイレクトされます。続行するには、希望のオプションを選択してください。 + デフォルト + アンインストール + From 0fa35d71be8347623ff3de07d957ab7241efeabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 20:35:00 +0000 Subject: [PATCH 63/80] Translated using Weblate (French) Currently translated at 100.0% (93 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/fr/ --- .../ResourceDictionary.fr-FR.xaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml index 87a926b..9c3256d 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml @@ -77,4 +77,25 @@ GoAwayEdge a été désactivé avec succès sur ce système. Impossible d'activer GoAwayEdge sur ce système : {0} Impossible d'appliquer les paramètres : {0} + Défaut + Rediriger ou supprimer ? + Voulez-vous rediriger tous les appels de Edge vers un autre navigateur, ou supprimer complètement Edge ? + Rediriger tous les appels de Edge vers votre navigateur préféré. + Avertissement + Annuler + Tout rediriger + La suppression de Microsoft Edge peut entraîner de graves problèmes pour le système, car il est profondément intégré à Windows et essentiel pour de nombreuses fonctionnalités, notamment les mises à jour, les fichiers d'aide et certaines applications. Sa suppression peut entraîner une instabilité ou des dysfonctionnements.\n\nNe procédez que si vous comprenez parfaitement les risques et si vous disposez d'une sauvegarde fiable ou d'un point de restauration. + Supprimer Microsoft Edge + Service météorologique + Changez le service pour votre site web météo préféré. + Service météorologique personnalisé + Veuillez saisir l'URL du service météorologique. + Clé Copilote + Programme externe + Exécuter une application externe lorsque vous appuyez sur la touche Copilote. + Chemin d'accès à l'application + Sélectionnez l'application que vous souhaitez exécuter. + Arguments + Définissez les arguments de votre application. + Aucune source sélectionnée From cd3d64f1fe7f28d6fc30a0a497867c2c908d88ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Wed, 25 Dec 2024 23:45:55 +0000 Subject: [PATCH 64/80] Translated using Weblate (Portuguese (Brazil)) Currently translated at 87.0% (81 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pt_BR/ --- .../ResourceDictionary.pt-BR.xaml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml index d9fce4f..d2ad094 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml @@ -58,4 +58,44 @@ O arquivo de inicialização alternativo do Edge foi criado com sucesso. Instalar Painel de Controle Instalar o Painel de Controle para configurar o GoAwayEdge mais facilmente. + Execute um aplicativo externo quando você pressionar a tecla Copilot. + A remoção do Microsoft Edge pode causar sérios problemas no sistema, pois ele está profundamente integrado ao Windows e é essencial para muitos recursos, incluindo atualizações, arquivos de ajuda e alguns aplicativos. Excluí-lo pode resultar em instabilidade ou funcionalidade interrompida.\n\nSó prossiga se você compreender totalmente os riscos e tiver um backup ou ponto de restauração confiável. + Não foi possível aplicar as configurações: {0} + Não foi possível desativar o GoAwayEdge neste sistema: {0} + Deseja redirecionar todas as chamadas do Edge para outro navegador ou remover completamente o Edge? + Caminho para o aplicativo + Selecione o aplicativo que deseja executar. + Gerencie teclas de atalho e muito mais. + Ativar/desativar o GoAwayEdge + Desativar o encaminhamento de consultas de pesquisa para outros navegadores. + Ativar o GoAwayEdge + Desativar o GoAwayEdge + Serviço meteorológico + Altere o serviço para seu site de clima favorito. + Serviço meteorológico personalizado + Digite o URL do Serviço de Meteorologia. + Chave do copiloto + Programa externo + Argumentos + Defina os argumentos de seu aplicativo. + Nenhuma fonte selecionada + O GoAwayEdge foi desativado com sucesso neste sistema. + Não foi possível ativar o GoAwayEdge neste sistema: {0} + Provedor de IA + Altere o provedor para sua IA favorita (ou para seu site favorito). + Provedor de IA personalizado + Digite o URL do provedor de IA (ou seu site favorito). + O GoAwayEdge foi ativado com sucesso neste sistema. + Padrão + Advertência + Cancelar + Redirecionar ou remover? + Redirecionar tudo + Redirecione todas as chamadas do Edge para seu navegador favorito. + Remover Microsoft Edge + Painel de controle do GoAwayEdge + Bem-vindo ao GoAwayEdge + Microsoft Edge + Windows Copilot + Gerenciar mecanismos de pesquisa e muito mais. From 4aac961c9e46bb39390d983128fb37437eabc672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 02:19:11 +0100 Subject: [PATCH 65/80] Updated silent switch --- GoAwayEdge/App.xaml.cs | 48 ++++++++++++++----- .../Common/Installation/InstallRoutine.cs | 27 +++++++---- GoAwayEdge/Common/Runtime/ArgumentParse.cs | 16 +++++-- .../ResourceDictionary.de-DE.xaml | 1 + .../Localization/ResourceDictionary.xaml | 1 + .../UserInterface/Setup/Installer.xaml.cs | 3 +- .../Setup/Pages/Installation.xaml.cs | 7 ++- .../Setup/Pages/InstallationSuccess.xaml.cs | 4 ++ README.md | 24 ++++++---- 9 files changed, 91 insertions(+), 40 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index 9f9355c..a6b8dc5 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -50,7 +50,7 @@ public void Application_Startup(object sender, StartupEventArgs e) IsDebug = true; if (IsAdministrator() == false) { - ElevateAsAdmin(); + ElevateAsAdmin(); Environment.Exit(0); return; } @@ -70,7 +70,7 @@ public void Application_Startup(object sender, StartupEventArgs e) { if (IsAdministrator() == false) { - ElevateAsAdmin(string.Join(" ", args)); + ElevateAsAdmin(string.Join(" ", args)); Environment.Exit(0); return; } @@ -113,25 +113,47 @@ public void Application_Startup(object sender, StartupEventArgs e) { foreach (var arg in args) { - if (arg.StartsWith("-se:")) + if (arg.StartsWith("-e:")) Configuration.Search = ArgumentParse.ParseSearchEngine(arg); - if (arg.Contains("--url:")) + if (arg.Contains("--search-url:")) { - Configuration.CustomQueryUrl = ParseCustomSearchEngine(arg); - Configuration.Search = !string.IsNullOrEmpty(Configuration.CustomQueryUrl) ? SearchEngine.Custom : SearchEngine.Google; + Configuration.CustomQueryUrl = ParseCustomUrl(arg, 13); + Configuration.Search = !string.IsNullOrEmpty(Configuration.CustomQueryUrl) + ? SearchEngine.Custom + : SearchEngine.Google; + } + + if (arg.Contains("-a:")) + Configuration.AiProvider = ArgumentParse.ParseAiProvider(arg); + if (arg.Contains("--ai-url:")) + { + Configuration.CustomAiProviderUrl = ParseCustomUrl(arg, 9); + Configuration.AiProvider = !string.IsNullOrEmpty(Configuration.CustomAiProviderUrl) + ? AiProvider.Custom + : AiProvider.Default; + } + + if (arg.Contains("-w:")) + Configuration.WeatherProvider = ArgumentParse.ParseWeatherProvider(arg); + if (arg.Contains("--weather-url:")) + { + Configuration.CustomWeatherProviderUrl = ParseCustomUrl(arg, 14); + Configuration.WeatherProvider = !string.IsNullOrEmpty(Configuration.CustomWeatherProviderUrl) + ? WeatherProvider.Custom + : WeatherProvider.Default; } } if (IsAdministrator() == false) { - ElevateAsAdmin(string.Join(" ", args)); + ElevateAsAdmin(string.Join(" ", args)); Environment.Exit(0); return; } Configuration.InitialEnvironment(); - InstallRoutine.Install(null); - Environment.Exit(0); + var result = InstallRoutine.Install(null); + Environment.Exit(result); } if (args.Contains("-u")) { @@ -191,7 +213,7 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") - ElevateAsAdmin("--update"); + ElevateAsAdmin("--update"); Environment.Exit(0); } @@ -207,7 +229,7 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") - ElevateAsAdmin("--update"); + ElevateAsAdmin("--update"); Environment.Exit(0); } @@ -240,9 +262,9 @@ private static void ElevateAsAdmin(string? arguments = null) Process.Start(startInfo); } - private static string? ParseCustomSearchEngine(string argument) + private static string? ParseCustomUrl(string argument, int count) { - var argParsed = argument.Remove(0, 6); + var argParsed = argument.Remove(0, count); var result = Uri.TryCreate(argParsed, UriKind.Absolute, out var uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); return result ? argParsed : null; diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index c150eb9..a4bced3 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -19,7 +19,7 @@ public partial class Shell32 public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); } - public static void Install(object? sender, DoWorkEventArgs? e = null) + public static int Install(object? sender, DoWorkEventArgs? e = null) { var worker = sender as BackgroundWorker; @@ -40,7 +40,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Apply registry key @@ -108,7 +108,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } } catch (Exception ex) @@ -121,7 +121,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Kill Microsoft Edge processes @@ -142,7 +142,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } } else if (!Configuration.NoEdgeInstalled) @@ -163,7 +163,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } } @@ -201,7 +201,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Register Uninstall data @@ -216,7 +216,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Create Shortcut for Control Panel @@ -235,6 +235,7 @@ public static void Install(object? sender, DoWorkEventArgs? e = null) worker?.ReportProgress(100, ""); Logging.Log("Installation finished."); Console.WriteLine("Installation finished."); + return 0; } public static void Uninstall(object? sender, DoWorkEventArgs? e = null) @@ -417,9 +418,15 @@ internal static bool CopyItself(string pathTo, bool overwrite = false) } } - catch (Exception e) + catch (Exception ex) { - MessageBox.Show(e.ToString()); + Logging.Log("Failed to copy itself: " + ex, Logging.LogLevel.ERROR); + Application.Current.Dispatcher.Invoke(() => + { + var errorMessage = LocalizationManager.LocalizeValue("FailedInstallation", ex.Message); + var messageUi = new MessageUi("GoAwayEdge", errorMessage, "OK"); + messageUi.ShowDialog(); + }); return false; } diff --git a/GoAwayEdge/Common/Runtime/ArgumentParse.cs b/GoAwayEdge/Common/Runtime/ArgumentParse.cs index d28b3a3..f039b99 100644 --- a/GoAwayEdge/Common/Runtime/ArgumentParse.cs +++ b/GoAwayEdge/Common/Runtime/ArgumentParse.cs @@ -211,7 +211,11 @@ public static EdgeChannel ParseEdgeChannel(string argument) public static AiProvider ParseAiProvider(string argument) { - return argument.ToLower() switch + var arg = argument; + if (argument.StartsWith("-a:")) + arg = argument.Remove(0, 3); + + return arg.ToLower() switch { "default" => AiProvider.Default, "copilot" => AiProvider.Copilot, @@ -227,8 +231,8 @@ public static AiProvider ParseAiProvider(string argument) public static SearchEngine ParseSearchEngine(string argument) { var arg = argument; - if (argument.StartsWith("-se:")) - arg = argument.Remove(0, 4); + if (argument.StartsWith("-e:")) + arg = argument.Remove(0, 3); return arg.ToLower() switch { @@ -248,7 +252,11 @@ public static SearchEngine ParseSearchEngine(string argument) public static WeatherProvider ParseWeatherProvider(string argument) { - return argument.ToLower() switch + var arg = argument; + if (argument.StartsWith("-w:")) + arg = argument.Remove(0, 3); + + return arg.ToLower() switch { "default" => WeatherProvider.Default, "weathercom" => WeatherProvider.WeatherCom, diff --git a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml index caa3765..c952b4f 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.de-DE.xaml @@ -45,6 +45,7 @@ Installation abgeschlossen! Öffnen Sie das Installationsprogramm, wenn Sie GoAwayEdge erneut anpassen möchten. + Öffnen Sie das Installationsprogramm oder das Kontrollpanel, wenn Sie GoAwayEdge erneut anpassen möchten. Deinstallation abgeschlossen! GoAwayEdge wurde erfolgreich vom System entfernt. Über PayPal spenden diff --git a/GoAwayEdge/Localization/ResourceDictionary.xaml b/GoAwayEdge/Localization/ResourceDictionary.xaml index b71241c..1aa727e 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.xaml @@ -55,6 +55,7 @@ Installation completed! Simply open this Installer, if you want to customize GoAwayEdge again. + Simply open this installer or the Control Panel if you want to customize GoAwayEdge again. Uninstallation completed! GoAwayEdge has been successfully removed from the system. Donate via PayPal diff --git a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs index 10da43e..504aaa0 100644 --- a/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Installer.xaml.cs @@ -65,7 +65,6 @@ internal void NextBtn_OnClick(object sender, RoutedEventArgs e) NextBtn.IsEnabled = false; BackBtn.IsEnabled = true; FrameWindow.Content = _redirectOrRemovePage; - SettingPage = new Settings(); break; } } @@ -81,7 +80,7 @@ private void BackBtn_OnClick(object sender, RoutedEventArgs e) FrameWindow.Content = LicensePage; break; case Settings: - NextBtn.IsEnabled = true; + NextBtn.IsEnabled = false; BackBtn.IsEnabled = true; FrameWindow.Content = _redirectOrRemovePage; break; diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs index 4117f99..fca8233 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs @@ -23,7 +23,7 @@ public Installation() } else { - applyBackgroundWorker.DoWork += InstallRoutine.Install; + applyBackgroundWorker.DoWork += InstallRoutine_Install; } applyBackgroundWorker.ProgressChanged += ApplyBackgroundWorker_ProgressChanged; applyBackgroundWorker.RunWorkerAsync(); @@ -36,5 +36,10 @@ private static void ApplyBackgroundWorker_ProgressChanged(object? sender, Progre Installer.ContentWindow?.FrameWindow.NavigationService.Navigate(new InstallationSuccess()); } } + + private static void InstallRoutine_Install(object? sender, DoWorkEventArgs e) + { + e.Result = InstallRoutine.Install(sender, e); + } } } diff --git a/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs index 5514679..4faab88 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/InstallationSuccess.xaml.cs @@ -19,6 +19,10 @@ public InstallationSuccess() Installer.ContentWindow!.NextBtn.Content = !string.IsNullOrEmpty(exitResource) ? exitResource : "Exit"; + var setupDescriptionResource = Configuration.InstallControlPanel ? + (string)Application.Current.MainWindow!.FindResource("SetupFinishedDescriptionWithControlPanel") : (string)Application.Current.MainWindow!.FindResource("SetupFinishedDescription"); + SetupDescription.Text = setupDescriptionResource; + if (Configuration.Uninstall) { Dispatcher.Invoke(() => diff --git a/README.md b/README.md index 729cdef..d990bdc 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Help me translate

- 🎉 Version 1.3.4 is out. Check out the release notes + 🎉 Version 2.0.0 is out. Check out the release notes here.

@@ -72,17 +72,21 @@ Feel free to explore the code, contribute, or simply enjoy a browser experience ## 🤫 2. Silent Installation You can install GoAwayEdge silently by parsing the following arguments: -| Switch | Description | -| ----------------- | ------------------------------------------------------------------------- | -| `-s` | Silent installation | -| `-se:` | Specify the Search Engine: `Google` (default), `Bing`, `DuckDuckGo`, `Yahoo`, `Yandex`, `Ecisua`, `Ask`, `Quant`, `Perplexity` | -| `--url:` | Custom search query url (ex: `https://google.com/search?q=`) | +| Switch | Description | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | +| `-s` | Silent installation | +| `-e:` | Specify the Search Engine: `Google` (default), `Bing`, `DuckDuckGo`, `Yahoo`, `Yandex`, `Ecisua`, `Ask`, `Quant`, `Perplexity` | +| `-a:` | Specify the AI Service: `Default`, `Copilot`, `ChatGPT`, `Gemini`, `GitHub_Copilot`, `Grok`, | +| `-w:` | Specify the Weather Service: `Default`, `WeatherCom`, `AccuWeather` | +| `--search-url:` | Custom search query url (ex: `https://google.com/search?q=`) | +| `--ai-url:` | Custom AI website (ex: `https://chatgpt.com`) | +| `--weather-url:` | Custom weather query url (ex: `https://my-weather.com/{country-code}/{latitude},{longitude}`) | Example: ```bat -GoAwayEdge.exe -s -se:DuckDuckGo -``` +GoAwayEdge.exe -s -e:DuckDuckGo +``` # 🗑️ Remove GoAwayEdge You can uninstall GoAwayEdge just like any other application. Alternatively, you can also take this way: @@ -91,7 +95,7 @@ You can uninstall GoAwayEdge just like any other application. Alternatively, you 3. Click on ```Uninstall```. 4. Done! -You can also uninstall GoAwayEdge by parsing the following argument: +You can also silently uninstall GoAwayEdge by parsing the following argument: ```bat GoAwayEdge.exe -u ``` @@ -110,7 +114,7 @@ This project uses the following libraries: GoAwayEdge is licensed under [MIT](https://github.com/valnoxy/GoAwayEdge/blob/main/LICENSE). So you are allowed to use freely and modify the application. I will not be responsible for any outcome. Proceed with any action at your own risk.
-
© 2018 - 2024 valnoxy. All Rights Reserved. +
© 2018 - 2025 valnoxy. All Rights Reserved.
By Jonas Günner <jonas@exploitox.de>

From 1ad40b481d2ad5eb15255381ac1b947c70bf459e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 01:57:00 +0000 Subject: [PATCH 66/80] Translated using Weblate (Spanish) Currently translated at 100.0% (93 of 93 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/es/ --- GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml index 8014003..1f2c2b8 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml @@ -62,7 +62,7 @@ No se ha podido desactivar GoAwayEdge en este sistema: {0} No se ha podido aplicar la configuración: {0} Desactivar GoAwayEdge - Eliminar Microsoft Edge puede causar graves problemas en el sistema, ya que está profundamente integrado en Windows y es esencial para muchas funciones, como las actualizaciones, los archivos de ayuda y algunas aplicaciones. Si lo eliminas, podrías provocar inestabilidad o una funcionalidad dañada.\n\n Solo procede si conoces bien los riesgos y tienes una copia de seguridad fiable o un punto de restauración. + Eliminar Microsoft Edge puede causar graves problemas en el sistema, ya que está profundamente integrado en Windows y es esencial para muchas funciones, como las actualizaciones, los archivos de ayuda y algunas aplicaciones. Si lo eliminas, podrías provocar inestabilidad o una funcionalidad dañada.\n\nSolo procede si conoces bien los riesgos y tienes una copia de seguridad fiable o un punto de restauración. Advertencia Cancelar ¿Quieres redirigir todas las llamadas de Edge a otro navegador o eliminar Edge por completo? From a9bac4d4affb4427575959c3908772a1effed645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:30:02 +0000 Subject: [PATCH 67/80] Translated using Weblate (Spanish) Currently translated at 98.9% (93 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/es/ --- GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml index 1f2c2b8..0e746e7 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.es-ES.xaml @@ -98,4 +98,5 @@ Servicio Meteorológico Servicio Meteorológico Personalizado Introduzca la URL del Servicio Meteorológico. + Simplemente abre este instalador o el Panel de Control si quieres personalizar GoAwayEdge de nuevo. From 30a49e084bc8654028c3dd801e5350857f9fadb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:09 +0000 Subject: [PATCH 68/80] Translated using Weblate (French) Currently translated at 98.9% (93 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/fr/ --- GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml index 9c3256d..9c10acf 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.fr-FR.xaml @@ -98,4 +98,5 @@ Arguments Définissez les arguments de votre application. Aucune source sélectionnée + Ouvrez simplement ce programme d'installation ou le panneau de configuration si vous souhaitez personnaliser GoAwayEdge à nouveau. From a356be57886e19b5ef0de6e22c7321ca34f94020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:19 +0000 Subject: [PATCH 69/80] Translated using Weblate (Italian) Currently translated at 98.9% (93 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/it/ --- GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml index 9ca5234..d1bb109 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.it-IT.xaml @@ -98,4 +98,5 @@ Definire gli argomenti dell'applicazione. Nessuna sorgente selezionata Predefinito + È sufficiente aprire questo programma di installazione o il Pannello di controllo se si desidera personalizzare nuovamente GoAwayEdge. From a5c4550fa564e497883e22d17b4d6b423349a0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:31 +0000 Subject: [PATCH 70/80] Translated using Weblate (Korean) Currently translated at 60.6% (57 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/ko/ --- GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml b/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml index 79af1a1..4792445 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ko-KR.xaml @@ -98,4 +98,5 @@ Edge에서 다른 브라우저로 모든 호출을 리디렉션하거나 Edge를 완전히 제거하시겠습니까? 모든 것을 리디렉션 모든 통화를 Edge에서 즐겨 사용하는 브라우저로 리디렉션하세요. + 이 설치 프로그램이나 제어판을 열면 GoAwayEdge를 다시 사용자 지정할 수 있습니다. From 4f31f8f42715d97ad80940ca434f6e1777d8084f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:42 +0000 Subject: [PATCH 71/80] Translated using Weblate (Polish) Currently translated at 97.8% (92 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pl/ --- GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml b/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml index 68849e2..e04e62d 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pl-PL.xaml @@ -98,4 +98,5 @@ Nie można włączyć GoAwayEdge w tym systemie: {0} Nie można wyłączyć GoAwayEdge w tym systemie: {0} Nie można zastosować ustawień: {0} + Po prostu otwórz ten instalator lub Panel sterowania, jeśli chcesz ponownie dostosować GoAwayEdge. From f89b1deb03f7e2e5b9d17d415731ab31f7c6bed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:47 +0000 Subject: [PATCH 72/80] Translated using Weblate (Portuguese (Brazil)) Currently translated at 86.1% (81 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pt_BR/ --- GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml index d2ad094..7f1587e 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pt-BR.xaml @@ -98,4 +98,5 @@ Microsoft Edge Windows Copilot Gerenciar mecanismos de pesquisa e muito mais. + Basta abrir esse instalador ou o Painel de Controle se quiser personalizar o GoAwayEdge novamente. From 0a1f917c82ce54765ec2cc688a347d24c3ed84cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:28:57 +0000 Subject: [PATCH 73/80] Translated using Weblate (Danish) Currently translated at 98.9% (93 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/da/ --- GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml index 502dac2..e36756a 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.da-DK.xaml @@ -92,4 +92,5 @@ Vil du omdirigere alle opkald fra Edge til en anden browser eller helt fjerne Edge? Omdiriger alting Omdiriger alle opkald fra Edge til din yndlingsbrowser. + Du skal blot åbne dette installationsprogram eller kontrolpanelet, hvis du vil tilpasse GoAwayEdge igen. From 3cafdd20196b1952bab614257153a999c5410a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:25 +0000 Subject: [PATCH 74/80] Translated using Weblate (Japanese) Currently translated at 0.0% (0 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/ja/ --- GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml b/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml index 0ada2ff..ccd6ce3 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ja-JP.xaml @@ -92,4 +92,5 @@ インストーラは、GoAwayEdgeをシステムにインストールするために必要なすべての手順を実行します。インストール後、すべてのEdgeコールがブラウザにリダイレクトされます。続行するには、希望のオプションを選択してください。 デフォルト アンインストール + GoAwayEdgeを再度カスタマイズしたい場合は、このインストーラーまたはコントロールパネルを開くだけです。 From 07da46f9c1289420cba216e26c5d46492752c832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:36 +0000 Subject: [PATCH 75/80] Translated using Weblate (Dutch) Currently translated at 0.0% (0 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/nl/ --- GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml b/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml index cf6c97a..523706f 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.nl-NL.xaml @@ -92,4 +92,5 @@ Een externe toepassing uitvoeren wanneer je op de Copilot-toets drukt. Wijzig de service naar uw favoriete weerwebsite. Aangepaste weerdienst + Open gewoon dit installatieprogramma of het Configuratiescherm als je GoAwayEdge opnieuw wilt aanpassen. From c94f6212d5598a4de8111f54b1d2ae2dec19e0a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:57 +0000 Subject: [PATCH 76/80] Translated using Weblate (Romanian) Currently translated at 0.0% (0 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/ro/ --- GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml b/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml index 6bfcf02..50fc405 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.ro-RO.xaml @@ -92,4 +92,5 @@ Gestionați comenzile rapide și multe altele. Activare/Dezactivare GoAwayEdge Activați GoAwayEdge + Pur și simplu deschideți acest program de instalare sau panoul de control dacă doriți să personalizați din nou GoAwayEdge. From 85bd65c902c73b35e9ef0f10f7a64b8fc6f99063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 13:29:52 +0000 Subject: [PATCH 77/80] Translated using Weblate (Portuguese (Portugal)) Currently translated at 0.0% (0 of 94 strings) Translation: GoAwayEdge/User Interface Translate-URL: http://translate.valnoxy.dev/projects/goawayedge/user-interface/pt_PT/ --- GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml b/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml index 1dfc14b..d70bd09 100644 --- a/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml +++ b/GoAwayEdge/Localization/ResourceDictionary.pt-PT.xaml @@ -92,4 +92,5 @@ Redirecionar tudo Redirecionar todas as chamadas do Edge para o seu browser favorito. Remover Microsoft Edge + Basta abrir este instalador ou o Painel de Controlo se pretender personalizar novamente o GoAwayEdge. From 3848a8b0638ce058271d2890aab850d0cb5d33e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 15:10:50 +0100 Subject: [PATCH 78/80] Update Readme --- GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index 95c27a5..cf6e58a 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-12-25T16:22:09.8471194Z||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; + True|2024-12-26T14:09:04.1027404Z||;True|2024-12-26T15:03:19.0005711+01:00||;True|2024-12-25T17:22:09.8471194+01:00||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; \ No newline at end of file diff --git a/README.md b/README.md index efab9ee..ecf1fc3 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ You can install GoAwayEdge silently by parsing the following arguments: | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | | `-s` | Silent installation | | `-e:` | Specify the Search Engine: `Google` (default), `Bing`, `DuckDuckGo`, `Yahoo`, `Yandex`, `Ecosia`, `Ask`, `Qwant`, `Perplexity` | -| `-a:` | Specify the AI Service: `Default`, `Copilot`, `ChatGPT`, `Gemini`, `GitHub_Copilot`, `Grok`, | +| `-a:` | Specify the AI Service: `Default`, `Copilot`, `ChatGPT`, `Gemini`, `GitHub_Copilot`, `Grok` | | `-w:` | Specify the Weather Service: `Default`, `WeatherCom`, `AccuWeather` | | `--search-url:` | Custom search query url (ex: `https://google.com/search?q=`) | | `--ai-url:` | Custom AI website (ex: `https://chatgpt.com`) | From d40a66a3d9254b546dd84a9d47a9d7ae378ef698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 15:26:10 +0100 Subject: [PATCH 79/80] Fixed silent uninstall bug --- GoAwayEdge/App.xaml.cs | 11 +++++++++-- GoAwayEdge/Common/Installation/InstallRoutine.cs | 13 +++++++------ .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../UserInterface/Setup/Pages/Installation.xaml.cs | 7 ++++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index a6b8dc5..cc4feb3 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -151,14 +151,21 @@ public void Application_Startup(object sender, StartupEventArgs e) return; } + Configuration.InstallControlPanel = true; Configuration.InitialEnvironment(); var result = InstallRoutine.Install(null); Environment.Exit(result); } if (args.Contains("-u")) { - InstallRoutine.Uninstall(null); - Environment.Exit(0); + if (IsAdministrator() == false) + { + ElevateAsAdmin(string.Join(" ", args)); + Environment.Exit(0); + return; + } + var result = InstallRoutine.Uninstall(null); + Environment.Exit(result); } if (args.Contains("--update")) { diff --git a/GoAwayEdge/Common/Installation/InstallRoutine.cs b/GoAwayEdge/Common/Installation/InstallRoutine.cs index a4bced3..0d2cbeb 100644 --- a/GoAwayEdge/Common/Installation/InstallRoutine.cs +++ b/GoAwayEdge/Common/Installation/InstallRoutine.cs @@ -238,7 +238,7 @@ public static int Install(object? sender, DoWorkEventArgs? e = null) return 0; } - public static void Uninstall(object? sender, DoWorkEventArgs? e = null) + public static int Uninstall(object? sender, DoWorkEventArgs? e = null) { var worker = sender as BackgroundWorker; Logging.Log("Start uninstallation ..."); @@ -261,7 +261,7 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } Process.Start(new ProcessStartInfo { @@ -269,7 +269,7 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) Arguments = "-u", UseShellExecute = true }); - Environment.Exit(0); + Environment.Exit(3010); } // Remove installation directory @@ -288,7 +288,7 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Remove user directory @@ -310,7 +310,7 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Remove Ifeo & Uri handler from registry @@ -359,7 +359,7 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) messageUi.ShowDialog(); }); Environment.Exit(1); - return; + return 1; } // Clean up Task Scheduler @@ -402,6 +402,7 @@ public static void Uninstall(object? sender, DoWorkEventArgs? e = null) worker?.ReportProgress(100, ""); Logging.Log("Uninstallation finished."); Console.WriteLine("Uninstallation finished."); + return 0; } internal static bool CopyItself(string pathTo, bool overwrite = false) diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index cf6e58a..6e07314 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-12-26T14:09:04.1027404Z||;True|2024-12-26T15:03:19.0005711+01:00||;True|2024-12-25T17:22:09.8471194+01:00||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; + True|2024-12-26T14:22:32.4690057Z||;True|2024-12-26T15:09:04.1027404+01:00||;True|2024-12-26T15:03:19.0005711+01:00||;True|2024-12-25T17:22:09.8471194+01:00||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; \ No newline at end of file diff --git a/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs index fca8233..baaa15e 100644 --- a/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs +++ b/GoAwayEdge/UserInterface/Setup/Pages/Installation.xaml.cs @@ -19,7 +19,7 @@ public Installation() applyBackgroundWorker.WorkerSupportsCancellation = true; if (Configuration.Uninstall) { - applyBackgroundWorker.DoWork += InstallRoutine.Uninstall; + applyBackgroundWorker.DoWork += InstallRoutine_Uninstall; } else { @@ -41,5 +41,10 @@ private static void InstallRoutine_Install(object? sender, DoWorkEventArgs e) { e.Result = InstallRoutine.Install(sender, e); } + + private static void InstallRoutine_Uninstall(object? sender, DoWorkEventArgs e) + { + e.Result = InstallRoutine.Uninstall(sender, e); + } } } From 2c13b22f5d20c51abca1c05fc3d52cb7ef2d8498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20G=C3=BCnner?= Date: Thu, 26 Dec 2024 19:05:48 +0100 Subject: [PATCH 80/80] Updated silent update --- GoAwayEdge/App.xaml.cs | 40 ++++++++++++++----- .../PublishProfiles/FolderProfile.pubxml.user | 2 +- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/GoAwayEdge/App.xaml.cs b/GoAwayEdge/App.xaml.cs index cc4feb3..80da669 100644 --- a/GoAwayEdge/App.xaml.cs +++ b/GoAwayEdge/App.xaml.cs @@ -47,11 +47,11 @@ public void Application_Startup(object sender, StartupEventArgs e) case 1 when args.Contains("--debug"): { if (args.Contains("--debug")) - IsDebug = true; + IsDebug = true; if (IsAdministrator() == false) { ElevateAsAdmin(); - Environment.Exit(0); + Environment.Exit(740); return; } @@ -71,7 +71,7 @@ public void Application_Startup(object sender, StartupEventArgs e) if (IsAdministrator() == false) { ElevateAsAdmin(string.Join(" ", args)); - Environment.Exit(0); + Environment.Exit(740); return; } @@ -79,7 +79,7 @@ public void Application_Startup(object sender, StartupEventArgs e) if (RegistryConfig.GetKey("ControlPanelIsInstalled") != "True") { Logging.Log("Control Panel is not allowed on this system, exiting ...", Logging.LogLevel.ERROR); - Environment.Exit(0); + Environment.Exit(1); return; } @@ -111,6 +111,8 @@ public void Application_Startup(object sender, StartupEventArgs e) if (args.Contains("-s")) // Silent Installation { + Configuration.InitialEnvironment(); + foreach (var arg in args) { if (arg.StartsWith("-e:")) @@ -146,13 +148,12 @@ public void Application_Startup(object sender, StartupEventArgs e) if (IsAdministrator() == false) { - ElevateAsAdmin(string.Join(" ", args)); - Environment.Exit(0); + var elevatedProcess = ElevateAndWait(string.Join(" ", args)); + Environment.Exit(elevatedProcess); return; } Configuration.InstallControlPanel = true; - Configuration.InitialEnvironment(); var result = InstallRoutine.Install(null); Environment.Exit(result); } @@ -160,8 +161,8 @@ public void Application_Startup(object sender, StartupEventArgs e) { if (IsAdministrator() == false) { - ElevateAsAdmin(string.Join(" ", args)); - Environment.Exit(0); + var elevatedProcess = ElevateAndWait(string.Join(" ", args)); + Environment.Exit(elevatedProcess); return; } var result = InstallRoutine.Uninstall(null); @@ -236,7 +237,10 @@ public void Application_Startup(object sender, StartupEventArgs e) ifeoMessageUi.ShowDialog(); if (ifeoMessageUi.Summary == "Btn1") + { ElevateAsAdmin("--update"); + Environment.Exit(740); + } Environment.Exit(0); } @@ -269,6 +273,24 @@ private static void ElevateAsAdmin(string? arguments = null) Process.Start(startInfo); } + private static int ElevateAndWait(string? arguments = null) + { + // Restart program and run as admin + var exeName = Process.GetCurrentProcess().MainModule?.FileName; + if (exeName == null) return -1; + var startInfo = new ProcessStartInfo(exeName) + { + Verb = "runas", + UseShellExecute = true, + Arguments = arguments + }; + var p = new Process(); + p.StartInfo = startInfo; + p.Start(); + p.WaitForExit(); + return p.ExitCode; + } + private static string? ParseCustomUrl(string argument, int count) { var argParsed = argument.Remove(0, count); diff --git a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user index 6e07314..24cbb46 100644 --- a/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/GoAwayEdge/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-12-26T14:22:32.4690057Z||;True|2024-12-26T15:09:04.1027404+01:00||;True|2024-12-26T15:03:19.0005711+01:00||;True|2024-12-25T17:22:09.8471194+01:00||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; + True|2024-12-26T17:33:52.9873568Z||;True|2024-12-26T18:31:07.1677995+01:00||;True|2024-12-26T17:03:19.1985996+01:00||;True|2024-12-26T16:24:41.8789667+01:00||;True|2024-12-26T15:22:32.4690057+01:00||;True|2024-12-26T15:09:04.1027404+01:00||;True|2024-12-26T15:03:19.0005711+01:00||;True|2024-12-25T17:22:09.8471194+01:00||;True|2024-08-13T19:39:30.3814052+02:00||;True|2024-08-13T19:35:07.3638159+02:00||;True|2024-08-13T01:10:27.4137217+02:00||;True|2024-08-13T01:06:17.9215774+02:00||;True|2024-08-13T00:56:54.4657665+02:00||;True|2024-08-13T00:49:21.1156303+02:00||;True|2024-08-13T00:45:56.3970427+02:00||;True|2024-08-13T00:25:23.5481220+02:00||;True|2024-08-12T22:11:19.4188626+02:00||;True|2024-08-12T22:10:38.2923046+02:00||;True|2024-08-12T22:08:45.6517147+02:00||;True|2024-07-30T00:22:22.2984409+02:00||;True|2024-07-30T00:18:17.4366719+02:00||;True|2024-07-30T00:17:49.8084336+02:00||;True|2024-07-22T18:41:59.8117684+02:00||;True|2024-06-18T00:28:22.3138517+02:00||;True|2024-06-18T00:16:46.9788815+02:00||;True|2024-06-09T20:14:23.6305404+02:00||;True|2024-06-09T19:02:49.2570274+02:00||;True|2024-06-09T18:47:29.9573023+02:00||;True|2024-06-09T18:46:39.8011527+02:00||;False|2024-06-09T18:46:05.6633541+02:00||;False|2024-06-09T18:45:59.2563619+02:00||;True|2024-02-18T17:16:27.0408261+01:00||;True|2024-02-18T17:15:41.3961034+01:00||;True|2024-02-18T17:11:58.7761728+01:00||;True|2024-02-18T17:08:57.9390623+01:00||;True|2024-02-18T17:08:26.6377454+01:00||;True|2024-02-18T17:07:45.2050537+01:00||;True|2024-02-18T17:05:12.7495146+01:00||;True|2024-02-18T17:02:32.4549017+01:00||;True|2024-02-18T16:48:25.3074382+01:00||;True|2023-10-19T00:00:28.0962969+02:00||;True|2022-11-13T02:33:03.7406004+01:00||;True|2022-11-13T02:19:07.9073988+01:00||;True|2022-11-13T02:18:35.3043045+01:00||;True|2022-11-12T20:05:07.6366825+01:00||;False|2022-11-12T20:04:52.3576134+01:00||;True|2022-11-12T19:36:12.8480978+01:00||; \ No newline at end of file