Skip to content

Commit a144800

Browse files
committed
Feature: Open Hosts File Editor
1 parent 70b404e commit a144800

6 files changed

Lines changed: 86 additions & 24 deletions

File tree

Source/NETworkManager.Localization/Resources/Strings.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/NETworkManager.Localization/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3802,6 +3802,9 @@ Right-click for more options.</value>
38023802
<data name="HostsFileEditorAdminMessage" xml:space="preserve">
38033803
<value>Read-only mode. Modifying the hosts file requires elevated rights!</value>
38043804
</data>
3805+
<data name="OpenHostsFile" xml:space="preserve">
3806+
<value>Open hosts file</value>
3807+
</data>
38053808
<data name="Comment" xml:space="preserve">
38063809
<value>Comment</value>
38073810
</data>

Source/NETworkManager.Models/HostsFileEditor/HostsFileEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ private static void OnHostsFileChanged()
3737
/// <summary>
3838
/// Path to the hosts file.
3939
/// </summary>
40-
private static string HostsFilePath => Path.Combine(HostsFolderPath, "hosts");
40+
public static string HostsFilePath => Path.Combine(HostsFolderPath, "hosts");
4141

4242
/// <summary>
4343
/// Identifier for the hosts file backup.

Source/NETworkManager/ViewModels/HostsFileEditorViewModel.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,28 @@ await DialogHelper.ShowMessageAsync(Application.Current.MainWindow, Strings.Erro
530530
}
531531
}
532532

533+
/// <summary>
534+
/// Gets the command to open the hosts file with the system default editor.
535+
/// </summary>
536+
public ICommand OpenHostsFileCommand => new RelayCommand(_ => OpenHostsFileAction().ConfigureAwait(false));
537+
538+
/// <summary>
539+
/// Opens the hosts file with the system default editor.
540+
/// Shows an error dialog if the process cannot be started.
541+
/// </summary>
542+
private async Task OpenHostsFileAction()
543+
{
544+
try
545+
{
546+
ExternalProcessStarter.RunProcess(HostsFileEditor.HostsFilePath);
547+
}
548+
catch (Exception ex)
549+
{
550+
await DialogHelper.ShowMessageAsync(Application.Current.MainWindow, Strings.Error, ex.Message,
551+
ChildWindowIcon.Error);
552+
}
553+
}
554+
533555
#endregion
534556

535557
#region Methods

