Skip to content

Commit cc05937

Browse files
BornToBeRootclaude
andcommitted
Fix: Neighbor Table runspace cached after a failed start
A failed start of the PowerShell runspace (e.g. Import-Module NetTCPIP) was cached by Lazy<T> until the application was restarted. Create it on demand inside the existing RunspaceLock and recreate it if it is not open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 96cadc2 commit cc05937

2 files changed

Lines changed: 42 additions & 13 deletions

File tree

‎Source/NETworkManager.Models/Network/NeighborTable.cs‎

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,26 +93,51 @@ private struct MIB_IPNET_ROW2
9393
private static readonly TimeSpan InterfaceAliasCacheDuration = TimeSpan.FromMinutes(5);
9494

9595
/// <summary>
96-
/// Lazily initialized PowerShell runspace. Created and configured on first access so that
97-
/// read-only paths (e.g. MAC address lookup in IP Scanner) do not start a PowerShell
98-
/// process unless a modifying operation is actually performed.
96+
/// Shared PowerShell runspace, see <see cref="SharedRunspace"/>.
9997
/// </summary>
100-
private static readonly Lazy<Runspace> _sharedRunspace = new(() =>
98+
private static Runspace _sharedRunspace;
99+
100+
/// <summary>
101+
/// Returns the shared runspace. It is created and configured on first access, so that read-only paths
102+
/// (e.g. MAC address lookup in IP Scanner) do not start a PowerShell process unless a modifying operation
103+
/// is actually performed. If the runspace could not be created (e.g. the <c>NetTCPIP</c> module failed to load)
104+
/// or is broken, it is created again on the next access, so a temporary error doesn't break adding / deleting
105+
/// entries until the application is restarted.
106+
/// Must only be accessed while <see cref="RunspaceLock"/> is held.
107+
/// </summary>
108+
private static Runspace SharedRunspace
101109
{
102-
var runspace = RunspaceFactory.CreateRunspace();
103-
runspace.Open();
110+
get
111+
{
112+
if (_sharedRunspace?.RunspaceStateInfo.State == RunspaceState.Opened)
113+
return _sharedRunspace;
104114

105-
using var ps = SMA.PowerShell.Create();
106-
ps.Runspace = runspace;
107-
ps.AddScript(@"
115+
_sharedRunspace?.Dispose();
116+
_sharedRunspace = null;
117+
118+
var runspace = RunspaceFactory.CreateRunspace();
119+
120+
try
121+
{
122+
runspace.Open();
123+
124+
using var ps = SMA.PowerShell.Create();
125+
ps.Runspace = runspace;
126+
ps.AddScript(@"
108127
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
109128
Import-Module NetTCPIP -ErrorAction Stop").Invoke();
129+
}
130+
catch
131+
{
132+
runspace.Dispose();
133+
throw;
134+
}
110135

111-
return runspace;
112-
});
136+
_sharedRunspace = runspace;
113137

114-
/// <summary>Returns the shared runspace, initializing it on first access.</summary>
115-
private static Runspace SharedRunspace => _sharedRunspace.Value;
138+
return runspace;
139+
}
140+
}
116141

117142
#endregion
118143

‎Website/docs/changelog/next-release.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ Release date: **xx.xx.2026**
115115

116116
- Fixed errors when changing the network configuration (e.g. missing permissions) not being shown — the change was reported as successful although it failed. The error message of Windows is now shown. [#3606](https://github.com/BornToBeRoot/NETworkManager/issues/3606)
117117

118+
**Neighbor Table**
119+
120+
- Fixed adding and deleting entries not working until the application was restarted if loading the PowerShell module `NetTCPIP` failed once.
121+
118122
**Dashboard**
119123

120124
- Fixed the **Network Connection** widget running a full connection check on every application startup, even if the Status Window or Dashboard was never opened. It now only checks when actually shown - via the tray icon, on a network change, or when the Dashboard tab is opened. [#3553](https://github.com/BornToBeRoot/NETworkManager/pull/3553)

0 commit comments

Comments
 (0)