Browse Source

write OutputType for asp.net library

pull/2186/head
文煌 5 years ago committed by Siegfried Pammer
parent
commit
d612008c9f
  1. 73
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs
  2. 63
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs
  3. 82
      ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs
  4. 2
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  5. 13
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs
  6. 4
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  7. 5
      ILSpy/LoadedAssembly.cs

73
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs

@ -85,8 +85,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -85,8 +85,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
PlaceIntoTag("PropertyGroup", xml, () => WriteAssemblyInfo(xml, module, project, projectType));
PlaceIntoTag("PropertyGroup", xml, () => WriteProjectInfo(xml, project));
PlaceIntoTag("ItemGroup", xml, () => WriteResources(xml, module, files, project));
PlaceIntoTag("ItemGroup", xml, () => WriteReferences(xml, module, project));
PlaceIntoTag("ItemGroup", xml, () => WriteResources(xml, files));
PlaceIntoTag("ItemGroup", xml, () => WriteReferences(xml, module, project, projectType));
xml.WriteEndElement();
}
@ -111,11 +111,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -111,11 +111,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
// Since we create AssemblyInfo.cs manually, we need to disable the auto-generation
xml.WriteElementString("GenerateAssemblyInfo", FalseString);
// 'Library' is default, so only need to specify output type for executables
if (!module.Reader.PEHeaders.IsDll)
{
WriteOutputType(xml, module.Reader.PEHeaders.PEHeader.Subsystem);
}
WriteOutputType(xml, module.Reader.PEHeaders.IsDll, module.Reader.PEHeaders.PEHeader.Subsystem, projectType);
WriteDesktopExtensions(xml, projectType);
@ -143,16 +139,27 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -143,16 +139,27 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
static void WriteOutputType(XmlTextWriter xml, Subsystem moduleSubsystem)
static void WriteOutputType(XmlTextWriter xml, bool isDll, Subsystem moduleSubsystem, ProjectType projectType)
{
switch (moduleSubsystem)
if (!isDll)
{
case Subsystem.WindowsGui:
xml.WriteElementString("OutputType", "WinExe");
break;
case Subsystem.WindowsCui:
xml.WriteElementString("OutputType", "Exe");
break;
switch (moduleSubsystem)
{
case Subsystem.WindowsGui:
xml.WriteElementString("OutputType", "WinExe");
break;
case Subsystem.WindowsCui:
xml.WriteElementString("OutputType", "Exe");
break;
}
}
else
{
// 'Library' is default, so only need to specify output type for executables (excludes ProjectType.Web)
if (projectType == ProjectType.Web)
{
xml.WriteElementString("OutputType", "Library");
}
}
}
@ -180,12 +187,12 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -180,12 +187,12 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
static void WriteResources(XmlTextWriter xml, PEFile module, IEnumerable<(string itemType, string fileName)> files, IProjectInfoProvider project)
static void WriteResources(XmlTextWriter xml, IEnumerable<(string itemType, string fileName)> files)
{
// remove phase
foreach (var file in files.Where(t => t.itemType == "EmbeddedResource"))
foreach (var (itemType, fileName) in files.Where(t => t.itemType == "EmbeddedResource"))
{
string buildAction = Path.GetExtension(file.fileName).ToUpperInvariant() switch
string buildAction = Path.GetExtension(fileName).ToUpperInvariant() switch
{
".CS" => "Compile",
".RESX" => "EmbeddedResource",
@ -195,27 +202,45 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -195,27 +202,45 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
continue;
xml.WriteStartElement(buildAction);
xml.WriteAttributeString("Remove", file.fileName);
xml.WriteAttributeString("Remove", fileName);
xml.WriteEndElement();
}
// include phase
foreach (var file in files.Where(t => t.itemType == "EmbeddedResource"))
foreach (var (itemType, fileName) in files.Where(t => t.itemType == "EmbeddedResource"))
{
if (Path.GetExtension(file.fileName) == ".resx")
if (Path.GetExtension(fileName) == ".resx")
continue;
xml.WriteStartElement("EmbeddedResource");
xml.WriteAttributeString("Include", file.fileName);
xml.WriteAttributeString("Include", fileName);
xml.WriteEndElement();
}
}
static void WriteReferences(XmlTextWriter xml, PEFile module, IProjectInfoProvider project)
static void WriteReferences(XmlTextWriter xml, PEFile module, IProjectInfoProvider project, ProjectType projectType)
{
bool isNetCoreApp = TargetServices.DetectTargetFramework(module).Identifier == ".NETCoreApp";
var targetPacks = new HashSet<string>();
if (isNetCoreApp)
{
targetPacks.Add("Microsoft.NETCore.App");
switch (projectType)
{
case ProjectType.WinForms:
case ProjectType.Wpf:
targetPacks.Add("Microsoft.WindowsDesktop.App");
break;
case ProjectType.Web:
targetPacks.Add("Microsoft.AspNetCore.App");
targetPacks.Add("Microsoft.AspNetCore.All");
break;
}
}
foreach (var reference in module.AssemblyReferences.Where(r => !ImplicitReferences.Contains(r.Name)))
{
if (project.AssemblyResolver.IsSharedAssembly(reference))
if (isNetCoreApp && project.AssemblyResolver.IsSharedAssembly(reference, out string runtimePack) && targetPacks.Contains(runtimePack))
{
continue;
}

63
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs

@ -135,7 +135,22 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -135,7 +135,22 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
static HashSet<string> dotNet30Assemblies = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
// System
"ComSvcConfig, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"Microsoft.Transactions.Bridge, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Transactions.Bridge.Dtc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"PresentationBuildTasks, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationCFFRasterizer, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Classic, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Royale, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"ReachFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"ServiceModelReg, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"SMSvcHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"System.IdentityModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.IdentityModel.Selectors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.IO.Log, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
@ -148,34 +163,30 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -148,34 +163,30 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
"System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
// WPF
"PresentationBuildTasks, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationCFFRasterizer, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Classic, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationFramework.Royale, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"ReachFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
// UIAutomation
"WindowsFormsIntegration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"UIAutomationClient, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"UIAutomationClientsideProviders, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"UIAutomationProvider, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"UIAutomationTypes, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
// WCF
"Microsoft.Transactions.Bridge, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Transactions.Bridge.Dtc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"WindowsFormsIntegration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"WsatConfig, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
};
static HashSet<string> dotNet35Assemblies = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
// System
"AddInProcess, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"AddInProcess32, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"AddInUtil, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"DataSvcUtil, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"EdmGen, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"Microsoft.Build.Conversion.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Data.Entity.Build.Tasks, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.VisualC.STLCLR, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"MSBuild, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Sentinel.v3.5Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"System.AddIn, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.AddIn.Contract, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
@ -202,14 +213,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -202,14 +213,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
"System.Windows.Presentation, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
// MSBuild
"Microsoft.Build.Conversion.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"Microsoft.Data.Entity.Build.Tasks, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
};
/// <summary>

82
ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs

@ -68,16 +68,86 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -68,16 +68,86 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
foreach (var section in rootNode.Children.OfType<AttributeSection>())
{
if (section.AttributeTarget != "assembly")
continue;
foreach (var attribute in section.Attributes)
if (section.AttributeTarget == "assembly")
{
foreach (var attribute in section.Attributes)
{
var trr = attribute.Type.Annotation<TypeResolveResult>();
if (trr == null)
continue;
string fullName = trr.Type.FullName;
var arguments = attribute.Arguments;
switch (fullName)
{
case "System.Diagnostics.DebuggableAttribute":
{
attribute.Remove();
break;
}
case "System.Runtime.CompilerServices.CompilationRelaxationsAttribute":
{
if (arguments.Count == 1 && arguments.First() is PrimitiveExpression expr && expr.Value is int value && value == 8)
attribute.Remove();
break;
}
case "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute":
{
if (arguments.Count != 1)
break;
if (!(arguments.First() is NamedExpression expr1) || expr1.Name != "WrapNonExceptionThrows")
break;
if (!(expr1.Expression is PrimitiveExpression expr2) || !(expr2.Value is bool value) || value != true)
break;
attribute.Remove();
break;
}
case "System.Runtime.Versioning.TargetFrameworkAttribute":
{
attribute.Remove();
break;
}
case "System.Security.Permissions.SecurityPermissionAttribute":
{
if (arguments.Count != 2)
break;
if (!(arguments.First() is MemberReferenceExpression expr1) || expr1.MemberName != "RequestMinimum")
break;
if (!(expr1.NextSibling is NamedExpression expr2) || expr2.Name != "SkipVerification")
break;
if (!(expr2.Expression is PrimitiveExpression expr3) || !(expr3.Value is bool value2) || value2 != true)
break;
attribute.Remove();
break;
}
}
}
}
else if (section.AttributeTarget == "module")
{
var trr = attribute.Type.Annotation<TypeResolveResult>();
if (trr != null && trr.Type.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute")
attribute.Remove();
foreach (var attribute in section.Attributes)
{
var trr = attribute.Type.Annotation<TypeResolveResult>();
if (trr == null)
continue;
switch (trr.Type.FullName)
{
case "System.Security.UnverifiableCodeAttribute":
attribute.Remove();
break;
}
}
}
else
{
continue;
}
if (section.Attributes.Count == 0)
{
section.Remove();
}
}
}
}

