In C# code can you catch a native exception thrown from deep in some unmanaged library? If so do you need to do anything differently to catch it or does a standard try...catch get it?
If you use a
try
{
}
catch(Exception ex)
{
}
it will catch ALL exceptions, depending on how you call the external libraries you might get a com related exception that encapsulates the error but it will catch the error.
The interop layer between C# and native code will convert the exception into a managed form, allowing it to be caught by your C# code. As of .NET 2.0, catch (Exception)
should catch anything other than a nonrecoverable error.
A standard try catch should do the trick i believe.
I run into a similar problem with a System.data exception throwing a sqlClient exception which was uncaught, adding a try..catch into my code did the trick in the instance
You can use Win32Exception and use its NativeErrorCode property to handle it appropriately.
// http://support.microsoft.com/kb/186550
const int ERROR_FILE_NOT_FOUND = 2;
const int ERROR_ACCESS_DENIED = 5;
const int ERROR_NO_APP_ASSOCIATED = 1155;
void OpenFile(string filePath)
{
Process process = new Process();
try
{
// Calls native application registered for the file type
// This may throw native exception
process.StartInfo.FileName = filePath;
process.StartInfo.Verb = "Open";
process.StartInfo.CreateNoWindow = true;
process.Start();
}
catch (Win32Exception e)
{
if (e.NativeErrorCode == ERROR_FILE_NOT_FOUND ||
e.NativeErrorCode == ERROR_ACCESS_DENIED ||
e.NativeErrorCode == ERROR_NO_APP_ASSOCIATED)
{
MessageBox.Show(this, e.Message, "Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
}
Somewhere using a .NET Reflector I've seen the following code:
try {
...
} catch(Exception e) {
...
} catch {
...
}
Hmm, C# does not allow to throw an exception not deriving from the System.Exception class. And as far as I known any exception cautch by the interop marshaller is wrapped by the exception class that inherits the System.Exception.
So my question is whether it's possible to catch an exception that is not a System.Exception.
Catch without () will catch non-CLS compliant exceptions including native exceptions.
try
{
}
catch
{
}
See the following FxCop rule for more info http://msdn.microsoft.com/en-gb/bb264489.aspx
This depends on what type of native exception you are talking about. If you're referring to an SEH exception then the CLR will do one of two things.
- In the case of a known SEH error code it will map it to the appropriate .Net exception (i.e. OutOfMemoryException)
- In the case of an un-mappable (E_FAIL) or unknown code it will just throw an SEHException instance.
Both of these will be caught with a simple "catch (Exception)" block.
The other type of native exception which can cross the native managed boundary are C++ exceptions. I'm not sure how they are mapped/handled. My guess is that since Windows implements C++ exceptions on top of SEH, they are just mapped the same way.
Almost, but not quite. You will catch the exception with
try
{
...
}
catch (Exception e)
{
...
}
but you will still have potential problems. According to MSDN, in order to insure exception destructors are called you would have to catch like:
try
{
...
}
catch
{
...
}
This is the only way to insure an exception destructor is called (though I'm not sure why). But that leaves you with the tradeoff of brute force versus a possible memory leak.
Incidentally, if you use the (Exception e) approach you should know the different types of exceptions you might come across. RuntimeWrappedException is what any managed non-exception type will be mapped to (for languages that can throw a string), and others will be mapped, such as OutOfMemoryException and AccessViolationException. COM Interop HRESULTS or exceptions other than E___FAIL will map to COMException, and finally at the end you have SEHException for E_FAIL or any other unmapped exception.
So what should you do? Best choice is don't throw exceptions from your unamanaged code! Hah. Really though if you have a choice, put up barriers and failing that make the choice of which is worse, a chance of a memory leak during exception handling, or not knowing what type your exception is.