Why is it impossible to detect MissingMethodException?

I have a dependency on .NET 2.0 SP2 in a deployed ClickOnce application (method ApplicationDeployment.CurrentDeployment.CheckForDetailedUpdate(false)only SP2).

I would like to check if SP2 is present during application launch. I tried to detect this by catching a MissingMethodException after calling the SP2-only method.

    /// <summary>
    /// The SP2 bootstrapper does not allow HomeSite installation
    /// http://msdn.microsoft.com/en-us/vstudio/bb898654.aspx
    /// So we only advice the user to download .NET 2.0 SP2 manually.
    /// </summary>
    private void CheckDotNet2SP()
    {
        WaitHandle wh = new AutoResetEvent(true);
        try
        {
            wh.WaitOne(1); //this method is .NET 2.0 SP2 only
        }
        //NOTE: this catch does not catch the MissingMethodException
        catch (Exception) //change to catch(MissingMethodException) does not help
        {
            //report that .NET 2.0 SP2 is missing
        }
        finally
        {
            wh.Close();
        }
    }

The code in catch is never executed when it runs on .NET 2.0 without SP2. The exception is thrown only by the event handler AppDomain.CurrentDomain.UnhandledException.

How is it possible that a MissingMethodException is not caught? I can imagine this is a special case - the CLR uses a method that does not exist, and somehow it is not possible to pass this to the catch block. I would like to understand the principle of this.

- ? - , catch?

+11
4

, JIT, , .. , catch . , MissingMethodException , ... CheckDotNet2SP MethodImpl[MethodImplOptions.NoInlining]. - , .

, .

+14

, "". - MissingMethodException, , , , , ( ).

, , , , PE- ..

, SP2, , . , , .


, OP:
, ( .NET, ...NET 4.0 unatchables): OutOfMemoryException ( , ), StackOverflowException ( ), ThreadAbortException ( , , catch), BadImageFormatException MissingManifestResourceException, , ( , , MissingMethodException, ). , , Exception, ( try/catch).

, - , .

+10

JIT, . :

    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);
    }
+3

You can use reflection to see if a method exists.

private void CheckDotNet2SP()
{
    return typeof(WaitHandle).GetMethod("WaitOne", new Type[] { typeof(int) }) 
       != null;
} 
+3
source

All Articles