UnholyRanger
UnholyRanger

Reputation: 1971

Testing if outlook is installed with C# exception-handling

I have a section of my application that allows for people to send an email of the generated text. My current problem is that when they load the form with the text, it throws an unhandled exception System.IO.FileNotFound when the user does not have outlook installed. On the load of the form, I try to determine is they have outlook installed.

try{
       //Assembly _out = Assembly.Load("Microsoft.Office.Interop.Outlook");
       Assembly _out = Assembly.Load("Microsoft.Office.Interop.Outlook, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
       //Microsoft.Office.Interop.Outlook.Application _out = new Microsoft.Office.Interop.Outlook.Application();
       //Microsoft.Office.Interop.Outlook.Application _out = new Microsoft.Office.Interop.Outlook.Application();
   }

Above is the code I have been trying. On the computer where I am developing, if the assembly name is off the catch statements will catch it. However, when I test it on an XP machine with no outlook, it throws the error and stops the loading of the form events.

Every catch statement I have tried (Catch all didn't even work):

        catch (System.IO.FileLoadException)
        { _noOutlook = true; type = "FILE-LOAD"; }
        catch (System.IO.FileNotFoundException)
        { _noOutlook = true; type = "FILE-NOT-FOUND"; }
        catch (System.IO.IOException)
        { _noOutlook = true; type = "IO"; }
        catch (System.Runtime.InteropServices.COMException)
        { _noOutlook = true; type = "INTEROP"; }
        catch (System.Runtime.InteropServices.InvalidComObjectException)
        { _noOutlook = true; type = "INTEROP-INVALIDCOM"; }
        catch (System.Runtime.InteropServices.ExternalException)
        { _noOutlook = true; type = "INTEROP-EXTERNAL"; }
        catch (System.TypeLoadException)
        { _noOutlook = true; type = "TYPELOAD"; }
        catch (System.AccessViolationException)
        { _noOutlook = true; type = "ACCESVIOLATION"; }
        catch (WarningException)
        { _noOutlook = true; type = "WARNING"; }
        catch (ApplicationException)
        { _noOutlook = true; type = "APPLICATION"; }
        catch (Exception)
        { _noOutlook = true; type = "NORMAL"; }

I'm looking for a method that will work (hopefully so I could use one code to work for Outlook 2010 & 2007) without having to check the registry / exact file path.

So a couple things I am wondering is why XP is even throwing the errors and not catching them, since it throws the FileNotFound when I have a catch for it, and what is a good method to determine if the outlook interop object will work.

Upvotes: 3

Views: 3041

Answers (2)

John Egbert
John Egbert

Reputation: 5776

public bool IsOutlookInstalled()
{
    try
    {
        var officeType = Type.GetTypeFromProgID("Outlook.Application");
        if (officeType == null)
        {
            // Outlook is not installed.   
            return false;
        }
        else
        {
            // Outlook is installed.      
            return true;
        }
    }
    catch (System.Exception ex)
    {
        return false;
    }
}

Upvotes: 1

L.B
L.B

Reputation: 116138

I have a 2007 installed XP machine. therefore I couldn't test for all cases. But this code seems to work.

public static bool IsOutlookInstalled()
{
    try
    {
        Type type = Type.GetTypeFromCLSID(new Guid("0006F03A-0000-0000-C000-000000000046")); //Outlook.Application
        if (type == null) return false;
        object obj = Activator.CreateInstance(type);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
        return true;
    }
    catch (COMException)
    {
        return false;
    }
}

Upvotes: 3

Related Questions