处理错误PInvokeStackImbalance

时间:2018-07-25 03:08:50

标签: c#

我想根据打印方法的结果更改复选框的状态。如果打印机未连接或找不到打印机,我想处理它。现在,如果未找到打印机,即未连接,我的代码将抛出PInvokeStackImbalance Occured,如果按继续,它不会进入catch(Exception ex)子句。我想处理这个错误,要么转到catch子句,要么仅捕获此PInvokeStackImbalance消息。下面是我的代码。

private void btnPrint_Click(object sender, EventArgs e)
        {
            if (txtPrinterName.Text == string.Empty)
            {
                MessageBox.Show("Enter a printer name");
                return;
            }
            try
            {
                var mstrFullCutCode = (char)27 + (char)109;
                _finalLength = noteToPrint;
                var printingObject = new PrintClass.Class1.RawPrinterHelper();
                var result = PrintClass.Class1.RawPrinterHelper.SendStringToPrinter(txtPrinterName.Text, _finalLength + mstrFullCutCode);
                frmMain.Instance.LblStatus.Text = "Printer is found: " + result;
                if ((bool)result)
                {
                    frmMain.Instance.CbPrinter.Checked = true;
                }
            }catch(Exception ex)
            {
                frmMain.Instance.LblStatus.Text = "Error: " + ex.Message;
            }

        }

这是托管调试助手的图片 enter image description here

1 个答案:

答案 0 :(得分:1)

  

…,如果我按继续,它将不会转到我的catch(Exception ex)子句。我想处理这个错误,要么转到catch子句,要么仅捕获此PInvokeStackImbalance消息。

我认为你不能。

尽管MDA 看起来就像未处理的异常,但这不是一个例外。例如,请参见页面Diagnosing Errors with Managed Debugging Assistants上的第一条注释,其中部分内容说明了这一点(加了强调)…

  

如果在不存在调试器的情况下引发了MDA事件,则该事件消息将显示在未处理的异常对话框中,尽管它不是未处理的异常。

一个PInvokeStackImbalance托管调试助手(MDA)"is activated when the CLR detects that the stack depth after a platform invoke call does not match the expected stack depth"。因此,它通常表示PInvoke使用的托管签名中有错误,不是缺少打印机。

您应该检查所用本机方法的声明-很可能是OpenPrinter

如果您使用的是KB article 322091中的RawPrinterHelper类,请注意SendBytesToPrinter返回truefalse来指示成功或失败,但返回{{1} }会忽略该返回值,并始终返回SendStringToPrinter

true函数应真正返回SendStringToPrinter的结果,并且您的代码应检查该返回值并调用GetLastWin32Error以获取有关失败的更多信息。您应该收到1801错误代码-打印机名称无效。