Browse Source

implement basic plug-in

pull/182/merge
Siegfried Pammer 14 years ago
parent
commit
d3f31d054e
  1. 61
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  2. 29
      ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
  3. 63
      ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj
  4. 16
      ILSpy.BamlDecompiler/MyClass.cs
  5. 4
      ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs
  6. 445
      ILSpy/BamlDecompiler.cs
  7. 23
      ILSpy/CSharpLanguage.cs
  8. 1
      ILSpy/ILSpy.csproj
  9. 2
      ILSpy/TreeNodes/ILSpyTreeNode.cs
  10. 2
      ILSpy/TreeNodes/ResourceEntryNode.cs
  11. 2
      ILSpy/TreeNodes/ResourceTreeNode.cs
  12. 2
      ILSpy/TreeNodes/XamlResourceNode.cs

61
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
public sealed class BamlResourceEntryNode : ResourceEntryNode
{
public BamlResourceEntryNode(string key, Stream data) : base(key, data)
{
}
public override bool View(DecompilerTextView textView)
{
AvalonEditTextOutput output = new AvalonEditTextOutput();
IHighlightingDefinition highlighting = null;
textView.RunWithCancellation(
token => Task.Factory.StartNew(
() => {
try {
if (LoadBaml(output))
highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml");
} catch (Exception ex) {
output.Write(ex.ToString());
}
return output;
}),
t => textView.ShowNode(t.Result, this, highlighting)
);
return true;
}
bool LoadBaml(AvalonEditTextOutput output)
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
MemoryStream bamlStream = new MemoryStream();
Data.Position = 0;
Data.CopyTo(bamlStream);
bamlStream.Position = 0;
XDocument xamlDocument;
using (XmlBamlReader reader = new XmlBamlReader(bamlStream))
xamlDocument = XDocument.Load(reader);
output.Write(xamlDocument.ToString());
return true;
}
}
}

29
ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using ICSharpCode.ILSpy.TreeNodes;
namespace ILSpy.BamlDecompiler
{
[Export(typeof(IResourceNodeFactory))]
public sealed class BamlResourceNodeFactory : IResourceNodeFactory
{
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource)
{
return null;
}
public ILSpyTreeNode CreateNode(string key, Stream data)
{
if (key.EndsWith(".baml", StringComparison.OrdinalIgnoreCase))
return new BamlResourceEntryNode(key, data);
else
return null;
}
}
}

63
ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj

@ -6,42 +6,66 @@ @@ -6,42 +6,66 @@
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<RootNamespace>ILSpy.BamlDecompiler</RootNamespace>
<AssemblyName>ILSpy.BamlDecompiler</AssemblyName>
<AssemblyName>ILSpy.BamlDecompiler.Plugin</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<AppDesignerFolder>Properties</AppDesignerFolder>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>True</DebugSymbols>
<OutputPath>..\ILSpy\bin\Debug\</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<OutputPath>..\ILSpy\bin\Release\</OutputPath>
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="MyClass.cs" />
<Compile Include="BamlResourceNodeFactory.cs" />
<Compile Include="BamlResourceEntryNode.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\AppDomainTypeResolver.cs" />
<Compile Include="Ricciolo.StylesExplorer.MarkupReflection\BamlAssembly.cs" />
@ -69,5 +93,32 @@ @@ -69,5 +93,32 @@
<ItemGroup>
<Folder Include="Ricciolo.StylesExplorer.MarkupReflection" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj">
<Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project>
<Name>ICSharpCode.Decompiler</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\ILSpy\ILSpy.csproj">
<Project>{1E85EFF9-E370-4683-83E4-8A3D063FF791}</Project>
<Name>ILSpy</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\Mono.Cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj">
<Project>{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}</Project>
<Name>ICSharpCode.TreeView</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

16
ILSpy.BamlDecompiler/MyClass.cs

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Collections.Generic;
namespace ILSpy.BamlDecompiler
{
/// <summary>
/// Description of MyClass.
/// </summary>
public class MyClass
{
}
}

4
ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs

