Try/Catch 在调试中效果很好,但在 .exe 中效果不佳

Posted

技术标签:

【中文标题】Try/Catch 在调试中效果很好,但在 .exe 中效果不佳【英文标题】:Try/Catch works well in debug but not in .exe 【发布时间】:2013-09-11 15:57:47 【问题描述】:

问题上方的帖子下方有一个 TL;DR 版本。 我有一个程序引用了一个我无法管理的外部程序集。它基本上管理与 Card PinPad 读卡器的连接,并组织从所述卡中读取的信息。有一些简单的代码:

    Try
        pinpad.readcard(lecturaEntrada, lecturaSalida)
    Catch ex As Exception
        MsgBox("Failed Card read " & ex.Message)
        Exit Sub
    End Try

这里发生的是 Pinpad 等待卡片读取,用户可以通过单击设备上的取消来取消它。抛出异常,ex.message 为“用户已取消”。我很确定这是一个创建/管理的异常,因为它不是真正的系统异常。因此,我可以在每次需要时以 100% 的比率重现错误/异常。

我用它做了几次测试,每次它都抛出异常。之后,我将其导出到生产/测试电脑。只是注意到它不再起作用了。经过大量修改后,我发现在 VStudio 调试运行时运行程序,try catch 可以完美运行。每当我使用可执行文件时,无论是在目标 PC 上还是在我自己的 DEV PC 上,可执行文件 try catch 都会出错,并且不会捕获任何内容,只会导致程序崩溃。

TLDR:程序有一个 try catch 例程。它在 VS2010 调试运行时运行良好,但在您使用 .exe 时不起作用

我可以做些什么来让它工作吗?在创建可执行文件的过程中,是否有一些我不知道的幕后发生的事情正在消除程序尝试捕获的能力?

编辑:我尝试关闭优化,以管理员身份运行,但无济于事。 Google 也没有给出任何答案

编辑:这里是堆栈跟踪:

en Banorte.NET.procearExcepcion(APIException* e)
en Banorte.PinPan.PinPadVerifone.leertarjeta(hashtable parametrosEntrada, hashtable parametrosSalida)
en PruebasPinPad.form.btnPagoTDC_click(objectsender,eventargs e) en C:\VS2010\PruebasPinPad\Form.vb:linea191

也没有内部异常

编辑:我在尝试直接调试 .exe 时发现了这个堆栈跟踪:

System.AccessViolationException was unhandled
  Message=Intento de leer o escribir en la memoria protegida. A menudo, esto indica que hay otra memoria dañada.
  Source=BanortePinPad
  StackTrace:
       en std.basic_string<char,std::char_traits<char>,std::allocator<char> >.dtor(basic_string<char\,std::char_traits<char>\,std::allocator<char> >* )
       en APIException.dtor(APIException* )
       en ___CxxCallUnwindDtor(IntPtr pDtor, Void* pThis)
       en leerTarjetaEx(map<std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,std::less<std::basic_string<char\,std::char_traits<char>\,std::allocator<char> > >\,std::allocator<std::pair<std::basic_string<char\,std::char_traits<char>\,std::allocator<char> > const \,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> > > > >* mapaParametrosEntrada, map<std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> >\,std::less<std::basic_string<char\,std::char_traits<char>\,std::allocator<char> > >\,std::allocator<std::pair<std::basic_string<char\,std::char_traits<char>\,std::allocator<char> > const \,std::basic_string<char\,std::char_traits<char>\,std::allocator<char> > > > >* mapaParametrosSalida)
       en Banorte.PinPad.PinPadVerifone.leerTarjeta(Hashtable parametrosEntrada, Hashtable parametrosSalida)
       en PruebasPinPAD.Form.btnPagoTDC_Click(Object sender, EventArgs e) en C:\VS2010\PruebasPinPAD\Form.vb:línea 191
       en System.Windows.Forms.Control.OnClick(EventArgs e)
       en System.Windows.Forms.Button.OnClick(EventArgs e)
       en System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       en System.Windows.Forms.Control.WndProc(Message& m)
       en System.Windows.Forms.ButtonBase.WndProc(Message& m)
       en System.Windows.Forms.Button.WndProc(Message& m)
       en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       en System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       en System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       en System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       en System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       en System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       en Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       en Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       en Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       en PruebasPinPAD.My.MyApplication.Main(String[] Args) en 17d14f5c-a337-4978-8281-53493378c1071.vb:línea 81

这里并编辑以提高我的问题。在此先感谢您提供的任何帮助,并感谢迄今为止尝试提供帮助的任何人。我还在努力解决这个问题。

编辑:我刚刚看到调试 exe 的错误,它读取。 AccessViolationException 未处理。并且无法在受保护的内存中读/写。

【问题讨论】:

你的 main 中有 try catch 代码吗? 您能否复制并粘贴在调试模式下捕获的异常/堆栈跟踪?这可能会提供一些线索,说明为什么您的发布版本无法捕捉到这一点。记住也要包括任何内部异常。 这个try-catch真的失败了吗?我看到您正在阅读卡片,这可能意味着您正在修改 USB 和端口等等。如果您以提升的权限运行 VS 并且错误在其他地方 - 更接近 USB 或读卡代码怎么办?您是否在运行某种未知的 3rd 方不安全代码,而 VS 会保护您? 永远不要实例化并抛出 System.Exception 对象...始终使用子类进行实例化,即使您必须自己创建它,因为这为您的代码提供了一些可以使用的上下文。 .. 目前,发生的任何异常都会向用户泄露 Exception.Message 属性!简而言之,严格定义您将引发的异常,并严格限制您捕获的内容...... @Ha11owed 代码在一个按钮内,在创建一些 hastables 和诸如此类之后。 【参考方案1】:

在我看来,您正在处理一个不符合 CLS 的异常。

要捕获任何不符合 CLS 的异常,您需要有一个空捕获:

try  
catch  

在 VB 中:

Try
Catch
End Try

所以你的代码应该是这样的:

Try
    pinpad.readcard(lecturaEntrada, lecturaSalida)
Catch
   MsgBox("Failed Card read")
   Exit Sub
End Try

【讨论】:

我按照您的指示尝试了这个,但它没有工作 =´(,和以前一样,在 VStudio 中工作(就像以前一样)但不适用于standalone.exe。谢谢你的努力,我还在努力。

以上是关于Try/Catch 在调试中效果很好,但在 .exe 中效果不佳的主要内容,如果未能解决你的问题,请参考以下文章

catch中的异常处理方式

JavaScript里的try..catch和if...else有何区别啊

tycatch(Exception ex)啥意思

php 语法错误定位 try catch Throwable

WebException 未在 try/catch 中捕获

若catch中抛出运行时异常,请问在try catch语句块中return语句是写在try中还是写在try catch语句外。