2
ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.Metadata
PEFile ResolveModule(PEFile mainModule, string moduleName);
#endif
bool IsGacAssembly(IAssemblyReference reference);
bool IsSharedAssembly(IAssemblyReference reference);
bool IsSharedAssembly(IAssemblyReference reference, out string runtimePack);
}
public interface IAssemblyReference

13
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs

@ -139,7 +139,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -139,7 +139,7 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
return TryResolveDotNetCoreShared(name);
return TryResolveDotNetCoreShared(name, out _);
}
internal string GetReferenceAssemblyPath(string targetFramework)
@ -188,13 +188,17 @@ namespace ICSharpCode.Decompiler.Metadata @@ -188,13 +188,17 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
public string TryResolveDotNetCoreShared(IAssemblyReference name)
public string TryResolveDotNetCoreShared(IAssemblyReference name, out string runtimePack)
{
if (dotnetBasePath == null)
{
runtimePack = null;
return null;
var basePaths = RuntimePacks.Select(pack => Path.Combine(dotnetBasePath, "shared", pack));
foreach (var basePath in basePaths)
}
foreach (string pack in RuntimePacks)
{
runtimePack = pack;
string basePath = Path.Combine(dotnetBasePath, "shared", pack);
if (!Directory.Exists(basePath))
continue;
var closestVersion = GetClosestVersionFolder(basePath, targetFrameworkVersion);
@ -207,6 +211,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -207,6 +211,7 @@ namespace ICSharpCode.Decompiler.Metadata
return Path.Combine(basePath, closestVersion, name.Name + ".exe");
}
}
runtimePack = null;
return null;
}

