I have a dependency on .NET 2.0 SP2 in my ClickOnce deployed application
(the ApplicationDeployment.CurrentDeployment.CheckForDetailedUpdate(false)
method is SP
I suspect it's happening at JIT time, before the method is even properly entered - i.e. before your catch block is hit. It's possible that if you catch MissingMethodException
in the calling method, that will sort it out... particularly if you decorate CheckDotNet2SP
with MethodImpl[MethodImplOptions.NoInlining]
. It still sounds like it would be pretty dicey though.
You could always check for the presence of the method with reflection rather than by trying to call it though.
There are a few exceptions that have been defined as "unrecoverable". One of them is MissingMethodException
, because if a method is missing in a class, this is a severe error and it requires unloading the class and reloading a new class to recover, which cannot be done trivially (if at all).
To recover, you need to reinstall, check the versions of the assemblies, check whether the PE images are valid etc.
If all you want to know is whether SP2 is installed, the default method is using a bootstrap application which simply checks the installed version. If all's fine, it runs the application, if not it shows a nice message.
Update requested by OP:
Other exceptions that are either hard to catch or uncatchable (may depend on your version of .NET, i.e., .NET 4.0 added more uncatchables): OutOfMemoryException
(can be caught when it is synchronous), StackOverflowException
(can never be caught), ThreadAbortException
(can be caught, but is special because it will automatically be reraised at the end of the catch-block), BadImageFormatException
and MissingManifestResourceException
if you'd try to catch it in the assembly throwing the exception (if you load it dynamically, same as with MissingMethodException
, you are capable of catching it). And in general, any exception that does not inherit from Exception
is hard to catch (but you can catch them with a generic try/catch block).
There are others, but the first three above are the ones you'll encounter most often in practice.
You could use reflection to see whether the method exists.
private void CheckDotNet2SP()
{
return typeof(WaitHandle).GetMethod("WaitOne", new Type[] { typeof(int) })
!= null;
}
Exception is thrown on JIT compilation step, so you didn't step into method. Try this version:
private bool CheckDotNet2SP()
{
try
{
CheckImpl();
return true;
}
catch (MissingMethodException)
{
return false;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void CheckImpl()
{
using (var wh = new ManualResetEvent(true))
wh.WaitOne(1);
}