c# - 获取动态加载程序集的异常行号
问题描述
我有一个外部文本文件,它是具有一些逻辑的 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();
}
如何获得正确的异常线?
解决方案
你需要得到内部异常。以这种方式尝试:
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();
}
}
}
}