Пример #1
0
        public static string DecompileCSharp(string assemblyFileName, DecompilerSettings settings = null)
        {
            if (settings == null)
            {
                settings = new DecompilerSettings();
            }
            using (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read)) {
                var module   = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
                var resolver = new UniversalAssemblyResolver(assemblyFileName, false,
                                                             module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
                resolver.AddSearchDirectory(Path.GetDirectoryName(typeof(Span <>).Assembly.Location));
                var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
                CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);
                decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAttributes());
                decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
                decompiler.AstTransforms.Insert(0, new RemoveNamespaceMy());
                decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
                var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(sortTypes: true);

                StringWriter output  = new StringWriter();
                var          visitor = new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop());
                syntaxTree.AcceptVisitor(visitor);

                string fileName = Path.GetTempFileName();
                File.WriteAllText(fileName, output.ToString());

                return(fileName);
            }
        }
Пример #2
0
        void RunInternal(string dir, string fileToRoundtrip, Action <string> testAction)
        {
            if (!Directory.Exists(TestDir))
            {
                Assert.Ignore($"Assembly-roundtrip test ignored: test directory '{TestDir}' needs to be checked out separately." + Environment.NewLine +
                              $"git clone https://github.com/icsharpcode/ILSpy-tests \"{TestDir}\"");
            }
            string inputDir      = Path.Combine(TestDir, dir);
            string decompiledDir = inputDir + "-decompiled";
            string outputDir     = inputDir + "-output";

            if (inputDir.EndsWith("TestCases"))
            {
                // make sure output dir names are unique so that we don't get trouble due to parallel test execution
                decompiledDir += Path.GetFileNameWithoutExtension(fileToRoundtrip);
                outputDir     += Path.GetFileNameWithoutExtension(fileToRoundtrip);
            }
            ClearDirectory(decompiledDir);
            ClearDirectory(outputDir);
            string projectFile = null;

            foreach (string file in Directory.EnumerateFiles(inputDir, "*", SearchOption.AllDirectories))
            {
                if (!file.StartsWith(inputDir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
                {
                    Assert.Fail($"Unexpected file name: {file}");
                }
                string relFile = file.Substring(inputDir.Length + 1);
                Directory.CreateDirectory(Path.Combine(outputDir, Path.GetDirectoryName(relFile)));
                if (relFile.Equals(fileToRoundtrip, StringComparison.OrdinalIgnoreCase))
                {
                    Console.WriteLine($"Decompiling {fileToRoundtrip}...");
                    Stopwatch w = Stopwatch.StartNew();
                    using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) {
                        PEFile module   = new PEFile(file, fileStream, PEStreamOptions.PrefetchEntireImage);
                        var    resolver = new UniversalAssemblyResolver(file, false, module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
                        resolver.AddSearchDirectory(inputDir);
                        resolver.RemoveSearchDirectory(".");
                        var decompiler = new TestProjectDecompiler(inputDir);
                        decompiler.AssemblyResolver = resolver;
                        // Let's limit the roundtrip tests to C# 7.3 for now; because 8.0 is still in preview
                        // and the generated project doesn't build as-is.
                        decompiler.Settings = new DecompilerSettings(LanguageVersion.CSharp7_3);
                        // use a fixed GUID so that we can diff the output between different ILSpy runs without spurious changes
                        decompiler.ProjectGuid = Guid.Parse("{127C83E4-4587-4CF9-ADCA-799875F3DFE6}");
                        decompiler.DecompileProject(module, decompiledDir);
                        Console.WriteLine($"Decompiled {fileToRoundtrip} in {w.Elapsed.TotalSeconds:f2}");
                        projectFile = Path.Combine(decompiledDir, module.Name + ".csproj");
                    }
                }
                else
                {
                    File.Copy(file, Path.Combine(outputDir, relFile));
                }
            }
            Assert.IsNotNull(projectFile, $"Could not find {fileToRoundtrip}");

            Compile(projectFile, outputDir);
            testAction(outputDir);
        }
Пример #3
0
        static CSharpDecompiler GetDecompiler(string assemblyFileName, string[] referencePaths)
        {
            var module   = new PEFile(assemblyFileName);
            var resolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());

            foreach (var path in referencePaths)
            {
                resolver.AddSearchDirectory(path);
            }
            return(new CSharpDecompiler(assemblyFileName, resolver, new DecompilerSettings()));
        }
Пример #4
0
        static void DecompileAsProject(string assemblyFileName, string outputDirectory, string[] referencePaths)
        {
            var decompiler = new WholeProjectDecompiler();
            var module     = new PEFile(assemblyFileName);
            var resolver   = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());

            foreach (var path in referencePaths)
            {
                resolver.AddSearchDirectory(path);
            }
            decompiler.AssemblyResolver = resolver;
            decompiler.DecompileProject(module, outputDirectory);
        }