4
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -189,9 +189,9 @@ namespace ICSharpCode.Decompiler.Metadata @@ -189,9 +189,9 @@ namespace ICSharpCode.Decompiler.Metadata
return GetAssemblyInGac(reference) != null;
}
public virtual bool IsSharedAssembly(IAssemblyReference reference)
public virtual bool IsSharedAssembly(IAssemblyReference reference, out string runtimePack)
{
return targetFrameworkIdentifier == TargetFrameworkIdentifier.NETCoreApp && dotNetCorePathFinder.TryResolveDotNetCoreShared(reference) != null;
return dotNetCorePathFinder.TryResolveDotNetCoreShared(reference, out runtimePack) != null;
}
public string FindAssemblyFile(IAssemblyReference name)

5
ILSpy/LoadedAssembly.cs

@ -288,9 +288,10 @@ namespace ICSharpCode.ILSpy @@ -288,9 +288,10 @@ namespace ICSharpCode.ILSpy
return parent.universalResolver?.IsGacAssembly(reference) == true;
}
public bool IsSharedAssembly(IAssemblyReference reference)
public bool IsSharedAssembly(IAssemblyReference reference, out string runtimePack)
{
return parent.universalResolver?.IsSharedAssembly(reference) == true;
runtimePack = null;
return parent.universalResolver?.IsSharedAssembly(reference, out runtimePack) == true;
}
public PEFile Resolve(Decompiler.Metadata.IAssemblyReference reference)

Loading…
Cancel
Save