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 ca
With Win32Exception you may need to check both Win32Exception.NativeErrorCode and its inherited ExternalException.ErrorCode values.
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.
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-4441e69c548aException.HResult.Exception.HResult has a default value of -2146233088 (0x80131500)Win32 error codes:
Win32Exception in the Win32Exception.NativeErrorCode property.COM error codes are listed on this page: https://docs.microsoft.com/en-us/windows/win32/com/com-error-codes-1
COMException in the COMException.HResult property.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.COMException is also used for SEH (Structured Exception Handling), but normally you won't encounter that in .NET.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.
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." );
}
Win32Exception has a property called ErrorCode, that returns the error HRESULT. With this, you can properly classify your exception, according to this link here.