Пример #1
0
        internal static async void GeneratePdbForAssembly(LoadedAssembly assembly)
        {
            var file = assembly.GetPEFileOrNull();

            if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))
            {
                await MessageBox.Show($"Cannot create PDB file for {Path.GetFileName(assembly.FileName)}, because it does not contain a PE Debug Directory Entry of type 'CodeView'.");

                return;
            }
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.Title           = "Save file";
            dlg.InitialFileName = DecompilerTextView.CleanUpName(assembly.ShortName) + ".pdb";
            dlg.Filters         = new List <FileDialogFilter> {
                new FileDialogFilter {
                    Name = "Portable PDB", Extensions = { "pdb" }
                }, new FileDialogFilter {
                    Name = "All files", Extensions = { "*" }
                }
            };
            dlg.Directory = Path.GetDirectoryName(assembly.FileName);
            string fileName = await dlg.ShowAsync(App.Current.GetMainWindow());

            if (string.IsNullOrEmpty(fileName))
            {
                return;
            }
            DecompilationOptions options = new DecompilationOptions();

            MainWindow.Instance.TextView.RunWithCancellation(ct => Task <AvaloniaEditTextOutput> .Factory.StartNew(() => {
                AvaloniaEditTextOutput output = new AvaloniaEditTextOutput();
                Stopwatch stopwatch           = Stopwatch.StartNew();
                using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write)) {
                    try {
                        var decompiler = new CSharpDecompiler(file, assembly.GetAssemblyResolver(), options.DecompilerSettings);
                        PortablePdbWriter.WritePdb(file, decompiler, options.DecompilerSettings, stream);
                    } catch (OperationCanceledException) {
                        output.WriteLine();
                        output.WriteLine("Generation was cancelled.");
                        throw;
                    }
                }
                stopwatch.Stop();
                output.WriteLine("Generation complete in " + stopwatch.Elapsed.TotalSeconds.ToString("F1") + " seconds.");
                output.WriteLine();
                output.AddButton(null, "Open Explorer", delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
                output.WriteLine();
                return(output);
            }, ct)).Then(output => MainWindow.Instance.TextView.ShowText(output)).HandleExceptions();
        }
Пример #2
0
        internal static void GeneratePdbForAssembly(LoadedAssembly assembly)
        {
            var file = assembly.GetPEFileOrNull();

            if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))
            {
                MessageBox.Show(string.Format(Resources.CannotCreatePDBFile, Path.GetFileName(assembly.FileName)));
                return;
            }
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.FileName         = DecompilerTextView.CleanUpName(assembly.ShortName) + ".pdb";
            dlg.Filter           = Resources.PortablePDBPdbAllFiles;
            dlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName);
            if (dlg.ShowDialog() != true)
            {
                return;
            }
            DecompilationOptions options = new DecompilationOptions();
            string fileName = dlg.FileName;

            Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task <AvalonEditTextOutput> .Factory.StartNew(() => {
                AvalonEditTextOutput output = new AvalonEditTextOutput();
                Stopwatch stopwatch         = Stopwatch.StartNew();
                using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    try
                    {
                        var decompiler = new CSharpDecompiler(file, assembly.GetAssemblyResolver(), options.DecompilerSettings);
                        PortablePdbWriter.WritePdb(file, decompiler, options.DecompilerSettings, stream);
                    }
                    catch (OperationCanceledException)
                    {
                        output.WriteLine();
                        output.WriteLine(Resources.GenerationWasCancelled);
                        throw;
                    }
                }
                stopwatch.Stop();
                output.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString("F1"));
                output.WriteLine();
                output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
                output.WriteLine();
                return(output);
            }, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions();
        }
        private void TestGeneratePdb([CallerMemberName] string testName = null)
        {
            const PdbToXmlOptions options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.ThrowOnError | PdbToXmlOptions.IncludeTokens | PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.IncludeMethodSpans;

            string    xmlFile    = Path.Combine(TestCasePath, testName + ".xml");
            string    xmlContent = File.ReadAllText(xmlFile);
            XDocument document   = XDocument.Parse(xmlContent);
            var       files      = document.Descendants("file").ToDictionary(f => f.Attribute("name").Value, f => f.Value);

            Tester.CompileCSharpWithPdb(Path.Combine(TestCasePath, testName + ".expected"), files);

            string peFileName       = Path.Combine(TestCasePath, testName + ".expected.dll");
            string pdbFileName      = Path.Combine(TestCasePath, testName + ".expected.pdb");
            var    moduleDefinition = new PEFile(peFileName);
            var    resolver         = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
            var    decompiler       = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());

            using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, testName + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                pdbStream.SetLength(0);
                PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true);
                pdbStream.Position = 0;
                using (Stream peStream = File.OpenRead(peFileName))
                    using (Stream expectedPdbStream = File.OpenRead(pdbFileName))
                    {
                        using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(pdbFileName, ".xml"), false, Encoding.UTF8))
                        {
                            PdbToXmlConverter.ToXml(writer, expectedPdbStream, peStream, options);
                        }
                        peStream.Position = 0;
                        using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(xmlFile, ".generated.xml"), false, Encoding.UTF8))
                        {
                            PdbToXmlConverter.ToXml(writer, pdbStream, peStream, options);
                        }
                    }
            }
            string expectedFileName = Path.ChangeExtension(xmlFile, ".expected.xml");

            ProcessXmlFile(expectedFileName);
            string generatedFileName = Path.ChangeExtension(xmlFile, ".generated.xml");

            ProcessXmlFile(generatedFileName);
            Assert.AreEqual(Normalize(expectedFileName), Normalize(generatedFileName));
        }
Пример #4
0
        int GeneratePdbForAssembly(string assemblyFileName, string pdbFileName, CommandLineApplication app)
        {
            var module = new PEFile(assemblyFileName,
                                    new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read),
                                    PEStreamOptions.PrefetchEntireImage,
                                    metadataOptions: MetadataReaderOptions.None);

            if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(module))
            {
                app.Error.WriteLine($"Cannot create PDB file for {assemblyFileName}, because it does not contain a PE Debug Directory Entry of type 'CodeView'.");
                return(ProgramExitCodes.EX_DATAERR);
            }

            using (FileStream stream = new FileStream(pdbFileName, FileMode.OpenOrCreate, FileAccess.Write)) {
                var decompiler = GetDecompiler(assemblyFileName);
                PortablePdbWriter.WritePdb(module, decompiler, GetSettings(), stream);
            }

            return(0);
        }
Пример #5
0
        public void CustomPdbId()
        {
            // Generate a PDB for an assembly using a randomly-generated ID, then validate that the PDB uses the specified ID
            (string peFileName, string pdbFileName) = CompileTestCase(nameof(CustomPdbId));

            var moduleDefinition = new PEFile(peFileName);
            var resolver         = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Metadata.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchEntireImage);
            var decompiler       = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());
            var expectedPdbId    = new BlobContentId(Guid.NewGuid(), (uint)Random.Shared.Next());

            using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, nameof(CustomPdbId) + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                pdbStream.SetLength(0);
                PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true, pdbId: expectedPdbId);

                pdbStream.Position = 0;
                var metadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader();
                var generatedPdbId = new BlobContentId(metadataReader.DebugMetadataHeader.Id);

                Assert.AreEqual(expectedPdbId.Guid, generatedPdbId.Guid);
                Assert.AreEqual(expectedPdbId.Stamp, generatedPdbId.Stamp);
            }
        }