@ -9,11 +9,11 @@ using System.Runtime.InteropServices; @@ -9,11 +9,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ILSpy.BamlDecompiler")]
[assembly: AssemblyTitle("ILSpy.BamlDecompiler.Plugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ILSpy.BamlDecompiler")]
[assembly: AssemblyProduct("ILSpy.BamlDecompiler.Plugin")]
[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

445
ILSpy/BamlDecompiler.cs

@ -1,445 +0,0 @@ @@ -1,445 +0,0 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// 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.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Baml2006;
using System.Xaml;
using System.Xaml.Schema;
using System.Xml;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.ILSpy.Baml
{
/// <remarks>Caution: use in separate AppDomain only!</remarks>
sealed class BamlDecompiler : MarshalByRefObject
{
public BamlDecompiler()
{
}
abstract class XamlNode
{
public readonly List<XamlNode> Children = new List<XamlNode>();
public abstract void WriteTo(XamlWriter writer);
}
[Conditional("DEBUG")]
static void Log(string format, params object[] args)
{
Debug.WriteLine(format, args);
}
sealed class XamlObjectNode : XamlNode
{
public readonly XamlType Type;
public XamlObjectNode(XamlType type)
{
this.Type = type;
}
public override void WriteTo(XamlWriter writer)
{
Log("StartObject {0}", this.Type);
writer.WriteStartObject(this.Type);
Debug.Indent();
foreach (XamlNode node in this.Children)
node.WriteTo(writer);
Debug.Unindent();
Log("EndObject");
writer.WriteEndObject();
}
}
sealed class XamlGetObjectNode : XamlNode
{
public override void WriteTo(XamlWriter writer)
{
Log("GetObject");
writer.WriteGetObject();
Debug.Indent();
foreach (XamlNode node in this.Children)
node.WriteTo(writer);
Debug.Unindent();
Log("EndObject");
writer.WriteEndObject();
}
}
sealed class XamlMemberNode : XamlNode
{
public XamlMember Member;
public XamlMemberNode(XamlMember member)
{
this.Member = member;
}
public override void WriteTo(XamlWriter writer)
{
Log("StartMember {0}", this.Member);
writer.WriteStartMember(this.Member);
Debug.Indent();
foreach (XamlNode node in this.Children)
node.WriteTo(writer);
Debug.Unindent();
Log("EndMember");
writer.WriteEndMember();
}
}
sealed class XamlValueNode : XamlNode
{
public readonly object Value;
public XamlValueNode(object value)
{
this.Value = value;
}
public override void WriteTo(XamlWriter writer)
{
Log("Value {0}", this.Value);
Debug.Assert(this.Children.Count == 0);
// requires XamlReaderSettings.ValuesMustBeString = true to work properly
writer.WriteValue(this.Value);
}
}
sealed class XamlNamespaceDeclarationNode : XamlNode
{
public readonly NamespaceDeclaration Namespace;
public XamlNamespaceDeclarationNode(NamespaceDeclaration @namespace)
{
this.Namespace = @namespace;
}
public override void WriteTo(XamlWriter writer)
{
Log("NamespaceDeclaration {0}", this.Namespace);
Debug.Assert(this.Children.Count == 0);
writer.WriteNamespace(this.Namespace);
}
}
static List<XamlNode> Parse(XamlReader reader)
{
List<XamlNode> currentList = new List<XamlNode>();
Stack<List<XamlNode>> stack = new Stack<List<XamlNode>>();
while (reader.Read()) {
switch (reader.NodeType) {
case XamlNodeType.None:
break;
case XamlNodeType.StartObject:
XamlObjectNode obj = new XamlObjectNode(reader.Type);
currentList.Add(obj);
stack.Push(currentList);
currentList = obj.Children;
break;
case XamlNodeType.GetObject:
XamlGetObjectNode getObject = new XamlGetObjectNode();
currentList.Add(getObject);
stack.Push(currentList);
currentList = getObject.Children;
break;
case XamlNodeType.StartMember:
XamlMemberNode member = new XamlMemberNode(reader.Member);
currentList.Add(member);
stack.Push(currentList);
currentList = member.Children;
break;
case XamlNodeType.Value:
currentList.Add(new XamlValueNode(reader.Value));
break;
case XamlNodeType.NamespaceDeclaration:
currentList.Add(new XamlNamespaceDeclarationNode(reader.Namespace));
break;
case XamlNodeType.EndObject:
case XamlNodeType.EndMember:
currentList = stack.Pop();
break;
default:
throw new InvalidOperationException("Invalid value for XamlNodeType");
}
}
if (stack.Count != 0)
throw new InvalidOperationException("Imbalanced stack");
return currentList;
}
void AvoidContentProperties(XamlNode node)
{
foreach (XamlNode child in node.Children)
AvoidContentProperties(child);
XamlObjectNode obj = node as XamlObjectNode;
if (obj != null) {
// Visit all except for the last child:
for (int i = 0; i < obj.Children.Count - 1; i++) {
// Avoids using content property syntax for simple string values, if the content property is not the last member.
// Without this, we cannot decompile &lt;GridViewColumn Header="Culture" DisplayMemberBinding="{Binding Culture}" /&gt;,
// because the Header property is the content property, but there is no way to represent the Binding as an element.
XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode;
if (memberNode != null && memberNode.Member == obj.Type.ContentProperty) {
if (memberNode.Children.Count == 1 && memberNode.Children[0] is XamlValueNode) {
// By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property.
XamlMember member = memberNode.Member;
memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable);
}
}
}
// We also need to avoid using content properties that have a markup extension as value, as the XamlXmlWriter would always expand those:
for (int i = 0; i < obj.Children.Count; i++) {
XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode;
if (memberNode != null && memberNode.Member == obj.Type.ContentProperty && memberNode.Children.Count == 1) {
XamlObjectNode me = memberNode.Children[0] as XamlObjectNode;
if (me != null && me.Type.IsMarkupExtension) {
// By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property.
XamlMember member = memberNode.Member;
memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable);
}
}
}
}
}
/// <summary>
/// It seems like BamlReader will always output 'x:Key' as last property. However, it must be specified as attribute in valid .xaml, so we move it to the front
/// of the attribute list.
/// </summary>
void MoveXKeyToFront(XamlNode node)
{
foreach (XamlNode child in node.Children)
MoveXKeyToFront(child);
XamlObjectNode obj = node as XamlObjectNode;
if (obj != null && obj.Children.Count > 0) {
XamlMemberNode memberNode = obj.Children[obj.Children.Count - 1] as XamlMemberNode;
if (memberNode != null && memberNode.Member == XamlLanguage.Key) {
// move memberNode in front of the first member node:
for (int i = 0; i < obj.Children.Count; i++) {
if (obj.Children[i] is XamlMemberNode) {
obj.Children.Insert(i, memberNode);
obj.Children.RemoveAt(obj.Children.Count - 1);
break;
}
}
}
}
}
AssemblyResolver asmResolver;
Assembly AssemblyResolve(object sender, ResolveEventArgs args)
{
string path = asmResolver.FindAssembly(args.Name);
if (path == null)
return null;
return Assembly.LoadFile(path);
}
public string DecompileBaml(MemoryStream bamlCode, string containingAssemblyFile, ConnectMethodDecompiler connectMethodDecompiler, AssemblyResolver asmResolver)
{
this.asmResolver = asmResolver;
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
bamlCode.Position = 0;
TextWriter w = new StringWriter();
Assembly assembly = Assembly.LoadFile(containingAssemblyFile);
Baml2006Reader reader = new Baml2006Reader(bamlCode, new XamlReaderSettings() { ValuesMustBeString = true, LocalAssembly = assembly });
var xamlDocument = Parse(reader);
string bamlTypeName = xamlDocument.OfType<XamlObjectNode>().First().Type.UnderlyingType.FullName;
var eventMappings = connectMethodDecompiler.DecompileEventMappings(bamlTypeName);
foreach (var xamlNode in xamlDocument) {
RemoveConnectionIds(xamlNode, eventMappings, reader.SchemaContext);
AvoidContentProperties(xamlNode);
MoveXKeyToFront(xamlNode);
}
XDocument doc = new XDocument();
XamlXmlWriter writer = new XamlXmlWriter(doc.CreateWriter(), reader.SchemaContext, new XamlXmlWriterSettings { AssumeValidInput = true });
foreach (var xamlNode in xamlDocument)
xamlNode.WriteTo(writer);
writer.Close();
// Fix namespace references
string suffixToRemove = ";assembly=" + assembly.GetName().Name;
foreach (XAttribute attrib in doc.Root.Attributes()) {
if (attrib.Name.Namespace == XNamespace.Xmlns) {
if (attrib.Value.EndsWith(suffixToRemove, StringComparison.Ordinal)) {
string newNamespace = attrib.Value.Substring(0, attrib.Value.Length - suffixToRemove.Length);
ChangeXmlNamespace(doc, attrib.Value, newNamespace);
attrib.Value = newNamespace;
}
}
}
return doc.ToString();
}
void RemoveConnectionIds(XamlNode node, Dictionary<int, EventRegistration[]> eventMappings, XamlSchemaContext context)
{
foreach (XamlNode child in node.Children)
RemoveConnectionIds(child, eventMappings, context);
XamlObjectNode obj = node as XamlObjectNode;
if (obj != null && obj.Children.Count > 0) {
var removableNodes = new List<XamlMemberNode>();
var addableNodes = new List<XamlMemberNode>();
foreach (XamlMemberNode memberNode in obj.Children.OfType<XamlMemberNode>()) {
if (memberNode.Member == XamlLanguage.ConnectionId && memberNode.Children.Single() is XamlValueNode) {
var value = memberNode.Children.Single() as XamlValueNode;
int id;
if (value.Value is string && int.TryParse(value.Value as string, out id) && eventMappings.ContainsKey(id)) {
var map = eventMappings[id];
foreach (var entry in map) {
if (entry.IsAttached) {
var type = context.GetXamlType(Type.GetType(entry.AttachSourceType));
var member = new XamlMemberNode(new XamlMember(entry.EventName, type, true));
member.Children.Add(new XamlValueNode(entry.MethodName));
addableNodes.Add(member);
} else {
var member = new XamlMemberNode(obj.Type.GetMember(entry.EventName));
member.Children.Add(new XamlValueNode(entry.MethodName));
addableNodes.Add(member);
}
}
removableNodes.Add(memberNode);
}
}
}
foreach (var rnode in removableNodes)
node.Children.Remove(rnode);
node.Children.InsertRange(node.Children.Count > 1 ? node.Children.Count - 1 : 0, addableNodes);
}
}
/// <summary>
/// Changes all references from oldNamespace to newNamespace in the document.
/// </summary>
void ChangeXmlNamespace(XDocument doc, XNamespace oldNamespace, XNamespace newNamespace)
{
foreach (XElement e in doc.Descendants()) {
if (e.Name.Namespace == oldNamespace)
e.Name = newNamespace + e.Name.LocalName;
}
}
}
[Export(typeof(IResourceNodeFactory))]
sealed class BamlResourceNodeFactory : IResourceNodeFactory
{
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource)
{
return null;
}
public ILSpyTreeNode CreateNode(string key, Stream data)
{
if (key.EndsWith(".baml", StringComparison.OrdinalIgnoreCase))
return new BamlResourceEntryNode(key, data);
else
return null;
}
}
sealed class BamlResourceEntryNode : ResourceEntryNode
{
public BamlResourceEntryNode(string key, Stream data) : base(key, data)
{
}
internal override bool View(DecompilerTextView textView)
{
AvalonEditTextOutput output = new AvalonEditTextOutput();
IHighlightingDefinition highlighting = null;
textView.RunWithCancellation(
token => Task.Factory.StartNew(
() => {
try {
if (LoadBaml(output))
highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml");
} catch (Exception ex) {
output.Write(ex.ToString());
}
return output;
}),
t => textView.ShowNode(t.Result, this, highlighting)
);
return true;
}
bool LoadBaml(AvalonEditTextOutput output)
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
AppDomain bamlDecompilerAppDomain = null;
try {
BamlDecompiler decompiler = CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, asm.FileName);
MemoryStream bamlStream = new MemoryStream();
Data.Position = 0;
Data.CopyTo(bamlStream);
output.Write(decompiler.DecompileBaml(bamlStream, asm.FileName, new ConnectMethodDecompiler(asm), new AssemblyResolver(asm)));
return true;
} finally {
if (bamlDecompilerAppDomain != null)
AppDomain.Unload(bamlDecompilerAppDomain);
}
}
public static BamlDecompiler CreateBamlDecompilerInAppDomain(ref AppDomain appDomain, string assemblyFileName)
{
if (appDomain == null) {
// Construct and initialize settings for a second AppDomain.
AppDomainSetup bamlDecompilerAppDomainSetup = new AppDomainSetup();
// bamlDecompilerAppDomainSetup.ApplicationBase = "file:///" + Path.GetDirectoryName(assemblyFileName);
bamlDecompilerAppDomainSetup.DisallowBindingRedirects = false;
bamlDecompilerAppDomainSetup.DisallowCodeDownload = true;
bamlDecompilerAppDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// Create the second AppDomain.
appDomain = AppDomain.CreateDomain("BamlDecompiler AD", null, bamlDecompilerAppDomainSetup);
}
return (BamlDecompiler)appDomain.CreateInstanceAndUnwrap(typeof(BamlDecompiler).Assembly.FullName, typeof(BamlDecompiler).FullName);
}
}
}

