To configure the RunVirtual key from an App-V package we needed to add a registry key/value to the local machine via an App-V script. Since our environment is VDI we are using a new feature in App-V 5 SP3 which enables us to target an App-V application which is published to the user (and not to the machine).
I won’t discuss what RunVirtual is – you can read this if you need to know.
The key reason for this tutorial is because we are performing this logic in the AppxManifest.xml and NOT the UserConfig.xml. I prefer to add my logic to AppxManifest.xml since it makes my package self-contained with no reliance on external (xml) files – see here.
Why is adding RunVirtual registry logic to the AppxManifest.xml different from adding it to the UserConfig.xml?
Well first a very brief bit of background – the registry key/value we need to add is:
HKCU\SOFTWARE\Microsoft\AppV\Client\RunVirtual\{LocalProcess.exe}
(Default) REG_SZ {PackageId}_{VersionId}
By creating a key under RunVirtual with the process name (Excel.exe in this case) we effectively saying “whenever we run Excel.exe I want it to run in the same virtual space as the App-V package with the specified PackageId_VersionId”. As you’ve probably gathered, this specific package was an Addin for Microsoft Excel.
Adding the logic via a UserConfig.xml script is relatively trivial. We can open the XML file in a text editor and add the following:
<UserScripts>
<PublishPackage>
<Path>cmd.exe</Path>
<Arguments>/C REG ADD HKCU\SOFTWARE\Microsoft\AppV\Client\RunVirtual\Excel.exe /ve /d "2a04d2aa-ad7a-4c51-b774-00ca0e1e1fad_e2ce036d-9cbf-479d-9b67-8b4648742e8c" /f</Arguments>
<Wait RollbackOnError="true" Timeout="30"/>
</PublishPackage>
<UnpublishPackage>
<Path>cmd.exe</Path>
<Arguments>/C REG DELETE HKCU\SOFTWARE\Microsoft\AppV\Client\RunVirtual\Excel.exe /f</Arguments>
<Wait RollbackOnError="false" Timeout="30"/>
</UnpublishPackage>
</UserScripts>
However adding a similar change via the AppxManifest.xml is slightly more complex. Whenever we import a new AppxManifest.xml via the Advanced tab in Edit mode, we need to save the package afterwards for the change to take effect. And what does this do? It flips the VersionId of the package! So we’re left with a situation whereby whenever we update the VersionId in the AppxManifest.xml it becomes redundant as soon as we save the updated package!
Introducing the Powershell approach….
Ignore the slightly different XML syntax for now – this is irrelevant in the context of this tutorial.
<appv:UserScripts>
<appv:PublishPackage>
<appv:Path>powershell.exe</appv:Path>
<appv:Arguments>-ExecutionPolicy ByPass -command "Get-AppvClientPackage -all | where {$_.Name -eq 'Alkane_Package'} | foreach { New-Item -Path HKCU:\SOFTWARE\Microsoft\AppV\Client\RunVirtual -Name Excel.exe -Value ($_.PackageId.toString() + '_' + $_.VersionId.toString()) -Force }"</appv:Arguments>
<appv:Wait RollbackOnError="false" />
</appv:PublishPackage>
<appv:UnpublishPackage>
<appv:Path>powershell.exe</appv:Path>
<appv:Arguments>-ExecutionPolicy ByPass -command "Remove-Item -Path HKCU:\SOFTWARE\Microsoft\AppV\Client\RunVirtual\Excel.exe -Recurse -Force"</appv:Arguments>
<appv:Wait RollbackOnError="false" />
</appv:UnpublishPackage>
</appv:UserScripts>
The main part to note is the Powershell one-liner, which I’ll explain below:
Get-AppvClientPackage -all | where {$_.Name -eq 'Alkane_Package'} | foreach { New-Item -Path HKCU:\SOFTWARE\Microsoft\AppV\Client\RunVirtual -Name Excel.exe -Value ($_.PackageId.toString() + '_' + $_.VersionId.toString()) -Force }
What we’re doing here is:
- Getting all locally ADDED packages (Note that Get-AppvClientPackage -Name “Alkane_Package” will return nothing since the package is not published when the PublishPackage event runs!)
- Looping through them where the Name attribute is the name of my target package (Alkane_Package)
- We then use foreach because of this
- And then we can dynamically get the PackageId and VersionId of the package to add it to the registry value
Hi..great article…
I came across this issue a few weeks ago and realised that every time I saved the manifest file it changed the VersionID.
How do you modify the manifest file to add multiple EXE files..?
For Example i have sequenced Adobe Acrobat and want to add the Run Virtual keys for all the addins (WinWord,Excel,Powerpoint,Outlook)
Hi Gary. Thanks! If I’m understanding correctly, you may want to look at this post? http://www.alkanesolutions.co.uk/2016/05/25/using-runvirtual-present-excel-addins/
All i am looking for is the command to add multiple EXE’s under the runvirtual key..
So is it just a comma after each EXE…
RunVirtual -Name Excel.exe,Winword.exe,Outlook.exe
In using CMD /C and the 2 x config files we add multiple EXE’s as below…
REG ADD HKLM\Software\Microsoft\AppV\Client\RunVirtual\WINWORD.EXE /ve /d b8c914a5-7183-4b08-99a9-0b9b8e92da3f_90daefa1-8cf9-4d7f-8a4a-49fb80c4074e /f | REG ADD HKLM\Software\Microsoft\AppV\Client\RunVirtual\EXCEL.EXE /ve /d b8c914a5-7183-4b08-99a9-0b9b8e92da3f_90daefa1-8cf9-4d7f-8a4a-49fb80c4074e /f | REG ADD HKLM\Software\Microsoft\AppV\Client\RunVirtual\POWERPNT.EXE /ve /d b8c914a5-7183-4b08-99a9-0b9b8e92da3f_90daefa1-8cf9-4d7f-8a4a-49fb80c4074e /f | REG ADD HKLM\Software\Microsoft\AppV\Client\RunVirtual\OUTLOOK.EXE /ve /d b8c914a5-7183-4b08-99a9-0b9b8e92da3f_90daefa1-8cf9-4d7f-8a4a-49fb80c4074e /f
Ahh I see. In that case maybe try this:
Let me know if this works or not as I don’t have time to test it. Be careful how you manage your RunVirtual entries though. As previously linked to in these comments, I’d be tempted to create a ‘blank’ package for each process to be honest.
Hi ,
I Have created a package for excel add ins now i want to add a key in RunVirtual folder in registry after updating UserScript.xml
<UserScripts>
<PublishPackage>
<Path>cmd.exe</Path>
<Arguments>/C REG ADD HKLM\SOFTWARE\Microsoft\AppV\Client\RunVirtual\Excel.exe /t REG_SZ /d “0caeee91-79fa-4f7a-a3df-7a0a62b455ac_7982df1a-9b0a-40f8-ab9a-23d6950f8662″ /f</Arguments>
<Wait RollbackOnError=”true” Timeout=”30″/>
</PublishPackage>
<UnpublishPackage>
<Path>cmd.exe</Path>
<Arguments>/C REG DELETE HKCU\SOFTWARE\Microsoft\AppV\Client\RunVirtual\Excel.exe /f</Arguments>
<Wait RollbackOnError=”false” Timeout=”30″/>
</UnpublishPackage>
</UserScripts>
But registry key is not added. please help me to solve this problem.
Hi. I suspect it’s a permissions issue since you’re trying to add a HKLM registry entry from a User script…
i am using above script in appvmainfest.xml but still not adding registry key dynamically. please help me.
<appv:UserScripts>
<appv:PublishPackage>
<appv:Path>powershell.exe</appv:Path>
<appv:Arguments>-ExecutionPolicy ByPass -command “Get-AppvClientPackage -all | where {$_.Name -eq ‘AddInExcel’} | foreach { New-Item -Path HKCU:\SOFTWARE\Microsoft\AppV\Client\RunVirtual -Name Excel.exe -Value ($_.PackageId.toString() + ‘_’ + $_.VersionId.toString()) -Force }”</appv:Arguments>
<appv:Wait RollbackOnError=”false” />
</appv:PublishPackage>
<appv:UnpublishPackage>
<appv:Path>powershell.exe</appv:Path>
<appv:Arguments>-ExecutionPolicy ByPass -command “Remove-Item -Path HKCU:\SOFTWARE\Microsoft\AppV\Client\RunVirtual\Excel.exe -Recurse -Force”</appv:Arguments>
<appv:Wait RollbackOnError=”false” />
</appv:UnpublishPackage>
</appv:UserScripts>
A few thoughts off the top of my head…..check that your package name is ‘AddInExcel’ as per your script, check that you are not publishing in a global context, check for any dodgy quotes (As a result of copying and pasting – these two characters are different ““).
Thanks Kae, yes package name is AddInExcel. I am not getting how do i check this package publishing in Global context.