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?
I'm catching it like this:
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
}
}
With
Win32Exceptionyou may need to check bothWin32Exception.NativeErrorCodeand its inheritedExternalException.ErrorCodevalues.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:HRESULTvalues are actually self-describing bit-fields and the format is documented here: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548aException.HResult.Exception.HResulthas a default value of-2146233088(0x80131500)Win32 error codes:
Win32Exceptionin theWin32Exception.NativeErrorCodeproperty.COM error codes are listed on this page: https://learn.microsoft.com/en-us/windows/win32/com/com-error-codes-1
COMExceptionin theCOMException.HResultproperty.Win32Exceptioninstead of aCOMException, and theWin32Exception.NativeErrorCodewill contain the COM error code instead of a Win32 error code.Process.Start()is one such example. This is explained below.COMExceptionis 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_APPNOTFOUNDand is0x800401F5- but curiously it's returned in aWin32Exceptionrather than aCOMException.What's interesting is that the .NET Framework (I haven't checked .NET Core),
Process.Startalways throwsWin32Exceptionfor both theUseShellExecute == trueandfalsebranches. But whenUseShellExecute == truethen COM is used, so the COM error is simply passed-intoWin32Exceptions constructor and it just magically works (becauseWin32ExceptioncallsFormatMessageto get the human-readable error message from the error-code, andFormatMessagesupports returning error-messages for Win32, HRESULT and COM status codes (as they generally don't overlap)....which means we just need to do this: