6

Given a Type object in .NET, is it possible for me to get the source code filename? I know this would only be available in Debug builds and that's fine, I also know that I can use the StackTrace object to get the filename for a particular frame in a callstack, but that's not what I want.

But is it possible for me to get the source code filename for a given System.Type?

Einar Egilsson
  • 3,438
  • 9
  • 36
  • 47
  • possible duplicate of [How to get the source file name and the line number of a type member?](http://stackoverflow.com/questions/126094/how-to-get-the-source-file-name-and-the-line-number-of-a-type-member) – Darin Dimitrov Oct 28 '10 at 07:29
  • Why do you want it? Most of the reasons I can think of would be solved by tools like Symbol/Source servers... – Dan Puzey Oct 28 '10 at 22:16

3 Answers3

7

I encountered a similar problem. I needed to found the file name and line number of a specific method with only the type of the class and the method name. I'm on an old mono .net version (unity 4.6). I used the library cecil, it provide some helper to analyse your pbd (or mdb for mono) and analyse debug symbols. https://github.com/jbevain/cecil/wiki

For a given type and method:

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

I found this solution:

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

I know it's a bit late :) but I hope this will help somebody!

Tichau
  • 305
  • 2
  • 11
3

I've used code like this to get a source file and line number from the method that is running:

//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 + ")";
j0k
  • 22,600
  • 28
  • 79
  • 90
3

Considering that at least C# supports partial class declarations (say, public partial class Foo in two source code files), what would "the source code filename for a given System.Type" mean? If a type declaration is spread out over multiple source code files within the same assembly, there is no single point in the source code where the declaration begins.

@Darin Dimitrov: This doesn't seem like a duplicate of "How to get the source file name and the line number of a type member?" to me, since that is about a type member, whereas this question is about a type.

user
  • 6,897
  • 8
  • 43
  • 79
  • We were doing a massive refactoring of namespaces and things like that at my company and I wanted to write a unit test that checked whether namespace corresponded to file location. We're actually done now so I don't need it anymore but the question still stands, there must be some way to access the pdb and get this info? As for partial classes, then we should be able to get both filenames. – Einar Egilsson Nov 08 '10 at 07:27
  • @Michael it would be `string[]` :-D – Simon_Weaver Jul 17 '13 at 12:22
  • @Simon_Weaver Well, duh, but the OP asked for "***the*** source code filename for a given System.Type" :-) – user Jul 17 '13 at 12:32