如何在C#中获得异常的确切位置,这可以在VB.net中完成



首先
我之前试过发布这个问题,但没有正确解释,这只是让人困惑。所以我删除了旧问题,试着用一个完全不同的标题重新写一遍。

而且我搜索过堆栈溢出,有相关的问题,但没有一个回答这个问题。如果你能提供任何帮助,我将不胜感激提供的其他stackerflow问题的答案并不能解决编译器和dotfuscator更改行号的问题。我正在寻找一种在C#程序中实现下面VB解决方案的方法

我的测试系统:
-Windows 10
-VS202
-C#
-Net Framework 4.8
-WinForms

我正在努力实现的目标:
我们正在尝试在C#中构建一个错误报告系统,该系统将给出引发异常的确切行号。它需要使用已编译的release.exe文件在VB.net中很容易做到这一点,但我在C#中找不到实现这一点的方法。

以下是如何在VB.net中获得准确位置:

10:     On Error Resume Next
20:     Err.Raise(60000)
' Returns 20.
30:     MsgBox(Erl())

上面的代码来自这里的Microsoft文档,显示了从VB6继承的ErrObject.Ell属性的用法。当我还是一名VB6程序员时,我使用该系统建立了广泛的错误报告功能。这是一个非常有用的工具,可以让世界上的任何最终用户向母船(开发人员)报告详细的错误信息。这使我们能够迅速了解问题并进行必要的重新考虑。

当然最好从一开始就消除错误,但当全世界有一百万用户在不同版本的Windows上下载共享软件时,会有一些错误在测试版中不会出现。

不幸的是,我在C#中找不到任何方法在代码行的开头添加数字标记,比如上面的10:、20:、30:。这些不是Visual Studio的行号。。。它们由程序员键入,以标记代码中的每一行,如Microsoft文档中所述。我也没有找到任何方法让微软ErrObject在C#中工作,就像它在VB.net中一样

以下是我在C#中尝试的内容:
以下是测试代码:

private void button2_Click(object sender, EventArgs e)
{
try
{
int x = 10;      // This is line 38 in the editor window
int y = 0;
int z = 0;
z = x / y;       // This is line 41,throwing the exception (divide by zero)
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

问题:
ex.ToString()总是返回try块的第一行(在本例中为第38行),而不是返回触发错误的实际行(第41行)。关于堆栈溢出的其他答案也是如此,包括StackTrace等。

我的问题:
在C#中有没有一种方法可以像在VB.net中那样获得引发异常的确切代码行?如果是,如何?

一个可能的解决方案
有人建议,可以每隔一行代码增加一个整数变量,然后报告该整数值,但出现异常。我很欣赏这种创造性思维,但我希望也会有其他想法。谢谢

谢谢
如能提供任何帮助,我们将不胜感激。

好的。。。我们有解决方案您可以运行经过优化的编译器,然后运行Dotfuscator,仍然可以获得System.Exception类报告的确切错误行号而且。。。没有PDB文件可以帮助黑客破解你的软件。

只需将调试信息设置为";嵌入式">

.Net Framework 4.8指令的说明(截至VS2022的当前版本):
(逐步帮助新人)

  • 右键单击您的项目并选择"属性">
  • 在Properties(属性)窗口的左侧面板中;构建">
  • 确保";优化代码";被选中(或不被选中…这是您的选择)
  • 单击";高级";按钮,位于屏幕右下角
  • 在Advanced(高级)窗口中,向下大约2/3,您将看到";调试信息:;带有下拉框
  • 选择";嵌入式";并点击";OK";。Advanced(高级)窗口将消失

.Net 6.0的说明(截至VS2022的当前版本):

  • 右键单击您的项目并选择"属性">
  • 在Properties(属性)窗口的左侧面板中;生成>"概述">
  • 在";"优化代码";,选择";释放";(或者不…这是你的选择)
  • 直接在";优化代码,您将看到"调试符号";带有下拉框
  • 选择";嵌入DLL/EXE">
  • 关闭"项目属性"窗口

现在。。。重新生成(REbuild!)编译器优化并调试设置为嵌入式的发布版本。然后运行dotfuscator,您的dotfusatedRelease.exe仍将从以下代码中获得准确的行号:

catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}

很明显,这个示例是基本的,但您可以构建一个健壮的错误报告系统,其中包括system.Exception类(此处为Microsoft文档)中内置的此功能和其他功能。我们打算建立一个网站,从桌面应用程序接收信息,并将其存储到数据库中,作为基本服务票证系统的一部分。

性能测试:

我建立了一个小应用程序,运行一个简单的数学运算循环,重复200000000次,计时结果(平均3次)。结果如下:

编译器优化-调试信息设置为";无">-点模糊:
时间:4116.3毫秒(未报告行号)

编译器优化-调试信息设置为";嵌入式">-点模糊
时间:4115.9毫秒(报告的确切行号!)

希望这能帮助任何有兴趣为他们的软件创建错误报告系统的人。

祝大家好运!!

试试这个:

try
{
int x = 10;      // This is line 38 in the editor window
int y = 0;
int z = 0;
z = x / y;       // This is line 41,throwing the exception (divide by zero)
}
catch (Exception ex)
{
int CodeLine = new System.Diagnostics.StackTrace(ex, true).GetFrame(0).GetFileLineNumber();
MessageBox.Show(CodeLine.ToString());
}

从模糊代码中获取原始行号似乎是一项应由模糊处理程序处理的产品功能。或者,您可以预处理原始的.cs文件,预处理的文件将传递给模糊处理程序。例如,您的输入代码是:

34 private void button2_Click(object sender, EventArgs e)
35    {
36        try
37        {
38            int x = 10;      // This is line 38 in the editor window
39            int y = 0;
40            int z = 0;
41            z = x / y;       // This is line 41,throwing the exception (divide by zero)
42        }
43        catch (System.Exception ex)
44        {
45            MessageBox.Show(ex.ToString());
46        }
47    }

您的预处理采用上述代码并插入行号。然后将生成的代码传递给模糊处理程序。

private void button2_Click(object sender, EventArgs e)
{
int lineNumber = 36;
try
{
lineNumber = 38;
int x = 10;      // This is line 38 in the editor window
lineNumber = 39;
int y = 0;
lineNumber = 40;
int z = 0;
lineNumber = 41;
z = x / y;       // This is line 41,throwing the exception (divide by zero)
lineNumber = 42;
}
catch (System.Exception ex)
{
// decide how to handle Exceptions. Possibly wrap the exception in a new custom exception
// or write the line number and file to a log file
throw new LineNumberWrapperException(lineNumber, ex);
}
}

最新更新