C# 从调试生成中的类型获取文件的源代码文件名

C# 从调试生成中的类型获取文件的源代码文件名,c#,.net,debug-symbols,C#,.net,Debug Symbols,给定.NET中的类型对象,我是否可以获取源代码文件名?我知道这只在调试版本中可用,这很好,我还知道我可以使用StackTrace对象获取调用堆栈中特定帧的文件名,但这不是我想要的 但是,我是否可以获取给定System.Type的源代码文件名?考虑到至少C#支持部分类声明(例如,在两个源代码文件中,public partial class Foo),那么“给定System.Type的源代码文件名”是什么意思?如果类型声明分布在同一程序集中的多个源代码文件上,则源代码中没有声明开始的单一点 @Dar

给定.NET中的类型对象,我是否可以获取源代码文件名?我知道这只在调试版本中可用,这很好,我还知道我可以使用StackTrace对象获取调用堆栈中特定帧的文件名,但这不是我想要的


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

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


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

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

//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 + ")";

我遇到了类似的问题。我需要找到一个特定方法的文件名和行号,其中只包含类的类型和方法名。我使用的是旧的mono.net版本(unity 4.6)。我使用了cecil库,它提供了一些帮助来分析pbd(或mono的mdb)和分析调试符号

对于给定类型和方法:

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;
        }
    }
}
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.Empty;
int lineNumber=-1;
Mono.Cecil.TypeDefinition TypeDefinition=assemblyDefinition.MainModule.GetType(myType.FullName);
for(int index=0;index0)
{
Mono.Cecil.Cil.SequencePoint SequencePoint=methodBody.Instructions[0]。SequencePoint;
fileName=sequencePoint.Document.Url;
lineNumber=sequencePoint.Stratline;
}
}
}

我知道有点晚了:)但我希望这能帮助别人

你为什么想要它的可能副本?我能想到的大多数原因都可以通过诸如Symbol/Source Server之类的工具来解决……我们在我的公司进行了大规模的名称空间重构之类的工作,我想编写一个单元测试,检查名称空间是否与文件位置对应。我们现在实际上已经完成了,所以我不再需要它了,但问题仍然存在,一定有办法访问pdb并获取此信息?至于分部类,那么我们应该能够同时获得两个文件名。@Michael应该是
string[]
:-D@Simon_Weaver嗯,没错,但OP要求提供“给定系统的源代码文件名。键入”:-)