23
ILSpy/CSharpLanguage.cs

@ -437,17 +437,18 @@ namespace ICSharpCode.ILSpy @@ -437,17 +437,18 @@ namespace ICSharpCode.ILSpy
if (fileName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) {
MemoryStream ms = new MemoryStream();
entryStream.CopyTo(ms);
var decompiler = Baml.BamlResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assembly.FileName);
string xaml = null;
try {
xaml = decompiler.DecompileBaml(ms, assembly.FileName, new ConnectMethodDecompiler(assembly), new AssemblyResolver(assembly));
}
catch (XamlXmlWriterException) { } // ignore XAML writer exceptions
if (xaml != null) {
File.WriteAllText(Path.Combine(options.SaveAsProjectDirectory, Path.ChangeExtension(fileName, ".xaml")), xaml);
yield return Tuple.Create("Page", Path.ChangeExtension(fileName, ".xaml"));
continue;
}
// TODO implement extension point
// var decompiler = Baml.BamlResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assembly.FileName);
// string xaml = null;
// try {
// xaml = decompiler.DecompileBaml(ms, assembly.FileName, new ConnectMethodDecompiler(assembly), new AssemblyResolver(assembly));
// }
// catch (XamlXmlWriterException) { } // ignore XAML writer exceptions
// if (xaml != null) {
// File.WriteAllText(Path.Combine(options.SaveAsProjectDirectory, Path.ChangeExtension(fileName, ".xaml")), xaml);
// yield return Tuple.Create("Page", Path.ChangeExtension(fileName, ".xaml"));
// continue;
// }
}
using (FileStream fs = new FileStream(Path.Combine(options.SaveAsProjectDirectory, fileName), FileMode.Create, FileAccess.Write)) {
entryStream.CopyTo(fs);

1
ILSpy/ILSpy.csproj

@ -93,7 +93,6 @@ @@ -93,7 +93,6 @@
</Compile>
<Compile Include="AssemblyList.cs" />
<Compile Include="AssemblyListManager.cs" />
<Compile Include="BamlDecompiler.cs" />
<Compile Include="CommandLineArguments.cs" />
<Compile Include="Commands.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />

2
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -69,7 +69,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// This method is called on the main thread when only a single item is selected.
/// If it returns false, normal decompilation is used to view the item.
/// </summary>
internal virtual bool View(TextView.DecompilerTextView textView)
public virtual bool View(TextView.DecompilerTextView textView)
{
return false;
}

2
ILSpy/TreeNodes/ResourceEntryNode.cs

@ -132,7 +132,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -132,7 +132,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
get { return Images.ResourceImage; }
}
internal override bool View(DecompilerTextView textView)
public override bool View(DecompilerTextView textView)
{
try {
AvalonEditTextOutput output = new AvalonEditTextOutput();

2
ILSpy/TreeNodes/ResourceTreeNode.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -78,7 +78,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
internal override bool View(DecompilerTextView textView)
public override bool View(DecompilerTextView textView)
{
EmbeddedResource er = r as EmbeddedResource;
if (er != null) {

2
ILSpy/TreeNodes/XamlResourceNode.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy.Xaml @@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy.Xaml
{
}
internal override bool View(DecompilerTextView textView)
public override bool View(DecompilerTextView textView)
{
AvalonEditTextOutput output = new AvalonEditTextOutput();
IHighlightingDefinition highlighting = null;

Loading…
Cancel
Save