We have a PowerPoint VBA addin which is installed using an MSI installer written with WIX (Windows Installer XML).
For the addin to be picked up (for all users) by PowerPoint, name-value pairs need to be added to this registry key in HKLM: SOFTWARE\Microsoft\Office\[POWERPOINT_VERSION_NUMBER]\PowerPoint\AddIns\OurAddinName
, where [POWERPOINT_VERSION_NUMBER]
has the form 14.0, 16.0 etc. The addin works with PowerPoint 2007 and greater (i.e. >=12.0).
To get the right version number, the installer had been looking here: PowerPoint.Application\CurVer
in HKCR. This gives a value like PowerPoint.Application.16
. However (as of January 2022), the value of CurVer does not seem to be reliable. One of my machines has it as PowerPoint.Application.11
and on another it's PowerPoint.Application.16
. Both have the same recent version of PowerPoint (Version 2111 Build 16.0.14701.20240). Both machines have a single version of Office.
Where CurVer
is giving the incorrect value for computing the right key to register the addin, this creates a couple of problems:
- When a user uninstalls the addin, the registry key for the path to the addin does not get deleted (it's trying to remove
HKLM\SOFTWARE\Microsoft\Office11円.0\PowerPoint\AddIns\OurAddinName
rather thanHKLM\SOFTWARE\Microsoft\Office16円.0\PowerPoint\AddIns\OurAddinName
), so thereafter when the user opens PowerPoint they will get an error message about not being able to find the addin. - When a user tries to install the addin, they will get an error message saying that their version of PowerPoint is too old.
My working solution
- Inspect
HKLM\SOFTWARE\Microsoft\Office\ClickToRun\Configuration\VersionToReport
instead ofCurVer
- Inspect
HKCR\PowerPoint.Application\CurVer
ifVersionToReport
not available (maybe it might not be available on older installs? Some of our customers' organisations have very old installs of Office) - Store the version found here in the registry - under an entry for our software - so the right location can always be found for an uninstall
Using WIX and vb.net, it looks like this:
Get the registry values:
<Property Id="CTR_POWERPOINT_VERSION" Secure="yes">
<RegistrySearch Id="RegPowerPointVersion"
Root="HKLM"
Key="SOFTWARE\Microsoft\Office\ClickToRun\Configuration"
Name="VersionToReport"
Type="raw">
</RegistrySearch>
</Property>
<Property Id="CURVER_POWERPOINT_VERSION" Secure="yes">
<RegistrySearch Id="RegCurVerPowerPointVersion"
Root="HKCR"
Key="PowerPoint.Application\CurVer"
Type="raw">
</RegistrySearch>
</Property>
<Property Id="RECORDED_POWERPOINT_VERSION" Secure="yes">
<RegistrySearch Id="RegRecordedPowerPointVersion"
Root="HKLM"
Key="SOFTWARE\OurCompany\OurAddinName"
Name="powerpoint_version"
Type="raw">
</RegistrySearch>
</Property>
Make available for custom actions:
<CustomAction Id="SetPowerPointVersionProperty"
Property="CTR_POWERPOINT_VERSION"
HideTarget="no"
Value="[CTR_POWERPOINT_VERSION]"/>
<CustomAction Id="SetCurVerPowerPointVersionProperty"
Property="CURVER_POWERPOINT_VERSION"
HideTarget="no"
Value="[CURVER_POWERPOINT_VERSION]"/>
<CustomAction Id="SetRecordedPowerPointVersionProperty"
Property="RECORDED_POWERPOINT_VERSION"
HideTarget="no"
Value="[RECORDED_POWERPOINT_VERSION]"/>
Process with vb.net:
Dim versionToUse As String
versionToUse = Regex.Match(Me.session("RECORDED_POWERPOINT_VERSION"), "[0-9]+").Value
' Note, when updating the addin, this is always done by doing an uninstall
' followed by an install - so in the uninstall phase RECORDED_POWERPOINT_VERSION
' will have something in it, and in the install phase it will be empty.
If versionToUse = vbNullString Then
versionToUse = Regex.Match(Me.session("CTR_POWERPOINT_VERSION"), "[0-9]+").Value
End If
If versionToUse = vbNullString Then
versionToUse = Regex.Match(Me.session("CURVER_POWERPOINT_VERSION"), "[0-9]+").Value
End If
Me.session("POWERPOINT_VERSION_NUMBER") = versionToUse & ".0"
Set the registry values (all also repeated on WOW6432Node):
<RegistryKey Root="HKLM"
Key="SOFTWARE\Microsoft\Office\[POWERPOINT_VERSION_NUMBER]\PowerPoint\AddIns\MyAddinName">
<RegistryValue Name="AutoLoad"
Action="write"
Value="1"
Type="integer"
KeyPath="yes"/>
<RegistryValue Name="Path"
Action="write"
Value="[APPLICATIONFOLDER]our-addin.ppam"
Type="string"
KeyPath="no"/>
</RegistryKey>
And record the location in a registry location for our addin:
<RegistryKey Root="HKLM"
Key="SOFTWARE\OurCompany\OurAddinName">
<RegistryValue Name="powerpoint_version"
Action="write"
Value="[POWERPOINT_VERSION_NUMBER]"
Type="string"
KeyPath="no"/>
</RegistryKey>
How does this look?
1 Answer 1
I have similar code in VBA to pull the version. It's much more simple because I can pull the version from the running application itself. It knows it's own version and doesn't care what arbitrary values exist in the registry. You could do this from VB.NET using office interop code.
First you need add a reference
- In Solution Explorer, right-click your project's name and then click
Add Reference
. The Add Reference dialog box appears. - On the Assemblies page, select
Microsoft.Office.Interop.PowerPoint
in the Component Name list. If you do not see the assemblies, you may need to ensure they are installed and displayed. See How to: Install Office Primary Interop Assemblies. - Click OK.
Then you need to import the assembly you referenced:
Imports Microsoft.Office.Interop.PowerPoint
Then you can pull the version like this:
Public Function GetPowerPointVersion As String
Dim CurVer As String
Using thisPowerPoint As New Microsoft.Office.Interop.PowerPoint.Application()
CurVer = thisPowerPoint.Version
thisPowerPoint.Quit
End Using
Return CurVer
End Function
-
\$\begingroup\$ That looks interesting. I've not been able to work out how to install the primary interop assemblies though. On that page you linked to it's saying to enable .NET Programmability Support - but I can't see any way to do that - there don't seem to be options to modify program install parameters on my version of Office 365 which were available on previous versions (and which are the solutions you get when searching). \$\endgroup\$neilt17– neilt172022年01月05日 09:15:49 +00:00Commented Jan 5, 2022 at 9:15
-
1\$\begingroup\$ @neilt17 I would recommend looking for a NuGet package any time you don't have the assemblies to add as a reference. It's the modern way of doing it. I've used this one before: nuget.org/packages/NetOfficeFw.PowerPoint \$\endgroup\$HackSlash– HackSlash2022年01月05日 17:09:09 +00:00Commented Jan 5, 2022 at 17:09
Explore related questions
See similar questions with these tags.