从调试版本中的类型获取文件的源代码文件名

时间:2010-10-28 07:23:41

标签: c# .net debug-symbols

给定.NET中的Type对象,我是否可以获取源代码文件名?我知道这只能在Debug版本中使用,这很好,我也知道我可以使用StackTrace对象来获取callstack中特定帧的文件名,但这不是我想要的。

但是我可以获取给定System.Type的源代码文件名吗?

3 个答案:

答案 0 :(得分:4)

我遇到了类似的问题。我需要找到一个特定方法的文件名和行号,只有类的类型和方法名。我正在使用旧的单声道.net版本(Unity 4.6)。我使用了库cecil,它提供了一些帮助来分析你的pbd(或mdb为单声道)并分析调试符号。 https://github.com/jbevain/cecil/wiki

对于给定的类型和方法:

System.Type myType = typeof(MyFancyClass);
string methodName = "DoAwesomeStuff";

我找到了这个解决方案:

Mono.Cecil.ReaderParameters readerParameters = new Mono.Cecil.ReaderParameters { ReadSymbols = true };
Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(string.Format("Library\\ScriptAssemblies\\{0}.dll", assemblyName), readerParameters);

string fileName = string.Empty;
int lineNumber = -1;

Mono.Cecil.TypeDefinition typeDefinition = assemblyDefinition.MainModule.GetType(myType.FullName);
for (int index = 0; index < typeDefinition.Methods.Count; index++)
{
    Mono.Cecil.MethodDefinition methodDefinition = typeDefinition.Methods[index];
    if (methodDefinition.Name == methodName)
    {
        Mono.Cecil.Cil.MethodBody methodBody = methodDefinition.Body;
        if (methodBody.Instructions.Count > 0)
        {
            Mono.Cecil.Cil.SequencePoint sequencePoint = methodBody.Instructions[0].SequencePoint;
            fileName = sequencePoint.Document.Url;
            lineNumber = sequencePoint.StartLine;
        }
    }
}

我知道这有点晚了:)但我希望这会对某人有所帮助!

答案 1 :(得分:3)

考虑到至少C#支持部分类声明(例如,两个源代码文件中的public partial class Foo),“给定System.Type的源代码文件名”是什么意思?如果类型声明分布在同一程序集中的多个源代码文件中,则声明开始的源代码中没有单个点。

@Darin Dimitrov:这似乎不像“如何获取源文件名和类型成员的行号?”的副本。对我来说,因为那是一个类型成员,而这个问题是关于类型

答案 2 :(得分:3)

我使用这样的代码从正在运行的方法中获取源文件和行号:

//must use the override with the single boolean parameter, set to true, to return additional file and line info

System.Diagnostics.StackFrame stackFrame = (new System.Diagnostics.StackTrace(true)).GetFrames().ToList().First();

//Careful:  GetFileName can return null even though true was specified in the StackTrace above.  This may be related to the OS on which this is running???

string fileName = stackFrame.GetFileName();
string process = stackFrame.GetMethod().Name + " (" + (fileName == null ? "" : fileName + " ") + fileLineNumber + ")";