- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前正在尝试从 IL 字节码和 PDB 文件中检索源代码,我已经到了可以从 IL 和反射生成源代码的地步我知道局部变量名称包含在 pdb 文件中。我的问题是我怎样才能找回它?我应该使用什么库来处理 pdb 文件(如果有)或者我应该自己编写代码?在哪里可以找到有关 pdb 文件格式的信息?目前在生成的源代码中,我正在为局部变量使用自动生成的值,但我想更改它,因为我相信如果您有 pdb 文件可供使用,则可以找到该信息。我试图查看谷歌,但没有找到任何有用的信息。
提前感谢您的回复;)
最佳答案
下面是如何使用 System.Diagnostics.SymbolStore
中的类型从 MethodInfo 中读取局部变量名称:
public class LocalVariableNameReader
{
Dictionary<int, string> _names = new Dictionary<int, string> ();
public string this [int index]
{
get
{
if (!_names.ContainsKey (index)) return null;
return _names [index];
}
}
public LocalVariableNameReader (MethodInfo m)
{
ISymbolReader symReader = SymUtil.GetSymbolReaderForFile (m.DeclaringType.Assembly.Location, null);
ISymbolMethod met = symReader.GetMethod (new SymbolToken (m.MetadataToken));
VisitLocals (met.RootScope);
}
void VisitLocals (ISymbolScope iSymbolScope)
{
foreach (var s in iSymbolScope.GetLocals ()) _names [s.AddressField1] = s.Name;
foreach (var c in iSymbolScope.GetChildren ()) VisitLocals (c);
}
}
SymUtil
类来自 this example .
编辑:以上链接已损坏。来自谷歌缓存:
A long time ago I was looking on how to process pdb files in order to get additional information that reflection simply could not provide. Now I stumped over a 5 year old post of Mike Stall (here) and suddenly all became clear. I’ve put together a small example which uses .net 4.0 to read the method body code as it is in the source code from where the assembly was compiled. Mind you that in order for this to work you have to have the pdb of the assembly available. Also please make sure you add a refference to ISymWrapper and your project is targeting .Net 4.0 framework, not .Net 4.0 Client.
using System;
using System.Diagnostics.SymbolStore;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
namespace PdbTest
{
class Program
{
static void Main(string[] args)
{
Assembly ass = Assembly.GetExecutingAssembly();
ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(ass.Location, null);
MethodInfo m = ass.GetType("PdbTest.TestClass").GetMethod("GetStringRepresentation");
ISymbolMethod met = symreader.GetMethod(new SymbolToken(m.MetadataToken));
int count = met.SequencePointCount;
ISymbolDocument[] docs = new ISymbolDocument[count];
int[] offsets = new int[count];
int[] lines = new int[count];
int[] columns = new int[count];
int[] endlines = new int[count];
int[] endcolumns = new int[count];
met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);
StreamReader reader = new StreamReader(docs[0].URL);
string[] linesOfCode = reader.ReadToEnd().Split('n');
reader.Close();
Console.WriteLine("The content of method PdbTest.TestClass.GetStringRepresentation");
for (int i = lines[0]; i < endlines[count - 1] - 1; i++)
{
Console.WriteLine(linesOfCode[i]);
}
}
}
#region test class
public enum MyEnum
{
Apples,
Oranges
}
public partial class TestClass
{
public string GetStringRepresentation(MyEnum e)
{
MyEnum e2 = MyEnum.Apples;
return e.ToString() + e2.ToString();
}
}
#endregion test class
#region Get a symbol reader for the given module
// Encapsulate a set of helper classes to get a symbol reader from a file.
// The symbol interfaces require an unmanaged metadata interface.
static class SymUtil
{
static class NativeMethods
{
[DllImport("ole32.dll")]
public static extern int CoCreateInstance(
[In] ref Guid rclsid,
[In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkOuter,
[In] uint dwClsContext,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out Object ppv);
}
// Wrapper.
public static ISymbolReader GetSymbolReaderForFile(string pathModule, string searchPath)
{
return SymUtil.GetSymbolReaderForFile(
new System.Diagnostics.SymbolStore.SymBinder(), pathModule, searchPath);
}
// We demand Unmanaged code permissions because we're reading from the file
// system and calling out to the Symbol Reader
// @TODO - make this more specific.
[System.Security.Permissions.SecurityPermission(
System.Security.Permissions.SecurityAction.Demand,
Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
public static ISymbolReader GetSymbolReaderForFile(
System.Diagnostics.SymbolStore.SymBinder binder, string pathModule, string searchPath)
{
// Guids for imported metadata interfaces.
Guid dispenserClassID = new Guid(0xe5cb7a31, 0x7512, 0x11d2, 0x89,
0xce, 0x00, 0x80, 0xc7, 0x92, 0xe5, 0xd8); // CLSID_CorMetaDataDispenser
Guid dispenserIID = new Guid(0x809c652e, 0x7396, 0x11d2, 0x97, 0x71,
0x00, 0xa0, 0xc9, 0xb4, 0xd5, 0x0c); // IID_IMetaDataDispenser
Guid importerIID = new Guid(0x7dac8207, 0xd3ae, 0x4c75, 0x9b, 0x67,
0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44); // IID_IMetaDataImport
// First create the Metadata dispenser.
object objDispenser;
NativeMethods.CoCreateInstance(ref dispenserClassID, null, 1,
ref dispenserIID, out objDispenser);
// Now open an Importer on the given filename. We'll end up passing this importer
// straight through to the Binder.
object objImporter;
IMetaDataDispenser dispenser = (IMetaDataDispenser)objDispenser;
dispenser.OpenScope(pathModule, 0, ref importerIID, out objImporter);
IntPtr importerPtr = IntPtr.Zero;
ISymbolReader reader;
try
{
// This will manually AddRef the underlying object, so we need to
// be very careful to Release it.
importerPtr = Marshal.GetComInterfaceForObject(objImporter,
typeof(IMetadataImport));
reader = binder.GetReader(importerPtr, pathModule, searchPath);
}
finally
{
if (importerPtr != IntPtr.Zero)
{
Marshal.Release(importerPtr);
}
}
return reader;
}
}
#region Metadata Imports
// We can use reflection-only load context to use reflection to query for
// metadata information rather
// than painfully import the com-classic metadata interfaces.
[Guid("809c652e-7396-11d2-9771-00a0c9b4d50c"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComVisible(true)]
interface IMetaDataDispenser
{
// We need to be able to call OpenScope, which is the 2nd vtable slot.
// Thus we need this one placeholder here to occupy the first slot..
void DefineScope_Placeholder();
//STDMETHOD(OpenScope)( // Return code.
//LPCWSTR szScope, // [in] The scope to open.
// DWORD dwOpenFlags, // [in] Open mode flags.
// REFIID riid, // [in] The interface desired.
// IUnknown **ppIUnk) PURE; // [out] Return interface on success.
void OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] String szScope,
[In] Int32 dwOpenFlags, [In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.IUnknown)] out Object punk);
// Don't need any other methods.
}
// Since we're just blindly passing this interface through managed code to the Symbinder,
// we don't care about actually importing the specific methods.
// This needs to be public so that we can call Marshal.GetComInterfaceForObject() on
// it to get the underlying metadata pointer.
[Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComVisible(true)]
[CLSCompliant(true)]
public interface IMetadataImport
{
// Just need a single placeholder method so that it doesn't complain
// about an empty interface.
void Placeholder();
}
#endregion
#endregion Get a symbol reader for the given module
}
关于c# - 从 PDB 文件中检索局部变量名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6166767/
有人可以解释一下为什么我得到: "use of unassigned local variable number_of_column" for: if (i f.LastWriteTime).Fir
我正在尝试为查询定义和初始化 MySQL 变量。 我有以下几点: declare @countTotal int; SET @countTotal = select COUNT(*) from nG
局部变量由小写字母或下划线(_)开头.局部变量不像全局和实变量一样在初始化前含nil值. ruby>$foo nil ruby>@foo nil ruby>foo ER
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
当我单击 Login 类上的注册按钮时,出现 nullpointerException,它给出了该错误。我尝试修改本地和全局变量,但似乎没有任何方法可以修复该错误,我可能在 onClickListen
我之前看过一些关于此的帖子,但我一直无法找到有关 actionListeners 的帖子。我正在尝试使用 JButton 数组创建井字棋。如果可能的话,如何在使用 for 循环临时变量的同时向它们添加
我试图找出一种将 getView() 方法中的位置变量传递给内部类的方法。但是,这不能是最终变量,因为 ListView 中的每个项目都会调用 getView() ,因此它会发生变化。有没有办法访问该
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
这对你们中的某些人来说似乎微不足道,但我对下面的这两个示例感到困惑。 int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int i
这个问题在这里已经有了答案: How do JavaScript closures work? (86 个答案) 关闭 7 年前。 所以我正在复习我的 vanilla Javascript,专门用于
我正在将mockito与spring(java 1.8)一起使用,并且我尝试在我的Answer对象中使用局部变量: public IProductDTO productForMock = null;
是否可以在java中为静态方法注入(inject)局部变量,比如 @Inject public void someMethod() { @MyInjectQualifier MyObjectC
我有一个函数,每 2 秒被重复调用一次,每次从屏幕顶部带来一个具有随机纹理的球。我希望能够在 touchesBegan 中使用这个球,但我不能,因为它是一个局部变量。我试过将它设为全局变量,但这给了我
这是(我假设)一个基本问题,但我似乎无法弄清楚。 给定以下代码: from src.Globals import * import pygame # Used to manage how fast t
这就是我在循环中引用全局变量的方法。 _.forEach(myTableName.detailsObjects, function (o, key) { if
我已经创建了一些代码: import numpy as np Length=(2.7)*10**-3 Nx=4 x = np.linspace(0, Length, Nx+1) # mes
如何获取局部变量? 我有这个代码 if (ctrl is Control) { Control c = (Control)ctrl; foreach (object innerCtrl
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Difference between class variables and class instance
我正在学习 Python 3,我有一个关于 Python 中面向对象编程的非常基本的问题。这是我的代码。 class pet: number_of_legs = 0 def count
我有以下代码块: class Student{ int age; //instance variable String name; //instance varia
我是一名优秀的程序员,十分优秀!