1

I have an external text file, it is C# class with some logic. In my main program I need to compile that file and run whatever method of that class.

Example of the external class:

using System;

public class DymamicClass
{
    public string TestValue()
    {
        var items = new string[] { "item1", "item2" };
        return items[9];
    }
}

For loading external file I use these steps:

CSharpCodeProvider Compiler = new CSharpCodeProvider();
List<string> importDlls = new List<string>(new string[] { "System.dll", "System.Data.dll" });

CompilerParameters compilerPars = new CompilerParameters(importDlls.ToArray());
compilerPars.GenerateInMemory = true;
compilerPars.IncludeDebugInformation = true;
compilerPars.CompilerOptions += " /debug:pdbonly";

string path = Assembly.GetExecutingAssembly().Location;
compilerPars.ReferencedAssemblies.Add(path);

CompilerResults Results = Compiler.CompileAssemblyFromFile(compilerPars, codePath);

After the file loaded to the program, I try to execute TestValue() method from the loaded class. There is "index was outside the bounds of the array" exception in the method. I need to get the exact line that threw exception. But instead of line "return items[9];" I always get the line "public string TestValue()".

Here is sample how I process exception:

var trace = new System.Diagnostics.StackTrace(exception, true);
if (trace.FrameCount > 0)
{
    var frame = trace.GetFrame(trace.FrameCount - 1);
    var className = frame.GetMethod().ReflectedType.Name;
    var methodName = frame.GetMethod().ToString();
    var lineNumber = frame.GetFileLineNumber();
}

How to get the right line of exception?

Anderson Pimentel
  • 5,086
  • 2
  • 32
  • 54
Artemiy
  • 43
  • 3
  • Possible duplicate of [How do I get the current line number?](https://stackoverflow.com/questions/12556767/how-do-i-get-the-current-line-number) . I realize the dynamic loading is different, but, the accepted answer should work. –  Dec 26 '18 at 18:04

1 Answers1

0

you need to get Inner Exception. Try in this way :

using System;
using System.Collections.Generic;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;

public class Folders
{

    public static void Main(string[] args)
    {
        try
        {
            var source = @"using System;

public static class DymamicClass
{
    public static string TestValue()
    {
        var items = new string[] { ""item1"", ""item2"" };
            return items[9];
        }

    }";
            CSharpCodeProvider Compiler = new CSharpCodeProvider();
            List<string> importDlls = new List<string>(new string[] { "System.dll", "System.Data.dll" });

            CompilerParameters compilerPars = new CompilerParameters(importDlls.ToArray());
            compilerPars.GenerateInMemory = true;
            compilerPars.IncludeDebugInformation = true;
            compilerPars.CompilerOptions += " /debug:pdbonly";

            string path = Assembly.GetExecutingAssembly().Location;
            compilerPars.ReferencedAssemblies.Add(path);

            CompilerResults Results = Compiler.CompileAssemblyFromSource(compilerPars, source);

            Assembly assembly = Results.CompiledAssembly;
            Type program = assembly.GetType("DymamicClass");
            MethodInfo main = program.GetMethod("TestValue");
            main.Invoke(null, null);
        }
        catch (Exception e)
        {
            var trace = new System.Diagnostics.StackTrace(e.InnerException, true);
            if (trace.FrameCount > 0)
            {
                var frame = trace.GetFrame(trace.FrameCount - 1);
                var className = frame.GetMethod().ReflectedType.Name;
                var methodName = frame.GetMethod().ToString();
                var lineNumber = frame.GetFileLineNumber();
            }
        }
    }
}
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72