获取动态加载的程序集的异常行号

时间:2018-12-26 17:52:06

标签: c# .net

我有一个外部文本文件,它是带有某些逻辑的C#类。在我的主程序中,我需要编译该文件并运行该类的任何方法。

外部类的示例:

using System;

public class DymamicClass
{
    public 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.CompileAssemblyFromFile(compilerPars, codePath);

文件加载到程序后,我尝试从加载的类执行TestValue()方法。该方法中存在“索引超出数组范围”的异常。我需要获得引发异常的确切行。但是,而不是“ return items [9];”行我总是得到“公共字符串TestValue()”行。

以下是我如何处理异常的示例:

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

如何获得正确的例外情况?

1 个答案:

答案 0 :(得分:0)

您需要获取内部异常。以这种方式尝试:

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