Skip to content

Commit 888dcce

Browse files
finally
1 parent 7b22cf7 commit 888dcce

3 files changed

Lines changed: 86 additions & 29 deletions

File tree

private/assembly-loader.ps1

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,24 @@ function Initialize-DbatoolsAssemblyLoader {
6363
# Get platform information
6464
$platformDetails = Get-PlatformDetails
6565

66-
# Initialize the redirector for non-Core PowerShell
66+
# Reset resolver states
67+
$script:isResolving = $false
68+
$script:resolverInitialized = $false
69+
70+
# Initialize resolvers for non-Core PowerShell
6771
if ($PSVersionTable.PSEdition -ne 'Core') {
6872
try {
73+
# Initialize redirector first
6974
Initialize-DbatoolsAssemblyRedirector
75+
76+
# Then initialize resolution handler if redirector succeeded
77+
if ($script:dbatoolsRedirector) {
78+
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($script:onAssemblyResolveEventHandler)
79+
$script:resolverInitialized = $true
80+
}
7081
}
7182
catch {
72-
Write-Warning "Failed to initialize assembly redirector: $($_.Exception.Message)"
83+
Write-Warning "Failed to initialize assembly handlers: $($_.Exception.Message)"
7384
Write-Warning "This may cause issues with assembly loading in Windows PowerShell"
7485
}
7586
}
@@ -254,15 +265,24 @@ function Reset-DbatoolsAssemblyLoader {
254265

255266
# Remove assembly resolve handlers in non-Core PowerShell
256267
if ($PSVersionTable.PSEdition -ne 'Core') {
257-
# Remove standard handler
258-
if ($script:onAssemblyResolveEventHandler) {
259-
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($script:onAssemblyResolveEventHandler)
260-
}
268+
try {
269+
# Remove standard handler
270+
if ($script:onAssemblyResolveEventHandler -and $script:resolverInitialized) {
271+
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($script:onAssemblyResolveEventHandler)
272+
$script:resolverInitialized = $false
273+
}
274+
275+
# Remove redirector handler if it exists
276+
if ($script:dbatoolsRedirector) {
277+
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($script:dbatoolsRedirector.EventHandler)
278+
$script:dbatoolsRedirector = $null
279+
}
261280

262-
# Remove redirector handler if it exists
263-
if ($script:dbatoolsRedirector) {
264-
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($script:dbatoolsRedirector.EventHandler)
265-
$script:dbatoolsRedirector = $null
281+
# Reset resolver state
282+
$script:isResolving = $false
283+
}
284+
catch {
285+
Write-Warning "Error removing assembly handlers: $_"
266286
}
267287
}
268288

private/assembly-redirector.ps1

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ function Initialize-DbatoolsAssemblyRedirector {
88
$dir = [System.IO.Path]::Combine($script:libraryroot, "lib")
99
$dir = ("$dir\").Replace('\', '\\')
1010

11-
if (-not ("Redirector" -as [type])) {
11+
# Only create type if not already defined
12+
if (-not ("Redirector" -as [type]) -and $PSVersionTable.PSEdition -ne 'Core') {
1213
$source = @"
1314
using System;
1415
using System.Linq;
@@ -56,9 +57,25 @@ public class Redirector
5657
5758
public readonly ResolveEventHandler EventHandler;
5859
60+
private static bool isResolving = false;
61+
5962
protected Assembly AssemblyResolve(object sender, ResolveEventArgs e)
6063
{
64+
// Guard against empty assembly names
65+
if (e == null || string.IsNullOrEmpty(e.Name))
66+
{
67+
return null;
68+
}
6169
70+
// Prevent recursive resolution
71+
if (isResolving)
72+
{
73+
return null;
74+
}
75+
76+
isResolving = true;
77+
try
78+
{
6279
// Only track essential system dependencies
6380
string[] systemDlls = {
6481
"System.Memory",
@@ -164,7 +181,12 @@ public class Redirector
164181
}
165182
}
166183
}
167-
return null;
184+
return null;
185+
}
186+
finally
187+
{
188+
isResolving = false;
189+
}
168190
}
169191
}
170192
"@
@@ -179,16 +201,18 @@ public class Redirector
179201
}
180202
}
181203

182-
try {
183-
$redirector = New-Object Redirector
184-
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($redirector.EventHandler)
185-
186-
# Store the redirector instance in script scope for cleanup
187-
$script:dbatoolsRedirector = $redirector
188-
}
189-
catch {
190-
Write-Warning "Failed to initialize assembly redirector: $_"
191-
throw
204+
# Only initialize redirector for non-Core PowerShell if not already initialized
205+
if ($PSVersionTable.PSEdition -ne 'Core' -and -not $script:dbatoolsRedirector) {
206+
try {
207+
$redirector = New-Object Redirector
208+
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($redirector.EventHandler)
209+
# Store the redirector instance in script scope for cleanup
210+
$script:dbatoolsRedirector = $redirector
211+
}
212+
catch {
213+
Write-Warning "Failed to initialize assembly redirector: $_"
214+
throw
215+
}
192216
}
193217
}
194218

private/assembly-resolution.ps1

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,24 @@ function Get-DbatoolsAssemblyPath {
151151
}
152152

153153
# Assembly resolution event handler
154+
# Track resolution state to prevent recursion
155+
$script:isResolving = $false
156+
154157
$script:onAssemblyResolveEventHandler = [System.ResolveEventHandler] {
155158
param($sender, $args)
156159

157-
try {
158-
if (-not $args -or [string]::IsNullOrEmpty($args.Name)) {
159-
Write-Warning "Empty assembly name provided to resolver"
160-
return $null
161-
}
160+
# Guard against empty assembly names early
161+
if (-not $args -or [string]::IsNullOrEmpty($args.Name)) {
162+
return $null
163+
}
162164

165+
# Prevent recursive resolution
166+
if ($script:isResolving) {
167+
return $null
168+
}
169+
170+
$script:isResolving = $true
171+
try {
163172
# Parse assembly name
164173
$assemblyName = [System.Reflection.AssemblyName]::new($args.Name)
165174
if ([string]::IsNullOrEmpty($assemblyName.Name)) {
@@ -196,11 +205,15 @@ $script:onAssemblyResolveEventHandler = [System.ResolveEventHandler] {
196205
Write-Warning "Error resolving assembly $($args.Name): $_"
197206
return $null
198207
}
208+
finally {
209+
$script:isResolving = $false
210+
}
199211
}
200212

201-
# Initialize assembly resolution for non-Core PowerShell
202-
if ($PSVersionTable.PSEdition -ne 'Core') {
213+
# Initialize assembly resolution for non-Core PowerShell if not already initialized
214+
if ($PSVersionTable.PSEdition -ne 'Core' -and -not $script:resolverInitialized) {
203215
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($script:onAssemblyResolveEventHandler)
216+
$script:resolverInitialized = $true
204217
}
205218

206219
Export-ModuleMember -Function Get-DbatoolsPlatformInfo, Get-DbatoolsAssemblyPath

0 commit comments

Comments
 (0)