在捕获块中,如何获得抛出异常的行号?


您可以包含与程序集关联的. pdb符号文件,其中包含元数据信息,当抛出异常时,它将在异常起源的堆栈跟踪中包含完整的信息。它将包含堆栈中每个方法的行号。


简单的方法,使用exception . tostring()函数,它将返回异常描述之后的行。

您还可以检查程序调试数据库,因为它包含关于整个应用程序的调试信息/日志。


如果您需要的行号不仅仅是从Exception中获得的格式化堆栈跟踪。你可以使用StackTrace类:

try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}

请注意,这仅在程序集有pdb文件可用时才有效。


在全球。resx文件中有一个名为Application_Error的事件

每当发生错误时,它就会触发,您可以很容易地获得有关错误的任何信息,并将其发送到错误跟踪电子邮件。

此外,我认为所有你需要做的是编译全局。Resx并将其dll's (2 dll)添加到您的bin文件夹,它将工作!


如果你没有。pbo文件:

C#

public int GetLineNumber(Exception ex)
{
    var lineNumber = 0;
    const string lineSearch = ":line ";
    var index = ex.StackTrace.LastIndexOf(lineSearch);
    if (index != -1)
    {
        var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
        if (int.TryParse(lineNumberText, out lineNumber))
        {
        }
    }
    return lineNumber;
}

Vb.net

Public Function GetLineNumber(ByVal ex As Exception)
    Dim lineNumber As Int32 = 0
    Const lineSearch As String = ":line "
    Dim index = ex.StackTrace.LastIndexOf(lineSearch)
    If index <> -1 Then
        Dim lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length)
        If Int32.TryParse(lineNumberText, lineNumber) Then
        End If
    End If
    Return lineNumber
End Function

或者作为Exception类的扩展

public static class MyExtensions
{
    public static int LineNumber(this Exception ex)
    {
        var lineNumber = 0;
        const string lineSearch = ":line ";
        var index = ex.StackTrace.LastIndexOf(lineSearch);
        if (index != -1)
        {
            var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
            if (int.TryParse(lineNumberText, out lineNumber))
            {
            }
        }
        return lineNumber;
    }
}   

更新到答案

    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(st.FrameCount-1);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();

看看这个

StackTrace st = new StackTrace(ex, true);
//Get the first stack frame
StackFrame frame = st.GetFrame(0);

//Get the file name
string fileName = frame.GetFileName();

//Get the method name
string methodName = frame.GetMethod().Name;

//Get the line number from the stack frame
int line = frame.GetFileLineNumber();

//Get the column number
int col = frame.GetFileColumnNumber();

我尝试使用@davy-c的解决方案,但有一个异常“系统。输入字符串的格式不正确。’”,这是由于仍然有文本超过行号,我修改了他发布的代码,并提出:

int line = Convert.ToInt32(objErr.ToString().Substring(objErr.ToString().IndexOf("line")).Substring(0, objErr.ToString().Substring(objErr.ToString().IndexOf("line")).ToString().IndexOf("\r\n")).Replace("line ", ""));

这适用于我在VS2017 c#。


扩展方法

static class ExceptionHelpers
{
    public static int LineNumber(this Exception ex)
    {
        int n;
        int i = ex.StackTrace.LastIndexOf(" ");
        if (i > -1)
        {
            string s = ex.StackTrace.Substring(i + 1);
            if (int.TryParse(s, out n))
                return n;
        }
        return -1;
    }
}

使用

try
{
    throw new Exception("A new error happened");
}
catch (Exception ex)
{
    //If error in exception LineNumber() will be -1
    System.Diagnostics.Debug.WriteLine("[" + ex.LineNumber() + "] " + ex.Message);
}

为我工作:

var st = new StackTrace(e, true);

// Get the bottom stack frame
var frame = st.GetFrame(st.FrameCount - 1);
// Get the line number from the stack frame
var line = frame.GetFileLineNumber();
var method = frame.GetMethod().ReflectedType.FullName;
var path = frame.GetFileName();

我添加了一个扩展到Exception,它返回行,列,方法,文件名和消息:

public static class Extensions
{
    public static string ExceptionInfo(this Exception exception)
    {

        StackFrame stackFrame = (new StackTrace(exception, true)).GetFrame(0);
        return string.Format("At line {0} column {1} in {2}: {3} {4}{3}{5}  ",
           stackFrame.GetFileLineNumber(), stackFrame.GetFileColumnNumber(),
           stackFrame.GetMethod(), Environment.NewLine, stackFrame.GetFileName(),
           exception.Message);

    }
}

如果生成异常的库是用调试符号编译的,那么行号将包含在堆栈跟踪中。这可以是一个单独的文件(*.pdb),也可以嵌入到库中。

对于.NET Core、.NET 5及更高版本,要在发布版本中拥有完整的异常行号,请按如下方式配置项目:

<PropertyGroup>    
  <DebugSymbols>true</DebugSymbols>
  <DebugType>embedded</DebugType>

    <!-- Only enable the following if the line numbers mismatch -->
    <!--<Optimize>false</Optimize>-->
    
    <!--
      Additional properties which may impact how printed line numbers match the source code line numbers are listed here:
      https://learn.microsoft.com/en-us/dotnet/core/run-time-config/compilation
    -->
</PropertyGroup>

上面的配置将在构建的文件中直接包含调试符号,这些符号可以作为块发布。

上面的替代方法是将调试包与主要的nuget包一起恢复,目前还不支持:https://github.com/NuGet/Home/issues/9667

现在获取异常行号:

try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}

如果你的堆栈跟踪大于1,它应该是:

var st = new StackTrace(es, true);
// Get the top stack frame
var frame = st.GetFrame(st.FrameCount - 1);

//从栈帧中获取行号 var line = frame.GetFileLineNumber();


Convert.ToInt32(ex.StackTrace.Substring(ex.StackTrace.LastIndexOf(' ')));  

这将给出异常行no。