Description
Description
I need to remotely administer an IIS server, and Microsoft.Web.Administration is a long-standing solution which manages this via remote COM APIs.
The latest versions of Microsoft.Web.Administration ships for .NET Standard, but these builds have the remote-administration code compiled out, and instead just throw a NullReferenceException
from ServerManager.OpenRemote
.
The older version 7.0 of Microsoft.Web.Administration only ships for .NET Framework 2.0, but it works on .NET 8 if we supply System.Security.Permissions as well via NuGet.
However, the .NET 8 runtime fails to load System.Security.Permissions when operating inside of another AssemblyLoadContext. It only seems to succeed if the entrypoint project is what takes on the package references.
When debugging this the runtime does not even ask for System.Security.Permissions.dll. I cannot find anything from a dotnet-trace
to explain why it is failing, and procmon64 suggests that the .NET Runtime does not even look for the file on disk, it just aborts early with an exception.
Reproduction Steps
On a Windows machine with IIS and the .NET 8 SDK installed:
- Clone https://github.com/yaakov-h/dotnet-repro-remote-webadmin
- Create the folder 'bin'
cd bin
.\repro.ps1
from PowerShell as Administrator (elevated)
Expected behavior
The script displays success in all 5 scenarios:
- Initial build, loading using Assembly.Load
- Initial build, loading using AssemblyLoadContext
- Rebuild with additional reference, loading using Assembly.Load
- Rebuild with additional reference, loading using AssemblyLoadContext
- Rebuild with additional reference, loading using Type.GetType()
Actual behavior
The first two scenarios fail, the final three pass:
PS> .\repro.ps1
Building project...
Determining projects to restore...
Restored C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\PluginHost\PluginHost.csproj (in 70 ms).
2 of 3 projects are up-to-date for restore.
PluginInterfaces -> C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\PluginInterfaces.dll
RemoteWebAdministrationPlugin -> C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\plugins\RemoteWebAdministrationPlugin.dll
PluginHost -> C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\PluginHost.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.84
Running with Assembly.Load...
AppDomain.CurrentDomain.AssemblyResolve: Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
AppDomain.CurrentDomain.AssemblyResolve: System.Security.Permissions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'System.Security.Permissions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
File name: 'System.Security.Permissions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
at Microsoft.Web.Administration.Configuration.CheckPermissions(IAppHostElement section)
at Microsoft.Web.Administration.Configuration.GetSectionInternal(ConfigurationSection section, String sectionPath, String locationPath)
at Microsoft.Web.Administration.Configuration.GetSection(String sectionPath)
at Microsoft.Web.Administration.ServerManager.get_SitesSection()
at Microsoft.Web.Administration.ServerManager.get_Sites()
at RemoteWebAdministrationPlugin.ListRemoteIisSitesPlugin.DoSomething(String[] args) in C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\RemoteWebAdministrationPlugin\ListRemoteIisSitesPlugin.cs:line 19
at Program.<Main>$(String[] args) in C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\PluginHost\Program.cs:line 53
Running with AssemblyLoadContext...
PluginLoadContext.Load: Loading RemoteWebAdministrationPlugin from C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\plugins\RemoteWebAdministrationPlugin.dll
PluginLoadContext.Load: System.Runtime failed to resolve to path
PluginLoadContext.Load: PluginInterfaces loading from default context.
PluginLoadContext.Load: Loading Microsoft.Web.Administration from C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\plugins\Microsoft.Web.Administration.dll
PluginLoadContext.Load: mscorlib failed to resolve to path
PluginLoadContext.Load: System.Console failed to resolve to path
PluginLoadContext.Load: System failed to resolve to path
PluginLoadContext.LoadUnmanagedDll: ole32.dll failed to resolve to path
PluginLoadContext.Load: System.Configuration failed to resolve to path
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'System.Security.Permissions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
File name: 'System.Security.Permissions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
at Microsoft.Web.Administration.Configuration.CheckPermissions(IAppHostElement section)
at Microsoft.Web.Administration.Configuration.GetSectionInternal(ConfigurationSection section, String sectionPath, String locationPath)
at Microsoft.Web.Administration.Configuration.GetSection(String sectionPath)
at Microsoft.Web.Administration.ServerManager.get_SitesSection()
at Microsoft.Web.Administration.ServerManager.get_Sites()
at RemoteWebAdministrationPlugin.ListRemoteIisSitesPlugin.DoSomething(String[] args) in C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\RemoteWebAdministrationPlugin\ListRemoteIisSitesPlugin.cs:line 19
at Program.<Main>$(String[] args) in C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\PluginHost\Program.cs:line 53
Rebuilding project with ProjectReference...
Determining projects to restore...
Restored C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\PluginHost\PluginHost.csproj (in 201 ms).
2 of 3 projects are up-to-date for restore.
PluginInterfaces -> C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\PluginInterfaces.dll
RemoteWebAdministrationPlugin -> C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\plugins\RemoteWebAdministrationPlugin.dll
PluginHost -> C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\PluginHost.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.97
Running with Assembly.Load...
Server '5FKTZT3' has 5 sites hosted in IIS.
Running with AssemblyLoadContext...
PluginLoadContext.Load: Loading RemoteWebAdministrationPlugin from C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\plugins\RemoteWebAdministrationPlugin.dll
PluginLoadContext.Load: System.Runtime failed to resolve to path
PluginLoadContext.Load: PluginInterfaces loading from default context.
PluginLoadContext.Load: Loading Microsoft.Web.Administration from C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\bin\plugins\Microsoft.Web.Administration.dll
PluginLoadContext.Load: mscorlib failed to resolve to path
PluginLoadContext.Load: System.Console failed to resolve to path
PluginLoadContext.Load: System failed to resolve to path
PluginLoadContext.LoadUnmanagedDll: ole32.dll failed to resolve to path
PluginLoadContext.Load: System.Configuration failed to resolve to path
Server '5FKTZT3' has 5 sites hosted in IIS.
Running with direct Type.GetType...
Server '5FKTZT3' has 5 sites hosted in IIS.
Regression?
This worked using Assembly.Load in .NET Framework. likely due to System.Security.Permissions being part of the BCL.
Known Workarounds
Adding a direct reference from the plugin host to the plugin project seems to work as a workaround, though I have absolutely no idea why. This is also not a viable permanent/long term workaround, more of a strange oddity discovered whilst trying to reproduce the issue.
Additionally, using AppDomain.CurrentDomain.AssemblyResolve
hook as shown here appears to be a workaround, but this seems to break the purpose and spirit of using AssemblyLoadContext
.
Configuration
dotnet --info
:
.NET SDK:
Version: 8.0.300
Commit: 326f6e68b2
Workload version: 8.0.300-manifests.9e3391ed
MSBuild version: 17.10.4+10fbfbf2e
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.300\
.NET workloads installed:
[maui-windows]
Installation Source: VS 17.10.34916.146
Manifest Version: 8.0.21/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.21\WorkloadManifest.json
Install Type: Msi
[ios]
Installation Source: VS 17.10.34916.146
Manifest Version: 17.2.8053/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\17.2.8053\WorkloadManifest.json
Install Type: Msi
[maccatalyst]
Installation Source: VS 17.10.34916.146
Manifest Version: 17.2.8053/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\17.2.8053\WorkloadManifest.json
Install Type: Msi
[aspire]
Installation Source: VS 17.10.34916.146
Manifest Version: 8.0.0/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.0.0\WorkloadManifest.json
Install Type: Msi
[android]
Installation Source: VS 17.10.34916.146
Manifest Version: 34.0.95/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.95\WorkloadManifest.json
Install Type: Msi
Host:
Version: 9.0.0-preview.5.24306.7
Architecture: x64
Commit: a5cc707d97
.NET SDKs installed:
6.0.321 [C:\Program Files\dotnet\sdk]
6.0.423 [C:\Program Files\dotnet\sdk]
7.0.120 [C:\Program Files\dotnet\sdk]
7.0.317 [C:\Program Files\dotnet\sdk]
7.0.410 [C:\Program Files\dotnet\sdk]
8.0.106 [C:\Program Files\dotnet\sdk]
8.0.300 [C:\Program Files\dotnet\sdk]
9.0.100-preview.5.24307.3 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.19 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.0-preview.5.24306.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.19 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.0-preview.5.24306.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.30 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.19 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.0-preview.5.24306.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
C:\git\GitHub\yaakov-h\dotnet-repro-remote-webadmin\global.json
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
N.B. this also fails on machines w/o .NET 9 previews.
Other information
No response
Metadata
Metadata
Assignees
Type
Projects
Status