首页 > 解决方案 > 获取动态加载程序集的异常行号

问题描述

我有一个外部文本文件,它是具有一些逻辑的 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();
}

如何获得正确的异常线?

标签: c#.net

解决方案


你需要得到内部异常。以这种方式尝试:

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

推荐阅读