Source/NETworkManager/Views/HostsFileEditorView.xaml

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
<RowDefinition Height="10" />
3131
<RowDefinition Height="*" />
3232
<RowDefinition Height="10" />
33-
<RowDefinition Height="Auto" />
33+
<RowDefinition Height="Auto" />
34+
<RowDefinition Height="10" />
35+
<RowDefinition Height="Auto" />
3436
<RowDefinition Height="Auto" />
3537
</Grid.RowDefinitions>
3638
<!-- Row 0: Header + Refresh + Search -->
@@ -213,30 +215,52 @@
213215
<KeyBinding Command="{Binding DeleteEntryCommand}" Key="Delete" />
214216
</controls:MultiSelectDataGrid.InputBindings>
215217
</controls:MultiSelectDataGrid>
216-
<!-- Row 4: Status message + Add button -->
217-
<Grid Grid.Column="0" Grid.Row="4">
218+
<!-- Row 4: Status message -->
219+
<WrapPanel Grid.Row="4"
220+
Orientation="Horizontal"
221+
VerticalAlignment="Center"
222+
HorizontalAlignment="Left">
223+
<networkManager:LoadingIndicator IsActive="True"
224+
Style="{DynamicResource ResourceKey=LoadingIndicatorPulseStyle}"
225+
Visibility="{Binding Path=IsRefreshing, Converter={StaticResource ResourceKey=BooleanToVisibilityCollapsedConverter}}"
226+
Width="24" Height="24"
227+
SpeedRatio="1"
228+
Margin="0,0,10,0" />
229+
<TextBlock Style="{StaticResource ResourceKey=AccentTextBlock}"
230+
Visibility="{Binding Path=IsStatusMessageDisplayed, Converter={StaticResource ResourceKey=BooleanToVisibilityCollapsedConverter}}"
231+
Text="{Binding Path=StatusMessage}"
232+
VerticalAlignment="Center" />
233+
</WrapPanel>
234+
<!-- Row 6: Open hosts file button (left) + Add entry button (right) -->
235+
<Grid Grid.Row="6">
218236
<Grid.ColumnDefinitions>
219-
<ColumnDefinition Width="*" />
220-
<ColumnDefinition Width="10" />
221237
<ColumnDefinition Width="Auto" />
238+
<ColumnDefinition Width="10" />
239+
<ColumnDefinition Width="*" />
222240
</Grid.ColumnDefinitions>
223-
<WrapPanel Grid.Column="0" Grid.Row="0"
241+
<WrapPanel Grid.Column="0"
224242
Orientation="Horizontal"
225-
VerticalAlignment="Bottom"
243+
VerticalAlignment="Center"
226244
HorizontalAlignment="Left">
227-
<networkManager:LoadingIndicator IsActive="True"
228-
Style="{DynamicResource ResourceKey=LoadingIndicatorPulseStyle}"
229-
Visibility="{Binding Path=IsRefreshing, Converter={StaticResource ResourceKey=BooleanToVisibilityCollapsedConverter}}"
230-
Width="24" Height="24"
231-
SpeedRatio="1"
232-
Margin="0,0,10,0" />
233-
<TextBlock Style="{StaticResource ResourceKey=AccentTextBlock}"
234-
Visibility="{Binding Path=IsStatusMessageDisplayed, Converter={StaticResource ResourceKey=BooleanToVisibilityCollapsedConverter}}"
235-
Text="{Binding Path=StatusMessage}"
236-
VerticalAlignment="Center" />
245+
<Button Command="{Binding OpenHostsFileCommand}" Style="{StaticResource ImageWithTextButton}">
246+
<Grid>
247+
<Grid.ColumnDefinitions>
248+
<ColumnDefinition Width="Auto" />
249+
<ColumnDefinition Width="*" />
250+
</Grid.ColumnDefinitions>
251+
<Rectangle Style="{StaticResource ButtonWithImageRectangle}">
252+
<Rectangle.OpacityMask>
253+
<VisualBrush Stretch="Uniform" Visual="{iconPacks:Material Kind=FileEditOutline}" />
254+
</Rectangle.OpacityMask>
255+
</Rectangle>
256+
<TextBlock Grid.Column="1"
257+
Text="{x:Static localization:Strings.OpenHostsFile}"
258+
Style="{StaticResource ButtonWithImageTextBlock}" />
259+
</Grid>
260+
</Button>
237261
</WrapPanel>
238-
<WrapPanel Grid.Column="2" Grid.Row="0"
239-
Orientation="Horizontal"
262+
<WrapPanel Grid.Column="2"
263+
Orientation="Horizontal"
240264
VerticalAlignment="Center"
241265
HorizontalAlignment="Right">
242266
<Button Command="{Binding AddEntryCommand}" Style="{StaticResource ImageWithTextButton}">
@@ -250,14 +274,14 @@
250274
<VisualBrush Stretch="Uniform" Visual="{iconPacks:Material Kind=Plus}" />
251275
</Rectangle.OpacityMask>
252276
</Rectangle>
253-
<TextBlock Grid.Column="1" Text="{x:Static localization:Strings.AddEntryDots}"
277+
<TextBlock Grid.Column="1" Text="{x:Static localization:Strings.AddEntryDots}"
254278
Style="{StaticResource ButtonWithImageTextBlock}" />
255279
</Grid>
256280
</Button>
257281
</WrapPanel>
258-
</Grid>
259-
<!-- Row 5: Admin note -->
260-
<Grid Grid.Column="0" Grid.Row="5"
282+
</Grid>
283+
<!-- Row 7: Admin note -->
284+
<Grid Grid.Column="0" Grid.Row="7"
261285
Background="{DynamicResource MahApps.Brushes.Gray10}"
262286
Visibility="{Binding Source={x:Static settings:ConfigurationManager.Current}, Path=IsAdmin, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}"
263287
Margin="0,10,0,0">

Website/docs/changelog/next-release.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ Release date: **xx.xx.2025**
5252
- Added support for `F5` and `Enter` keys to start capturing network packets. [#3383](https://github.com/BornToBeRoot/NETworkManager/pull/3383)
5353
- Redesigned the "restart as admin" note to be more compact and visually consistent. [#3383](https://github.com/BornToBeRoot/NETworkManager/pull/3383)
5454

55+
**Hosts File Editor**
56+
57+
- Button to open the hosts file in the default text editor added. [#3383](https://github.com/BornToBeRoot/NETworkManager/pull/3383)
58+
5559
## Bug Fixes
5660

5761
**Port Scanner**

0 commit comments

Comments
 (0)