mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
197 lines
7.6 KiB
C#
197 lines
7.6 KiB
C#
// Copyright (c) 2020 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;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection.PortableExecutable;
|
|
using System.Xml;
|
|
|
|
using ICSharpCode.Decompiler.Metadata;
|
|
using ICSharpCode.Decompiler.Solution;
|
|
using ICSharpCode.Decompiler.Util;
|
|
|
|
namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
|
|
{
|
|
/// <summary>
|
|
/// A <see cref="IProjectFileWriter"/> implementation that creates the projects in the default format.
|
|
/// </summary>
|
|
sealed class ProjectFileWriterDefault : IProjectFileWriter
|
|
{
|
|
/// <summary>
|
|
/// Creates a new instance of the <see cref="ProjectFileWriterDefault"/> class.
|
|
/// </summary>
|
|
/// <returns>A new instance of the <see cref="ProjectFileWriterDefault"/> class.</returns>
|
|
public static IProjectFileWriter Create() => new ProjectFileWriterDefault();
|
|
|
|
/// <inheritdoc />
|
|
public void Write(
|
|
TextWriter target,
|
|
IProjectInfoProvider project,
|
|
IEnumerable<ProjectItemInfo> files,
|
|
MetadataFile module)
|
|
{
|
|
const string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
|
|
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);
|
|
|
|
List<Guid> typeGuids = new List<Guid>();
|
|
if (targetFramework.IsPortableClassLibrary)
|
|
typeGuids.Add(ProjectTypeGuids.PortableLibrary);
|
|
typeGuids.Add(ProjectTypeGuids.CSharpWindows);
|
|
|
|
using (XmlTextWriter w = new XmlTextWriter(target))
|
|
{
|
|
w.Formatting = Formatting.Indented;
|
|
w.WriteStartDocument();
|
|
w.WriteStartElement("Project", ns);
|
|
w.WriteAttributeString("ToolsVersion", "4.0");
|
|
w.WriteAttributeString("DefaultTargets", "Build");
|
|
|
|
w.WriteStartElement("PropertyGroup");
|
|
w.WriteElementString("ProjectGuid", project.ProjectGuid.ToString("B").ToUpperInvariant());
|
|
w.WriteElementString("ProjectTypeGuids", string.Join(";", typeGuids.Select(g => g.ToString("B").ToUpperInvariant())));
|
|
|
|
w.WriteStartElement("Configuration");
|
|
w.WriteAttributeString("Condition", " '$(Configuration)' == '' ");
|
|
w.WriteValue("Debug");
|
|
w.WriteEndElement(); // </Configuration>
|
|
|
|
w.WriteStartElement("Platform");
|
|
w.WriteAttributeString("Condition", " '$(Platform)' == '' ");
|
|
w.WriteValue(platformName);
|
|
w.WriteEndElement(); // </Platform>
|
|
|
|
string outputType;
|
|
|
|
switch ((module as PEFile)?.Reader.PEHeaders.PEHeader.Subsystem)
|
|
{
|
|
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);
|
|
if (targetFramework.Identifier != null)
|
|
w.WriteElementString("TargetFrameworkIdentifier", targetFramework.Identifier);
|
|
if (targetFramework.VersionString != null)
|
|
w.WriteElementString("TargetFrameworkVersion", targetFramework.VersionString);
|
|
if (targetFramework.Profile != null)
|
|
w.WriteElementString("TargetFrameworkProfile", targetFramework.Profile);
|
|
w.WriteElementString("WarningLevel", "4");
|
|
w.WriteElementString("AllowUnsafeBlocks", "True");
|
|
|
|
if (project.StrongNameKeyFile != null)
|
|
{
|
|
w.WriteElementString("SignAssembly", "True");
|
|
w.WriteElementString("AssemblyOriginatorKeyFile", Path.GetFileName(project.StrongNameKeyFile));
|
|
}
|
|
|
|
w.WriteEndElement(); // </PropertyGroup>
|
|
|
|
w.WriteStartElement("PropertyGroup"); // platform-specific
|
|
w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' ");
|
|
w.WriteElementString("PlatformTarget", platformName);
|
|
if (targetFramework.VersionNumber > 400 && platformName == "AnyCPU"
|
|
&& ((module as PEFile)?.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0)
|
|
{
|
|
w.WriteElementString("Prefer32Bit", "false");
|
|
}
|
|
w.WriteEndElement(); // </PropertyGroup> (platform-specific)
|
|
|
|
w.WriteStartElement("PropertyGroup"); // Debug
|
|
w.WriteAttributeString("Condition", " '$(Configuration)' == 'Debug' ");
|
|
w.WriteElementString("OutputPath", "bin\\Debug\\");
|
|
w.WriteElementString("DebugSymbols", "true");
|
|
w.WriteElementString("DebugType", "full");
|
|
w.WriteElementString("Optimize", "false");
|
|
w.WriteEndElement(); // </PropertyGroup> (Debug)
|
|
|
|
w.WriteStartElement("PropertyGroup"); // Release
|
|
w.WriteAttributeString("Condition", " '$(Configuration)' == 'Release' ");
|
|
w.WriteElementString("OutputPath", "bin\\Release\\");
|
|
w.WriteElementString("DebugSymbols", "true");
|
|
w.WriteElementString("DebugType", "pdbonly");
|
|
w.WriteElementString("Optimize", "true");
|
|
w.WriteEndElement(); // </PropertyGroup> (Release)
|
|
|
|
|
|
w.WriteStartElement("ItemGroup"); // References
|
|
foreach (var r in module.AssemblyReferences)
|
|
{
|
|
if (r.Name != "mscorlib")
|
|
{
|
|
w.WriteStartElement("Reference");
|
|
w.WriteAttributeString("Include", r.Name);
|
|
var asm = project.AssemblyResolver.Resolve(r);
|
|
if (asm != null && !project.AssemblyReferenceClassifier.IsGacAssembly(r))
|
|
{
|
|
w.WriteElementString("HintPath", asm.FileName);
|
|
}
|
|
w.WriteEndElement();
|
|
}
|
|
}
|
|
w.WriteEndElement(); // </ItemGroup> (References)
|
|
|
|
foreach (IGrouping<string, ProjectItemInfo> gr in files.GroupBy(f => f.ItemType).OrderBy(g => g.Key))
|
|
{
|
|
w.WriteStartElement("ItemGroup");
|
|
foreach (var item in gr.OrderBy(f => f.FileName, StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
w.WriteStartElement(gr.Key);
|
|
w.WriteAttributeString("Include", item.FileName);
|
|
if (item.AdditionalProperties != null)
|
|
{
|
|
foreach (var (key, value) in item.AdditionalProperties)
|
|
w.WriteAttributeString(key, value);
|
|
}
|
|
w.WriteEndElement();
|
|
}
|
|
w.WriteEndElement();
|
|
}
|
|
if (targetFramework.IsPortableClassLibrary)
|
|
{
|
|
w.WriteStartElement("Import");
|
|
w.WriteAttributeString("Project", "$(MSBuildExtensionsPath32)\\Microsoft\\Portable\\$(TargetFrameworkVersion)\\Microsoft.Portable.CSharp.targets");
|
|
w.WriteEndElement();
|
|
}
|
|
else
|
|
{
|
|
w.WriteStartElement("Import");
|
|
w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets");
|
|
w.WriteEndElement();
|
|
}
|
|
|
|
w.WriteEndDocument();
|
|
}
|
|
}
|
|
}
|
|
}
|