Пример #5
0
        void RunTest(string name, string asmPath, string sourcePath)
        {
            using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read)) {
                var module   = new PEFile(asmPath, fileStream);
                var resolver = new UniversalAssemblyResolver(asmPath, false, module.Reader.DetectTargetFrameworkId());
                resolver.RemoveSearchDirectory(".");
                resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
                var    res        = module.Resources.First();
                Stream bamlStream = LoadBaml(res, name + ".baml");
                Assert.IsNotNull(bamlStream);
                XDocument document = BamlResourceEntryNode.LoadIntoDocument(module, resolver, bamlStream, CancellationToken.None);

                XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
            }
        }
Пример #6
0
 /// <summary>
 /// Instianciates a CSharpDecompiler from a given assemblyfilename and applies decompilersettings
 /// </summary>
 /// <param name="assemblyFileName">path for assemblyfile to decompile</param>
 /// <param name="settings">optional decompiler settings</param>
 /// <returns>Instance of CSharpDecompiler</returns>
 public CSharpDecompiler GetCSharpDecompiler(string assemblyFileName, DecompilerSettings settings = null)
 {
     if (settings == null)
     {
         settings = new DecompilerSettings();
     }
     using (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read))
     {
         var module   = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
         var resolver = new UniversalAssemblyResolver(assemblyFileName, false,
                                                      module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
         resolver.AddSearchDirectory(Path.GetDirectoryName(module.FullName));
         var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
         var decompiler = new CSharpDecompiler(typeSystem, settings);
         decompiler.DebugInfoProvider = DebugInfoLoader.LoadSymbols(module);
         return(decompiler);
     }
 }
        int DecompileAsProject(string assemblyFileName, string outputDirectory)
        {
            var decompiler = new WholeProjectDecompiler()
            {
                Settings = GetSettings()
            };
            var module   = new PEFile(assemblyFileName);
            var resolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());

            foreach (var path in ReferencePaths)
            {
                resolver.AddSearchDirectory(path);
            }
            decompiler.AssemblyResolver = resolver;
            decompiler.DecompileProject(module, outputDirectory);
            module.Reader.Dispose();

            return(0);
        }
Пример #8
0
        void RunTest(string name, string asmPath, string sourcePath)
        {
            using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read))
            {
                var module   = new PEFile(asmPath, fileStream);
                var resolver = new UniversalAssemblyResolver(asmPath, false, module.Reader.DetectTargetFrameworkId());
                resolver.RemoveSearchDirectory(".");
                resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
                var    res        = module.Resources.First();
                Stream bamlStream = LoadBaml(res, name + ".baml");
                Assert.IsNotNull(bamlStream);

                BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(module, resolver);
                var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings());

                XDocument document = decompiler.Decompile(bamlStream).Xaml;

                XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
            }
        }
Пример #9
0
        public static Task <string> DecompileCSharp(string assemblyFileName, DecompilerSettings settings = null)
        {
            if (settings == null)
            {
                settings = new DecompilerSettings();
            }
            using (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read))
            {
                var    module          = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
                string targetFramework = module.Metadata.DetectTargetFrameworkId();
                var    resolver        = new UniversalAssemblyResolver(assemblyFileName, false,
                                                                       targetFramework, null, PEStreamOptions.PrefetchMetadata);
                resolver.AddSearchDirectory(targetFramework.Contains(".NETFramework") ? RefAsmPath : coreRefAsmPath);
                var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
                CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);
                decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAttributes());
                decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
                decompiler.AstTransforms.Insert(0, new RemoveNamespaceMy());
                decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
                var pdbFileName = Path.ChangeExtension(assemblyFileName, ".pdb");
                if (File.Exists(pdbFileName))
                {
                    decompiler.DebugInfoProvider = DebugInfoUtils.FromFile(module, pdbFileName);
                }
                var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(sortTypes: true);

                StringWriter            output           = new StringWriter();
                CSharpFormattingOptions formattingPolicy = CreateFormattingPolicyForTests();
                var visitor = new CSharpOutputVisitor(output, formattingPolicy);
                syntaxTree.AcceptVisitor(visitor);

                string fileName = Path.GetTempFileName();
                File.WriteAllText(fileName, output.ToString());

                return(Task.FromResult(fileName));
            }
        }
Пример #10
0
 public EmbeddedAssemblyResolver(PEFile baseModule, string targetFramework)
 {
     this.baseModule = baseModule;
     _resolver       = new UniversalAssemblyResolver(baseModule.FileName, true, targetFramework, PEStreamOptions.PrefetchMetadata);
     _resolver.AddSearchDirectory(Path.GetDirectoryName(baseModule.FileName));
 }