You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[6.0.100-alpha.1.21064.42] Replychsharp get error CS0009: Metadata file 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0-alpha.1.21063.13\System.IO.Compression.Native.dll' could not be opened #47029
Download app source above and 'cd replay-csharp\Replay'
dotnet run
Type “Console.Write("hellow world")” in app window, and click Enter.
Expected Result:
print "hello world"
Actual Result:
error CS0009: Metadata file 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0-alpha.1.21063.13\System.IO.Compression.Native.dll' could not be opened -- PE image doesn't contain managed metadata.
Findings:
When debugging the source code in Visual Studio 2019, below logs print in Output window.
'Replay.exe' (CoreCLR: clrhost): Loaded 'C:\.NETCoreUpgradeApps\replay-csharp\Replay\bin\Debug\netcoreapp3.1\win-x64\System.Globalization.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Replay.exe' (CoreCLR: clrhost): Loaded 'C:\.NETCoreUpgradeApps\replay-csharp\Replay\bin\Debug\netcoreapp3.1\win-x64\System.AppContext.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Exception thrown: 'Microsoft.CodeAnalysis.Scripting.CompilationErrorException' in Microsoft.CodeAnalysis.Scripting.dll
changed the title [-][dotnet-sdk-6.0.100-alpha.1.21064.42] Replychsharp get error CS0009: Metadata file 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0-alpha.1.21063.13\System.IO.Compression.Native.dll' could not be opened[/-][+][6.0.100-alpha.1.21064.42] Replychsharp get error CS0009: Metadata file 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0-alpha.1.21063.13\System.IO.Compression.Native.dll' could not be opened[/+]on Jan 15, 2021
public MetadataReference[] GetDefaultAssemblies()
{
var installation = dotNetInstallationLocator.GetReferenceAssemblyPath() ?? throw new InvalidOperationException("Could not find dotnet installation");
// get SDK DLLs
var implementationPath = Path.Combine(installation.BasePath, "shared", "Microsoft.NETCore.App", installation.Version);
// get xml documentation for those DLLs
var latestRef = io
.GetDirectories(
Path.Combine(installation.BasePath, "packs", "Microsoft.NETCore.App.Ref")
)
.Last();
var referencePath = Path.Combine(latestRef, "ref");
return GroupDirectoryContentsIntoAssemblies(
io.GetFilesInDirectory(implementationPath, "*.dll", SearchOption.AllDirectories)
.Union(io.GetFilesInDirectory(referencePath, "*.xml", SearchOption.AllDirectories))
)
.Where(assembly => assembly.AssemblyName.StartsWith("System"))
.Select(assembly => io.CreateMetadataReferenceWithDocumentation(assembly))
.ToArray();
}
It "noticed" that the dll name changed from clrcompression.dll to System.IO.Compression.Native.dll which was done by @VSadov in 99f3f55 (#45713).
What this app is doing is incorrect. It's examining the .NETCore installation directory and using implementation assemblies for compilation. It assumes everything that starts with "System.*" will be managed assembly.
It looks like it already understands where the reference assemblies live. It should just use those for compilation.
@ericstj Hi, appreciate you taking a look into this. I'm sure the app is at fault here, rather than the runtime. As background, the app is a REPL for C#, and heavily uses the Roslyn APIs.
It ultimately needs the assemblies to pass into the following two Roslyn APIs:
The Roslyn ScriptOptions - Runtime evaluation with the Roslyn Scripting APIs (e.g. CSharpScript). This drives the core of the REPL evaluation.
The Roslyn ProjectInfo, for use with Roslyn Workspaces. This drives all the syntax highlighting, code completion, method documentation, and miscellaneous other services that require workspaces / projects.
I initially tried using the reference assemblies, and while that worked for the workspace APIs (item 2, above), it did not work for the scripting APIs (item 1, above). It failed with the error: Predefined type 'System.Object' is not defined or imported even without the System prefix filtering. The only way I was able to get the scripting API to work was by using the implementation assemblies.
I'm sure there's a better way to do this, but I was mostly figuring this out by trial and error.
@ericstj Can we confirm this issue as app issue but not a product issue?
Yes this is an app issue. The app is attempting to load all files in the framework directory and failed because we added a native binary that matched it's pattern. The app should be changed to handle this exception at the very least.
I initially tried using the reference assemblies, and while that worked for the workspace APIs (item 2, above), it did not work for the scripting APIs (item 1, above). It failed with the error: Predefined type 'System.Object' is not defined or imported even without the System prefix filtering. The only way I was able to get the scripting API to work was by using the implementation assemblies.
@ericstj No there is not. I'm not sure why the app is loading all framework assemblies instead of using #r directive to reference assemblies they want to reference by name and have Roslyn's assembly loader to resolve the name correctly.
The reason for using ScriptOptions.WithReferences was to ensure that both the CSharpScript instance and the Workspace instance had the exact same references; they need to be identical so services like code completion match what's evaluated in the script. I believe this is a constraint that any REPL (e.g. csi) would need to follow.
I'll take a look at using Roslyn's assembly loader, thanks for the suggestion! Is the idea that ScriptOptions.WithReferences should only be used for third-party assemblies?
@waf Hosting REPL and providing IDE services for it is non-trivial. We do not have good APIs that you could use out of the box. Our plan for future is to provide LSP server that provides IDE services that you could connect to. But we do not have that yet.
Understood, and thanks for the links. This has always been more of research side-project for me. I'll update my app to account for these changes in .NET 6.
@ericstj@waf Thanks for confirmation, as this is an app issue, we will close the ticket here.
Instead I created a bug to the app repo: waf/replay-csharp#3
Activity
[-][dotnet-sdk-6.0.100-alpha.1.21064.42] Replychsharp get error CS0009: Metadata file 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0-alpha.1.21063.13\System.IO.Compression.Native.dll' could not be opened[/-][+][6.0.100-alpha.1.21064.42] Replychsharp get error CS0009: Metadata file 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0-alpha.1.21063.13\System.IO.Compression.Native.dll' could not be opened[/+]ericstj commentedon Jan 15, 2021
This app is doing the following:
It "noticed" that the dll name changed from clrcompression.dll to System.IO.Compression.Native.dll which was done by @VSadov in 99f3f55 (#45713).
What this app is doing is incorrect. It's examining the .NETCore installation directory and using implementation assemblies for compilation. It assumes everything that starts with "System.*" will be managed assembly.
It looks like it already understands where the reference assemblies live. It should just use those for compilation.
@waf it looks like this is your project. https://github.com/waf/replay-csharp/blob/e433ad0da9c637d44ebe79ef13b25a3a89b27c35/Replay.Services/AssemblyLoading/DotNetAssemblyLocator.cs#L20
Is there any reason you have to use implementation assemblies here?
waf commentedon Jan 16, 2021
@ericstj Hi, appreciate you taking a look into this. I'm sure the app is at fault here, rather than the runtime. As background, the app is a REPL for C#, and heavily uses the Roslyn APIs.
It ultimately needs the assemblies to pass into the following two Roslyn APIs:
ScriptOptions- Runtime evaluation with the Roslyn Scripting APIs (e.g.CSharpScript). This drives the core of the REPL evaluation.ProjectInfo, for use with Roslyn Workspaces. This drives all the syntax highlighting, code completion, method documentation, and miscellaneous other services that require workspaces / projects.I initially tried using the reference assemblies, and while that worked for the workspace APIs (item 2, above), it did not work for the scripting APIs (item 1, above). It failed with the error:
Predefined type 'System.Object' is not defined or importedeven without theSystemprefix filtering. The only way I was able to get the scripting API to work was by using the implementation assemblies.I'm sure there's a better way to do this, but I was mostly figuring this out by trial and error.
jiangzeng01 commentedon Jan 18, 2021
@ericstj Can we confirm this issue as app issue but not a product issue?
ericstj commentedon Jan 19, 2021
Yes this is an app issue. The app is attempting to load all files in the framework directory and failed because we added a native binary that matched it's pattern. The app should be changed to handle this exception at the very least.
@jaredpar @tmat do you know if there is a way to use Roslyn scripting APIs against reference assemblies? I checked https://github.com/dotnet/roslyn/blob/afd10305a37c0ffb2cfb2c2d8446154c68cfa87a/docs/wiki/Scripting-API-Samples.md and couldn't find any example.
tmat commentedon Jan 19, 2021
@ericstj No there is not. I'm not sure why the app is loading all framework assemblies instead of using
#rdirective to reference assemblies they want to reference by name and have Roslyn's assembly loader to resolve the name correctly.waf commentedon Jan 20, 2021
The reason for using
ScriptOptions.WithReferenceswas to ensure that both the CSharpScript instance and the Workspace instance had the exact same references; they need to be identical so services like code completion match what's evaluated in the script. I believe this is a constraint that any REPL (e.g. csi) would need to follow.I'll take a look at using Roslyn's assembly loader, thanks for the suggestion! Is the idea that
ScriptOptions.WithReferencesshould only be used for third-party assemblies?tmat commentedon Jan 20, 2021
@waf Hosting REPL and providing IDE services for it is non-trivial. We do not have good APIs that you could use out of the box. Our plan for future is to provide LSP server that provides IDE services that you could connect to. But we do not have that yet.
Relevant sources in Roslyn:
http://sourceroslyn.io/#Microsoft.CodeAnalysis.Scripting/Hosting/Resolvers/RuntimeMetadataReferenceResolver.cs
http://sourceroslyn.io/#Microsoft.CodeAnalysis.InteractiveHost/Interactive/Core/InteractiveHost.cs
https://github.com/dotnet/roslyn/blob/ab5cee40ada204ea6975c43349ffba119905dd09/src/EditorFeatures/Core/Implementation/Interactive/InteractiveWorkspace.cs
waf commentedon Jan 20, 2021
Understood, and thanks for the links. This has always been more of research side-project for me. I'll update my app to account for these changes in .NET 6.
jiangzeng01 commentedon Jan 20, 2021
@ericstj @waf Thanks for confirmation, as this is an app issue, we will close the ticket here.
Instead I created a bug to the app repo: waf/replay-csharp#3