Programatically determine if Shared Features installed for VBA

Sometimes users/customers report my Visio application fails with error 438. This usually is the result of a Visio installation where the Office Shared Features do not have VBA enabled/installed.

Is there a way my application installer/setup can determine this?

April 13th, 2015 6:40am

You can check if corresponding feature is installed for the Visio product (it's called "VBAFiles"). The details depend on the technology you use. Windows Installer has an API function (there is also unmanaged version) to determine if a given feature of a given product is installed or not. Note that since there can be many ProductCodes for Visio (depending on edition, language, service pack, etc), you may need to check them all. For example, Visio 2013 can have ProductCode = "{90150000-0051-0000-0000-0000000FF1CE}". Given this code, you simple check is like this:

installer.FeatureState ("{90150000-0051-0000-0000-0000000FF1CE}", "VBAFiles") = 3

But some numbers in actual ProductCode the user has may be different. Basically, the "stable" parts are:

XXXXXXXX-005Z-XXXX-XXXX-0000000FF1CE

Instead of X you may have more or less anything. Instead of "00ZZ" you may have only a fixed list (see below). The tail is always fixed. The whole list of Visio product codes can be found in this KB article:

KB2786054: Description of the numbering scheme for product code GUIDs in Office

This code snippet (C#) which just iterates over possible combinations for Visio 2007, 2010, 2013:

            var installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            dynamic installer = Activator.CreateInstance(installerType);

            // iterate over all installed products
            foreach (var productCode in installer.Products)
            {
                // Visio "short-codes" see https://support.microsoft.com/en-us/kb/2786054
                var visioCodes = new [] {"0051", "0052", "0053", "0057" };

                // if our product code is Visio product code
                if (visioCodes.Any(visioCode => Regex.IsMatch(productCode, 
                    string.Format(@"^{{........-{0}-....-....-0000000FF1CE}}$", visioCode))))
                {
                    // check if VBA is isntalled
                    var vbaInstalled = installer.FeatureState(productCode, "VBAFiles") == 3;
                }
            }

Another pair of gotchas: user may have more than one Visio installed, and some of them may have VBA installed and some not. Also, this won't work for Visio for office 365, since it's not installed with MSI but streaming. But since you can't really change anything in Visio 365 install anyways, it doesn't seem to matter.

Not sure if messing with this worth it though :)


Free Windows Admin Tool Kit Click here and download it now
April 13th, 2015 1:06pm

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

April 16th, 2015 2:50am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
Free Windows Admin Tool Kit Click here and download it now
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
Free Windows Admin Tool Kit Click here and download it now
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
Free Windows Admin Tool Kit Click here and download it now
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
Free Windows Admin Tool Kit Click here and download it now
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
Free Windows Admin Tool Kit Click here and download it now
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
April 16th, 2015 6:49am

Great Nikolay, pointed me in the right direction, as VBAFiles is a shared feature I chose to use Word as was easier to get the product code.

set oWord = CreateObject("Word.Application")

prodcode = = oword.ProductCode

set installer = CreateObject("WindowsInstaller.Installer")

vbaState = installer.featurestate (prodcode,"VBAFiles")

if (vbastate=1) or (vbastate=3) or (vbastate=4) then
    'VBA installed
end if

Also, I had to check registry in case VBA had been disabled, so searching HLKM and HKCU for SOFTWARE\Microsoft\Office\*\Common\VBAOff. If present and has the value 1 then VBA is disabled for the product.

  • Marked as answer by Andy-W (UK) Thursday, April 16, 2015 6:49 AM
Free Windows Admin Tool Kit Click here and download it now
April 16th, 2015 6:49am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics