Jason
Jason

Reputation: 17099

How to know if the VBA component of Office is installed?

My Excel addin requires the Visual Basic for Applications option of Excel to be installed in order for it to work. I would like my install (which is written with InnoSetup) to be able to detect if VBA is installed and warn the user if it is not.

How can I detect if the option is already installed?

alt text

Upvotes: 6

Views: 19406

Answers (5)

Armin Sadeghi
Armin Sadeghi

Reputation: 845

The best way to detect if VBA is installed is to use the MsiQueryFeatureState API and ask Windows Installer whether the feature is installed or not. Below is some sample code that does this in VB.NET, however you could code this in any language that allows you to call COM components (sorry, not familiar with InnoSetup).

Private Declare Function MsiQueryFeatureState Lib "Msi" Alias "MsiQueryFeatureStateA" (ByVal Product As String, ByVal Feature As String) As Long

Public Function FVbaAvailable() As Boolean

    Dim objExcelApp As Object
    Dim strProductCode As String
    Dim nState As Long
    Dim fAvailable As Boolean = False

    Try
        ' Start an Excel instance and get the product code.
        objExcelApp = CreateObject("Excel.Application")
        strProductCode = DirectCast(objExcelApp.ProductCode, String)

        ' Get FeatureState for the VBAFiles Feature.
        nState = MsiQueryFeatureState(strProductCode, "VBAFiles")

        If (nState = 1) OrElse (nState = 3) OrElse (nState = 4) Then
            ' VBA is available.
            fAvailable = True
        End If

        ' Clean up.
        objExcelApp.Quit()
        Runtime.InteropServices.Marshal.FinalReleaseComObject(objExcelApp)
        objExcelApp = Nothing
    Catch ex As Exception
        Trace.WriteLine(ex.Message)
    End Try

    Return fAvailable
End Function

Upvotes: 0

Siarhei Helis
Siarhei Helis

Reputation: 9

public static  class VbePrerequisiteDetector {
    private const string VbeInstallationPathKey = @"SOFTWARE\Microsoft\VBA";
    private const string Vbe6InstallationPathValue = "Vbe6DllPath";
    private const string Vbe7InstallationPathValue = "Vbe7DllPath";

    /// <summary>
    /// Return true if VBE6 installed. VBE6 is prerequisite for for Office2003 and Office2007
    /// </summary>
    /// <returns>Return true if VBE6 installed.</returns>
    public static bool IsVbe6Installed() {
        try {
            RegistryKey vbaPathKey = Registry.LocalMachine.OpenSubKey(VbeInstallationPathKey);

            if (vbaPathKey != null) {
                if (vbaPathKey.GetValue(Vbe6InstallationPathValue) != null) {
                    string pathToVbe = (string)vbaPathKey.GetValue(Vbe6InstallationPathValue);
                    if (File.Exists(pathToVbe)) {
                        return true;
                    }

                }
            }
        }
        catch (Exception) {
            //Ignore all exceptions
        }
        return false;
    }

    /// <summary>
    /// Return true if VBE7 installed. VBE7 is prerequisite for for Office2010
    /// </summary>
    /// <returns>Return true if VBE7 installed.</returns>
    public static bool IsVbe7Installed() {
        try {
            RegistryKey vbaPathKey = Registry.LocalMachine.OpenSubKey(VbeInstallationPathKey);

            if (vbaPathKey != null) {
                if (vbaPathKey.GetValue(Vbe7InstallationPathValue) != null) {
                    string pathToVbe = (string)vbaPathKey.GetValue(Vbe7InstallationPathValue);
                    if (File.Exists(pathToVbe)) {
                        return true;
                    }

                }
            }
        }
        catch (Exception) {
            //Ignore all exceptions
        }
        return false;
    }
}

Upvotes: 0

coding Bott
coding Bott

Reputation: 4367

We are talking about Windows Installer components. The Installer has an API, where you can request if a feature/component is installed. ofcurse that api also return where the component is installed. if nessacary you can install missing components.

the only thing you need, is the component und product guid.

see documentation

Upvotes: 0

Anonymous Type
Anonymous Type

Reputation: 3061

Why don't you try a function like this... found here

Option Explicit
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long

Private Sub cmdCheck_Click()
MsgBox "Exist ???    =" & CheckForComponent("user32.dll")
End Sub

Private Function CheckForComponent(ComPath As String) As Boolean
Dim Ret As Long
Ret = LoadLibrary(ComPath)
FreeLibrary Ret

If Ret = 0 Then
        CheckForComponent = False
    Else
        CheckForComponent = True
End If

End Function 

Upvotes: 0

Tony Toews
Tony Toews

Reputation: 7882

One possibility is to check for the presence of VBE6.DLL in C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6. Or poke about in the registry looking for references to that DLL or the string VBA.

Note that this location/file name might be different for Office 2010 as there are some changes in the VBA editor.

Upvotes: 2

Related Questions