diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs index 26c1a8a58..f66485585 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs @@ -36,6 +36,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler /// The information about the project being created. /// A collection of source files to be included into the project. /// The module being decompiled. - void Write(TextWriter target, IProjectInfoProvider project, IEnumerable files, PEFile module); + void Write(TextWriter target, IProjectInfoProvider project, IEnumerable files, MetadataFile module); } } diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs index eb383ba75..a536d72c7 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs @@ -45,10 +45,10 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler TextWriter target, IProjectInfoProvider project, IEnumerable files, - PEFile module) + MetadataFile module) { const string ns = "http://schemas.microsoft.com/developer/msbuild/2003"; - string platformName = TargetServices.GetPlatformName(module); + string platformName = module is PEFile peFile ? TargetServices.GetPlatformName(peFile) : "AnyCPU"; var targetFramework = TargetServices.DetectTargetFramework(module); if (targetFramework.Identifier == ".NETFramework" && targetFramework.VersionNumber == 200) targetFramework = TargetServices.DetectTargetFrameworkNET20(module, project.AssemblyResolver, targetFramework); @@ -80,26 +80,22 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler w.WriteValue(platformName); w.WriteEndElement(); // - if (module.Reader.PEHeaders.IsDll) - { - w.WriteElementString("OutputType", "Library"); - } - else + string outputType; + + switch ((module as PEFile)?.Reader.PEHeaders.PEHeader.Subsystem) { - switch (module.Reader.PEHeaders.PEHeader.Subsystem) - { - case Subsystem.WindowsGui: - w.WriteElementString("OutputType", "WinExe"); - break; - case Subsystem.WindowsCui: - w.WriteElementString("OutputType", "Exe"); - break; - default: - w.WriteElementString("OutputType", "Library"); - break; - } + case Subsystem.WindowsGui: + outputType = "WinExe"; + break; + case Subsystem.WindowsCui: + outputType = "Exe"; + break; + default: + outputType = "Library"; + break; } + w.WriteElementString("OutputType", outputType); w.WriteElementString("LangVersion", project.LanguageVersion.ToString().Replace("CSharp", "").Replace('_', '.')); w.WriteElementString("AssemblyName", module.Name); @@ -123,7 +119,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler w.WriteStartElement("PropertyGroup"); // platform-specific w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' "); w.WriteElementString("PlatformTarget", platformName); - if (targetFramework.VersionNumber > 400 && platformName == "AnyCPU" && (module.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0) + if (targetFramework.VersionNumber > 400 && platformName == "AnyCPU" + && ((module as PEFile)?.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0) { w.WriteElementString("Prefer32Bit", "false"); } diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs index b5273f1d5..ee0029dc9 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler TextWriter target, IProjectInfoProvider project, IEnumerable files, - PEFile module) + MetadataFile module) { using (XmlTextWriter xmlWriter = new XmlTextWriter(target)) { @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler } } - static void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable files, PEFile module) + static void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable files, MetadataFile module) { xml.WriteStartElement("Project"); @@ -105,18 +105,30 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler } } - static void WriteAssemblyInfo(XmlTextWriter xml, PEFile module, IProjectInfoProvider project, ProjectType projectType) + static void WriteAssemblyInfo(XmlTextWriter xml, MetadataFile module, IProjectInfoProvider project, ProjectType projectType) { xml.WriteElementString("AssemblyName", module.Name); // Since we create AssemblyInfo.cs manually, we need to disable the auto-generation xml.WriteElementString("GenerateAssemblyInfo", FalseString); - WriteOutputType(xml, module.Reader.PEHeaders.IsDll, module.Reader.PEHeaders.PEHeader.Subsystem, projectType); + string platformName; + CorFlags flags; + if (module is PEFile { Reader.PEHeaders: var headers } peFile) + { + WriteOutputType(xml, headers.IsDll, headers.PEHeader.Subsystem, projectType); + platformName = TargetServices.GetPlatformName(peFile); + flags = headers.CorHeader.Flags; + } + else + { + WriteOutputType(xml, isDll: true, Subsystem.Unknown, projectType); + platformName = AnyCpuString; + flags = 0; + } WriteDesktopExtensions(xml, projectType); - string platformName = TargetServices.GetPlatformName(module); var targetFramework = TargetServices.DetectTargetFramework(module); if (targetFramework.Identifier == ".NETFramework" && targetFramework.VersionNumber == 200) targetFramework = TargetServices.DetectTargetFrameworkNET20(module, project.AssemblyResolver, targetFramework); @@ -134,7 +146,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler xml.WriteElementString("PlatformTarget", platformName); } - if (platformName == AnyCpuString && (module.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) != 0) + if (platformName == AnyCpuString && (flags & CorFlags.Prefers32Bit) != 0) { xml.WriteElementString("Prefer32Bit", TrueString); } @@ -238,7 +250,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler } } - static void WriteReferences(XmlTextWriter xml, PEFile module, IProjectInfoProvider project, ProjectType projectType) + static void WriteReferences(XmlTextWriter xml, MetadataFile module, IProjectInfoProvider project, ProjectType projectType) { bool isNetCoreApp = TargetServices.DetectTargetFramework(module).Identifier == ".NETCoreApp"; var targetPacks = new HashSet(); @@ -292,7 +304,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler } } - static ProjectType GetProjectType(PEFile module) + static ProjectType GetProjectType(MetadataFile module) { foreach (var referenceName in module.AssemblyReferences.Select(r => r.Name)) { diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs index 163f45d0e..adbf96fc4 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs @@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler /// The module to get the target framework description for. Cannot be null. /// A new instance of the class that describes the specified . /// - public static TargetFramework DetectTargetFramework(PEFile module) + public static TargetFramework DetectTargetFramework(MetadataFile module) { if (module is null) { diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs index 3f79da004..5a22d218f 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs @@ -133,10 +133,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler public void DecompileProject(MetadataFile file, string targetDirectory, CancellationToken cancellationToken = default(CancellationToken)) { - if (file is not PEFile) - { - throw new NotSupportedException("Module is not a valid PE file!"); - } string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(file.Name) + ".csproj"); using (var writer = new StreamWriter(projectFileName)) { @@ -146,10 +142,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler public ProjectId DecompileProject(MetadataFile file, string targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken = default(CancellationToken)) { - if (file is not PEFile module) - { - throw new NotSupportedException("Module is not a valid PE file!"); - } if (string.IsNullOrEmpty(targetDirectory)) { throw new InvalidOperationException("Must set TargetDirectory"); @@ -159,15 +151,19 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler var resources = WriteResourceFilesInProject(file).ToList(); var files = WriteCodeFilesInProject(file, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty()).ToList(), cancellationToken).ToList(); files.AddRange(resources); - files.AddRange(WriteMiscellaneousFilesInProject(module)); + var module = file as PEFile; + if (module != null) + { + files.AddRange(WriteMiscellaneousFilesInProject(module)); + } if (StrongNameKeyFile != null) { File.Copy(StrongNameKeyFile, Path.Combine(targetDirectory, Path.GetFileName(StrongNameKeyFile)), overwrite: true); } - projectWriter.Write(projectFileWriter, this, files, module); + projectWriter.Write(projectFileWriter, this, files, file); - string platformName = TargetServices.GetPlatformName(module); + string platformName = module != null ? TargetServices.GetPlatformName(module) : "AnyCPU"; return new ProjectId(platformName, ProjectGuid, ProjectTypeGuids.CSharpWindows); } @@ -764,7 +760,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler } } - public static bool CanUseSdkStyleProjectFormat(PEFile module) + public static bool CanUseSdkStyleProjectFormat(MetadataFile module) { return TargetServices.DetectTargetFramework(module).Moniker != null; } diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index a4a1c7461..11c8bdb9a 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -1955,7 +1955,7 @@ namespace ICSharpCode.Decompiler.Disassembler } } - public void WriteAssemblyHeader(PEFile module) + public void WriteAssemblyHeader(MetadataFile module) { var metadata = module.Metadata; if (!metadata.IsAssembly) @@ -2018,7 +2018,7 @@ namespace ICSharpCode.Decompiler.Disassembler } } - public void WriteModuleHeader(PEFile module, bool skipMVID = false) + public void WriteModuleHeader(MetadataFile module, bool skipMVID = false) { var metadata = module.Metadata; @@ -2085,17 +2085,20 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteLine("// MVID: {0}", metadata.GetGuid(moduleDefinition.Mvid).ToString("B").ToUpperInvariant()); } - var headers = module.Reader.PEHeaders; - output.WriteLine(".imagebase 0x{0:x8}", headers.PEHeader.ImageBase); - output.WriteLine(".file alignment 0x{0:x8}", headers.PEHeader.FileAlignment); - output.WriteLine(".stackreserve 0x{0:x8}", headers.PEHeader.SizeOfStackReserve); - output.WriteLine(".subsystem 0x{0:x} // {1}", headers.PEHeader.Subsystem, headers.PEHeader.Subsystem.ToString()); - output.WriteLine(".corflags 0x{0:x} // {1}", headers.CorHeader.Flags, headers.CorHeader.Flags.ToString()); + if (module is PEFile peFile) + { + var headers = peFile.Reader.PEHeaders; + output.WriteLine(".imagebase 0x{0:x8}", headers.PEHeader.ImageBase); + output.WriteLine(".file alignment 0x{0:x8}", headers.PEHeader.FileAlignment); + output.WriteLine(".stackreserve 0x{0:x8}", headers.PEHeader.SizeOfStackReserve); + output.WriteLine(".subsystem 0x{0:x} // {1}", headers.PEHeader.Subsystem, headers.PEHeader.Subsystem.ToString()); + output.WriteLine(".corflags 0x{0:x} // {1}", headers.CorHeader.Flags, headers.CorHeader.Flags.ToString()); + } WriteAttributes(module, metadata.GetCustomAttributes(EntityHandle.ModuleDefinition)); } - public void WriteModuleContents(PEFile module) + public void WriteModuleContents(MetadataFile module) { foreach (var handle in Process(module, module.Metadata.GetTopLevelTypeDefinitions().ToArray())) { diff --git a/ILSpy/Commands/IProtocolHandler.cs b/ILSpy/Commands/IProtocolHandler.cs index 251b6b5f5..53f6e7ef3 100644 --- a/ILSpy/Commands/IProtocolHandler.cs +++ b/ILSpy/Commands/IProtocolHandler.cs @@ -1,18 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Linq; +// Copyright (c) 2018 Siegfried Pammer +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + using System.Reflection.Metadata; -using System.Text; -using System.Threading.Tasks; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.TreeNodes; -using ICSharpCode.TreeView; namespace ICSharpCode.ILSpy { public interface IProtocolHandler { - ILSpyTreeNode Resolve(string protocol, PEFile module, Handle handle, out bool newTabPage); + ILSpyTreeNode Resolve(string protocol, MetadataFile module, Handle handle, out bool newTabPage); } } diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index 395c2222a..d83a412ba 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -393,7 +393,7 @@ namespace ICSharpCode.ILSpy public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { - var module = assembly.GetMetadataFileOrNull() as PEFile; + var module = assembly.GetMetadataFileOrNull(); if (module == null) { return null; @@ -427,38 +427,49 @@ namespace ICSharpCode.ILSpy } var metadata = module.Metadata; var corHeader = module.CorHeader; - var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress); - if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition) + if (module is PEFile peFile && corHeader != null) { - var entrypoint = typeSystem.MainModule.ResolveMethod(entrypointHandle, new Decompiler.TypeSystem.GenericContext()); - if (entrypoint != null) + var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress); + if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition) { - output.Write("// Entry point: "); - output.WriteReference(entrypoint, EscapeName(entrypoint.DeclaringType.FullName + "." + entrypoint.Name)); - output.WriteLine(); + var entrypoint = typeSystem.MainModule.ResolveMethod(entrypointHandle, new Decompiler.TypeSystem.GenericContext()); + if (entrypoint != null) + { + output.Write("// Entry point: "); + output.WriteReference(entrypoint, EscapeName(entrypoint.DeclaringType.FullName + "." + entrypoint.Name)); + output.WriteLine(); + } + } + output.WriteLine("// Architecture: " + GetPlatformDisplayName(peFile)); + if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0) + { + output.WriteLine("// This assembly contains unmanaged code."); + } + string runtimeName = GetRuntimeDisplayName(module); + if (runtimeName != null) + { + output.WriteLine("// Runtime: " + runtimeName); + } + if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.StrongNameSigned) != 0) + { + output.WriteLine("// This assembly is signed with a strong name key."); + } + if (peFile.Reader.ReadDebugDirectory().Any(d => d.Type == DebugDirectoryEntryType.Reproducible)) + { + output.WriteLine("// This assembly was compiled using the /deterministic option."); + } + if (module.Metadata.MetadataKind != MetadataKind.Ecma335) + { + output.WriteLine("// This assembly was loaded with Windows Runtime projections applied."); } } - output.WriteLine("// Architecture: " + GetPlatformDisplayName(module)); - if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0) - { - output.WriteLine("// This assembly contains unmanaged code."); - } - string runtimeName = GetRuntimeDisplayName(module); - if (runtimeName != null) - { - output.WriteLine("// Runtime: " + runtimeName); - } - if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.StrongNameSigned) != 0) - { - output.WriteLine("// This assembly is signed with a strong name key."); - } - if (module.Reader.ReadDebugDirectory().Any(d => d.Type == DebugDirectoryEntryType.Reproducible)) - { - output.WriteLine("// This assembly was compiled using the /deterministic option."); - } - if (module.Metadata.MetadataKind != MetadataKind.Ecma335) + else { - output.WriteLine("// This assembly was loaded with Windows Runtime projections applied."); + string runtimeName = GetRuntimeDisplayName(module); + if (runtimeName != null) + { + output.WriteLine("// Runtime: " + runtimeName); + } } if (metadata.IsAssembly) { diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs index d962a31b7..95c881bb4 100644 --- a/ILSpy/Languages/ILLanguage.cs +++ b/ILSpy/Languages/ILLanguage.cs @@ -165,12 +165,7 @@ namespace ICSharpCode.ILSpy { output.WriteLine("// " + assembly.FileName); output.WriteLine(); - var module = assembly.GetMetadataFileOrNull() as PEFile; - - if (module == null) - { - throw new NotSupportedException("This file is not a PE file"); - } + var module = assembly.GetMetadataFileOrNull(); if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { diff --git a/ILSpy/Languages/Language.cs b/ILSpy/Languages/Language.cs index 12db7ad96..26410fe24 100644 --- a/ILSpy/Languages/Language.cs +++ b/ILSpy/Languages/Language.cs @@ -561,7 +561,7 @@ namespace ICSharpCode.ILSpy } } - public static string GetRuntimeDisplayName(PEFile module) + public static string GetRuntimeDisplayName(MetadataFile module) { return module.Metadata.MetadataVersion; } diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index c2c32973f..4f2180953 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -826,12 +826,6 @@ namespace ICSharpCode.ILSpy static bool CanResolveTypeInPEFile(MetadataFile module, ITypeReference typeRef, out EntityHandle typeHandle) { - if (module is not PEFile) - { - typeHandle = default; - return false; - } - // We intentionally ignore reference assemblies, so that the loop continues looking for another assembly that might have a usable definition. if (module.IsReferenceAssembly()) { @@ -1314,7 +1308,7 @@ namespace ICSharpCode.ILSpy break; case EntityReference unresolvedEntity: string protocol = unresolvedEntity.Protocol ?? "decompile"; - PEFile file = unresolvedEntity.ResolveAssembly(assemblyList) as PEFile; + var file = unresolvedEntity.ResolveAssembly(assemblyList); if (file == null) { break; diff --git a/ILSpy/Metadata/GoToTokenCommand.cs b/ILSpy/Metadata/GoToTokenCommand.cs index d8963ce60..ae0fa1657 100644 --- a/ILSpy/Metadata/GoToTokenCommand.cs +++ b/ILSpy/Metadata/GoToTokenCommand.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy.Commands { public void Execute(TextViewContext context) { - int token = GetSelectedToken(context.DataGrid, out PEFile module).Value; + int token = GetSelectedToken(context.DataGrid, out MetadataFile module).Value; MainWindow.Instance.JumpToReference(new EntityReference(module, MetadataTokens.Handle(token), protocol: "metadata")); } @@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.Commands return context.DataGrid?.Name == "MetadataView" && GetSelectedToken(context.DataGrid, out _) != null; } - private int? GetSelectedToken(DataGrid grid, out PEFile module) + private int? GetSelectedToken(DataGrid grid, out MetadataFile module) { module = null; if (grid == null) @@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpy.Commands var moduleField = type.GetField("module", BindingFlags.NonPublic | BindingFlags.Instance); if (property == null || property.PropertyType != typeof(int) || !property.GetCustomAttributes(false).Any(a => a is ColumnInfoAttribute { Kind: ColumnKind.Token } c)) return null; - module = (PEFile)moduleField.GetValue(cell.Item); + module = (MetadataFile)moduleField.GetValue(cell.Item); return (int)property.GetValue(cell.Item); } } diff --git a/ILSpy/Metadata/MetadataProtocolHandler.cs b/ILSpy/Metadata/MetadataProtocolHandler.cs index 3fb5219d9..e4fc4bbec 100644 --- a/ILSpy/Metadata/MetadataProtocolHandler.cs +++ b/ILSpy/Metadata/MetadataProtocolHandler.cs @@ -28,7 +28,7 @@ namespace ICSharpCode.ILSpy.Metadata [Export(typeof(IProtocolHandler))] class MetadataProtocolHandler : IProtocolHandler { - public ILSpyTreeNode Resolve(string protocol, PEFile module, Handle handle, out bool newTabPage) + public ILSpyTreeNode Resolve(string protocol, MetadataFile module, Handle handle, out bool newTabPage) { newTabPage = true; if (protocol != "metadata") diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index a505fba67..00ce4204b 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -51,7 +51,6 @@ using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.CSharp.OutputVisitor; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.Documentation; -using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.AvalonEdit; using ICSharpCode.ILSpy.Options; @@ -411,7 +410,7 @@ namespace ICSharpCode.ILSpy.TextView } else if (segment.Reference is EntityReference unresolvedEntity) { - var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.CurrentAssemblyList) as PEFile; + var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.CurrentAssemblyList); if (module == null) return null; var typeSystem = new DecompilerTypeSystem(module, diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs index 112b01cc4..04b179a3d 100644 --- a/ILSpy/TreeNodes/AssemblyTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs @@ -129,7 +129,7 @@ namespace ICSharpCode.ILSpy.TreeNodes if (tooltip == null && LoadedAssembly.IsLoaded) { tooltip = new TextBlock(); - var module = LoadedAssembly.GetMetadataFileOrNull() as PEFile; + var module = LoadedAssembly.GetMetadataFileOrNull(); var metadata = module?.Metadata; if (metadata?.IsAssembly == true && metadata.TryGetFullAssemblyName(out var assemblyName)) { @@ -141,9 +141,12 @@ namespace ICSharpCode.ILSpy.TreeNodes tooltip.Inlines.Add(new Run(LoadedAssembly.FileName)); if (module != null) { - tooltip.Inlines.Add(new LineBreak()); - tooltip.Inlines.Add(new Bold(new Run("Architecture: "))); - tooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(module))); + if (module is PEFile peFile) + { + tooltip.Inlines.Add(new LineBreak()); + tooltip.Inlines.Add(new Bold(new Run("Architecture: "))); + tooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(peFile))); + } string runtimeName = Language.GetRuntimeDisplayName(module); if (runtimeName != null) {