本文介绍了处理特定的Win32异常(例如“未找到应用程序")的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用文件类型的默认应用程序启动了一个进程,但是如果用户删除了其默认应用程序,则会引发Win32Exception.此外,在其他情况下会引发Win32Exception,例如如果用户无权打开默认应用程序.

I start a process with the default application for the file type, but if the user has deleted his default application, a Win32Exception is thrown. In addition there are other cases when a Win32Exception is thrown e.g. if the user has no rights to open the default application.

现在,我正在寻找区分异常的最佳方法.

Now I'm looking for the best way to seperate between the exceptions.

我如何检查到底抛出了哪个异常?是通过异常消息检查它的唯一方法吗?

How can i check which exception exactly is thrown? Is the only way to check it by its Exception message?

我正在这样捕捉它:

        try
        {
            process.Start();
        }
        catch (Win32Exception exc)
        {
//How to check which exception exactly is thrown?
            return return string.Format("Process cannot be started", exc.Message)
        }

这是我首先想到的,但是我认为有一种更好的方法可以完成此任务:

This was mit first idea but i think there is a better way to accomplish this task:

catch (Win32Exception exc)
        {
            if(exc.Message == "Application not found")
            {
              //Do something
            }
            else if(exc.Message == "Another exception")
            {
              //Do something else
            }
        }

推荐答案

使用Win32Exception,您可能需要检查两者Win32Exception.NativeErrorCode及其继承的ExternalException.ErrorCode值.

With Win32Exception you may need to check both Win32Exception.NativeErrorCode and its inherited ExternalException.ErrorCode values.

C#6引入了异常过滤器,如果您打算重新引发异常,则允许您选择处理异常,而无需提前回退堆栈.

C# 6 introduces exception filters which allow you to opt-in to handling an exception without needing to rewind the stack prematurely if you intend to re-throw the exception.

Windows中的错误代码主要有三种类型:HRESULT,Win32错误代码和COM错误代码.

There are three main types of error-codes in Windows: HRESULT, Win32 Error Codes, and COM error codes.

  • HRESULT:

  • HRESULT values are actually self-describing bit-fields and the format is documented here: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a
  • They're exposed as Exception.HResult.
  • Note that Exception.HResult has a default value of -2146233088 (0x80131500)

Win32错误代码:

Win32 error codes:

  • These are listed on this page: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/18d8fbe8-a967-4f1c-ae50-99ca8e491d2d?redirectedfrom=MSDN
  • They're exposed only on Win32Exception in the Win32Exception.NativeErrorCode property.

COM错误代码在此页面上列出: https://docs.microsoft.com/zh-cn/windows/win32/com/com-error-codes-1

COM error codes are listed on this page: https://docs.microsoft.com/en-us/windows/win32/com/com-error-codes-1

  • 这些主要通过COMException.HResult属性中的COMException公开.
  • 但是,.NET中的某些位置将引发Win32Exception而不是COMException,并且Win32Exception.NativeErrorCode将包含COM错误代码而不是Win32错误代码.
    • Process.Start()就是这样一个例子.下面对此进行了说明.
    • These are chiefly exposed via COMException in the COMException.HResult property.
    • However some places in .NET will throw a Win32Exception instead of a COMException, and the Win32Exception.NativeErrorCode will contain the COM error code instead of a Win32 error code.
      • Process.Start() is one such example. This is explained below.

      关于您的问题:未找到应用程序"错误消息来自COM:CO_E_APPNOTFOUND且为0x800401F5-但奇怪的是,它是在Win32Exception而不是COMException中返回的.

      On to your question: The "Application not found" error message is from COM: CO_E_APPNOTFOUND and is 0x800401F5 - but curiously it's returned in a Win32Exception rather than a COMException.

      有趣的是,.NET Framework(我尚未检查.NET Core), Process.Start对于UseShellExecute == truefalse分支总是会抛出Win32Exception .但是,当使用UseShellExecute == true时使用COM,因此COM错误只是传递到Win32Exception的构造函数中,并且可以神奇地起作用(因为Win32Exception调用FormatMessage可以从错误中获取人类可读的错误消息-代码,并且FormatMessage支持返回Win32,HRESULT和COM状态代码的错误消息(因为它们通常不重叠).

      What's interesting is that the .NET Framework (I haven't checked .NET Core), Process.Start always throws Win32Exception for both the UseShellExecute == true and false branches. But when UseShellExecute == true then COM is used, so the COM error is simply passed-into Win32Exceptions constructor and it just magically works (because Win32Exception calls FormatMessage to get the human-readable error message from the error-code, and FormatMessage supports returning error-messages for Win32, HRESULT and COM status codes (as they generally don't overlap).

      ...这意味着我们只需要这样做:

      ...which means we just need to do this:

      const Int32 CO_E_APPNOTFOUND = unchecked( (Int32) 0x800401F5 );
      
      try
      {
          ProcessStartInfo psi = new ProcessStartInfo( "https://www.stackoverflow.com" );
          psi.UseShellExecute = true;
          psi.Verb = "open";
      
          using( Process p = Process.Start( psi ) )
          {
              p.WaitForExit();
          }
      }
      catch( Win32Exception w32Ex ) when ( w32Ex.NativeErrorCode == CO_E_APPNOTFOUND )
      {
          MessageBox.Show( "You don't have a web-browser installed or configured correctly." );
      }
      

      这篇关于处理特定的Win32异常(例如“未找到应用程序")的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 01:16