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(); }
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)); }
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); }
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); } }