C# 如何在C语言中获取异常错误代码#

C# 如何在C语言中获取异常错误代码#,c#,exception,C#,Exception,当我调用上面的WMI方法时,我希望访问被拒绝。在catch块中,我希望确保引发的异常确实是针对拒绝访问的。有没有办法得到它的错误代码?拒绝访问的Win32错误代码为5。 我不想在错误消息中搜索拒绝字符串或类似的内容 谢谢您可以使用此选项检查异常和内部异常是否存在异常 从C#6开始,可以在catch语句中使用,以指定处理程序必须为true的条件,才能执行特定异常 catch (Exception e) { var w32ex = e as Win32Exception; if(

当我调用上面的WMI方法时,我希望访问被拒绝。在catch块中,我希望确保引发的异常确实是针对拒绝访问的。有没有办法得到它的错误代码?拒绝访问的Win32错误代码为5。 我不想在错误消息中搜索拒绝字符串或类似的内容


谢谢

您可以使用此选项检查异常和内部异常是否存在异常

从C#6开始,可以在catch语句中使用,以指定处理程序必须为true的条件,才能执行特定异常

catch (Exception e) {  
    var w32ex = e as Win32Exception;
    if(w32ex == null) {
        w32ex = e.InnerException as Win32Exception;
    }    
    if(w32ex != null) {
        int code =  w32ex.ErrorCode;
        // do stuff
    }    
    // do other stuff   
}
在注释中,您确实需要查看实际抛出的异常,以了解您可以做什么,在这种情况下,特定捕获比仅捕获异常更可取。比如:

catch (Win32Exception ex) when (ex.InnerException is Win32Exception) {
    var w32ex = (Win32Exception)ex.InnerException;
    var code =  w32ex.ErrorCode;
}


但是,它只能从.NET 4.5以上版本获得。

您应该查看抛出异常的成员,特别是
.Message
.InnerException


我还要看看InvokeMethod的文档是否告诉您它是否抛出了比Exception更专业的异常类,比如@Preet建议的Win32Exception。捕获并查看异常基类可能不是特别有用。

我建议您使用来自异常对象的消息Properte,如下面的代码所示

 catch (Exception ex) {  
     var code = ex.HResult;
 }

在Preet Sangha的解决方案的基础上,以下内容将安全地介绍您正在使用的大型解决方案可能存在几个内部异常的场景

try
{
 object result = processClass.InvokeMethod("Create", methodArgs);
}
catch (Exception e)
{  
    //use Console.Write(e.Message); from Console Application 
    //and use MessageBox.Show(e.Message); from WindowsForm and WPF Application
}

此代码已经过单元测试。


当涉及到异常处理时,我不会过多地强调欣赏和实现良好实践的必要性,方法是在各自的块中管理每个预期的异常类型。

另一种方法是直接从异常类获取错误代码。例如:

private bool ExceptionContainsErrorCode(Exception e, int ErrorCode)
{
    Win32Exception winEx = e as Win32Exception;
    if (winEx != null && ErrorCode == winEx.ErrorCode) 
        return true;

    if (e.InnerException != null) 
        return ExceptionContainsErrorCode(e.InnerException, ErrorCode);

    return false;
}

运行代码,在catch块中放置断点,然后使用调试器查看异常并查看您拥有的信息。或者,您可以运行代码而不用费心调试,并使用GetType()打印异常类型。但乔尔的回答也肯定会起作用。你应该只抓住你期望的异常类型;捕捉
Exception
几乎总是一种糟糕的代码气味。@Bevan捕捉
Exception
几乎总是一个好主意。因为你不必一次显示一条消息——每个类都不应该知道这个应用程序是与GUI还是终端一起工作的。因此,您只需保存一个异常ID,就可以在很远的地方显示它。不需要专门捕获每个异常来执行相同的操作。至少这是我在C++中的工作方式。现在我正在使用C#,但看不出有什么原因会在这里产生影响。因为这个问题有点老了,这只是提醒那些想使用这个答案的人:对于.NET 3.0、3.5和4.0,您必须使用反射来获取HResult属性的值,因为它被标记为受保护。资料来源:在C#6中有一些小的改进,你可以将你的第一个if语句改为底线。第一部分检查null,并在
winEx==null
时使if条件失败。然后,它安全地检查
ErrorCode
属性,而不会引发null异常<代码>如果(winEx?.ErrorCode==ErrorCode)
try
{
 object result = processClass.InvokeMethod("Create", methodArgs);
}
catch (Exception e)
{  
    //use Console.Write(e.Message); from Console Application 
    //and use MessageBox.Show(e.Message); from WindowsForm and WPF Application
}
 try
 {
     object result = processClass.InvokeMethod("Create", methodArgs);
 }
 catch (Exception e)
 {
     // Here I was hoping to get an error code.
     if (ExceptionContainsErrorCode(e, 10004))
     {
         // Execute desired actions
     }
 }
private bool ExceptionContainsErrorCode(Exception e, int ErrorCode)
{
    Win32Exception winEx = e as Win32Exception;
    if (winEx != null && ErrorCode == winEx.ErrorCode) 
        return true;

    if (e.InnerException != null) 
        return ExceptionContainsErrorCode(e.InnerException, ErrorCode);

    return false;
}
catch (Exception ex)
{
    if (ex.InnerException is ServiceResponseException)
       {
        ServiceResponseException srex = ex.InnerException as ServiceResponseException;
        string ErrorCode = srex.ErrorCode.ToString();
       }
}