diff --git a/src/modules/Hosts/Hosts/Helpers/HostsService.cs b/src/modules/Hosts/Hosts/Helpers/HostsService.cs index e7b6eb1ca9..2e117446ad 100644 --- a/src/modules/Hosts/Hosts/Helpers/HostsService.cs +++ b/src/modules/Hosts/Hosts/Helpers/HostsService.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Abstractions; @@ -14,6 +15,7 @@ using System.Threading; using System.Threading.Tasks; using Hosts.Models; using Hosts.Settings; +using Microsoft.Win32; using Settings.UI.Library.Enumerations; namespace Hosts.Helpers @@ -210,6 +212,69 @@ namespace Hosts.Helpers .ForEach(f => f.Delete()); } + public void OpenHostsFile() + { + var notepadFallback = false; + + try + { + // Try to open in default editor + var key = Registry.ClassesRoot.OpenSubKey("SystemFileAssociations\\text\\shell\\edit\\command"); + if (key != null) + { + var commandPattern = key.GetValue(string.Empty).ToString(); // Default value + var file = null as string; + var args = null as string; + + if (commandPattern.StartsWith('\"')) + { + var endQuoteIndex = commandPattern.IndexOf('\"', 1); + if (endQuoteIndex != -1) + { + file = commandPattern[1..endQuoteIndex]; + args = commandPattern[(endQuoteIndex + 1)..].Trim(); + } + } + else + { + var spaceIndex = commandPattern.IndexOf(' '); + if (spaceIndex != -1) + { + file = commandPattern[..spaceIndex]; + args = commandPattern[(spaceIndex + 1)..].Trim(); + } + } + + if (file != null && args != null) + { + args = args.Replace("%1", HostsFilePath); + Process.Start(new ProcessStartInfo(file, args)); + } + else + { + notepadFallback = true; + } + } + } + catch (Exception ex) + { + Logger.LogError("Failed to open default editor", ex); + notepadFallback = true; + } + + if (notepadFallback) + { + try + { + Process.Start(new ProcessStartInfo("notepad.exe", HostsFilePath)); + } + catch (Exception ex) + { + Logger.LogError("Failed to open notepad", ex); + } + } + } + public void Dispose() { Dispose(disposing: true); diff --git a/src/modules/Hosts/Hosts/Helpers/IHostsService.cs b/src/modules/Hosts/Hosts/Helpers/IHostsService.cs index 06e1c6017a..06ef700914 100644 --- a/src/modules/Hosts/Hosts/Helpers/IHostsService.cs +++ b/src/modules/Hosts/Hosts/Helpers/IHostsService.cs @@ -22,5 +22,7 @@ namespace Hosts.Helpers Task PingAsync(string address); void CleanupBackup(); + + void OpenHostsFile(); } } diff --git a/src/modules/Hosts/Hosts/Strings/en-us/Resources.resw b/src/modules/Hosts/Hosts/Strings/en-us/Resources.resw index 5a057a99ce..58c015a923 100644 --- a/src/modules/Hosts/Hosts/Strings/en-us/Resources.resw +++ b/src/modules/Hosts/Hosts/Strings/en-us/Resources.resw @@ -222,6 +222,14 @@ Move up + + Open hosts file + "Hosts" refers to the system hosts file, do not loc + + + Open hosts file + "Hosts" refers to the system hosts file, do not loc + Ping "Ping" refers to the command-line utility, do not loc diff --git a/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs b/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs index 6b59ab4779..8f8734dd9b 100644 --- a/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs +++ b/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs @@ -97,6 +97,8 @@ namespace Hosts.ViewModels public ICommand OpenSettingsCommand => new RelayCommand(OpenSettings); + public ICommand OpenHostsFileCommand => new RelayCommand(OpenHostsFile); + public MainViewModel( IHostsService hostService, IUserSettings userSettings) @@ -197,6 +199,11 @@ namespace Hosts.ViewModels SettingsDeepLink.OpenSettings(SettingsDeepLink.SettingsWindow.Hosts); } + public void OpenHostsFile() + { + _hostsService.OpenHostsFile(); + } + public void Dispose() { Dispose(disposing: true); diff --git a/src/modules/Hosts/Hosts/Views/MainPage.xaml b/src/modules/Hosts/Hosts/Views/MainPage.xaml index 62be63e1c8..090000b9f8 100644 --- a/src/modules/Hosts/Hosts/Views/MainPage.xaml +++ b/src/modules/Hosts/Hosts/Views/MainPage.xaml @@ -124,7 +124,18 @@ - + + +