Placing multiple Shortcuts in a Wix Installer - wix

I'm trying to add multiple shortcuts under a certain folder using Wix. The code looks like this:
<DirectoryRef Id ="TARGETDIR">
<Directory Id="DesktopFolder" Name="DesktopFolder">
<Component Id="DesktopP" Guid="61AE5ABE-9ED2-43B0-98C4-3050A40BF061">
<Shortcut Id="DesktopMyProgramShortcut" Name="$(var.MyProgramLabelShortcut)" Target="[#MyProgramcsproja015777b77a239eeb0bd49c2dafdbe31]" WorkingDirectory="bin"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="SOFTWARE\Example\Shortcuts" Name="167CE804-4A37-45B8-B010-EB6B3E73BE54" Type="string" Value="" KeyPath="yes"/>
</Component>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id ="ProgramMenuFolderMyProgram" Name ="$(var.MyProgramLabelShortcut)">
<Component Id="ProgramMenuMyProgram" Guid="A7B4A27B-9367-4AFF-B8CC-D6651B18FBFD">
<Shortcut Id="ProgramMenuMyProgramShortcut" Name="$(var.MyProgramLabelShortcut)" Target="[#MyProgramcsproja015777b77a239eeb0bd49c2dafdbe31]" WorkingDirectory="bin"/>
<Shortcut Id="ProgramMenuMyProgramManual" Name="$(var.MyProgramLabelShortcut)" Target="[documents]" Icon="shell32.dll" IconIndex="45"/>
<RemoveFolder Id="ProgramMenuFolderMyProgram" On="uninstall"/>
<RegistryValue Root="HKCU" Key="SOFTWARE\Example\Shortcuts" Name="167CE804-4A37-45B8-B010-EB6B3E73BE54" Type="string" Value="" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</DirectoryRef>
The weird behavior is that, when I try to place more than one shortcut, only the second one is added. I've tried placing the Shortcut in separate Components but still acts that way. In Windows7 works perfectly by the way.
Any suggestion about how to fix it?
Thanks in advance!

The problem had to do with the name of the shortcuts. I guess that, since their names were equal, the first shortcut was overwritten by the second one. I've fixed it changing the name of the second shortcut.

Related

How do I tell wix to install a file in a directory set in a property?

I want to do the following where XLSTART is defined as:
<CustomAction Id="AssignXLSTART" Return="check" Execute="firstSequence" Directory ='XLSTART' Value='[AppDataFolder]\Microsoft\Excel\XLSTART'>
</CustomAction>
And then I have a subsequent CustomAction that calls some C# code that may change this value.
And then in the list of files to install I have:
<Directory Id="XlStartFolderId" Name="[XLSTART]">
<Component Id="ExcelMacro_xla" Guid="26D21093-B617-4fb8-A5E7-016493D46055" DiskId="1">
<File Id="ExcelXLA" Name="AutoTagExcelMacro.xlam" ShortName="XLMacro.xla" Source="$(var.srcFolder)\AutoTagExcelMacro.xlam"/>
</Component>
</Directory>
But the above puts it in the INSTALLDIR[XLSTART]. How do I get it to read this as a property?
You should be able to install to the userprofile directory you refer to like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="LocalAppDataFolder">
<Directory Id="Microsoft" Name="Microsoft">
<Directory Id="Excel" Name="Excel">
<Directory Id="XLSTART" Name="XLSTART">
<Component Id="ExcelAddIn" Feature="MyFeature" Guid="{11111-1111-GUID-HERE-YOURGUIDHERE}">
<File Source="C:\SourceFiles\MyAddin.xla" />
<RemoveFolder Id="Microsoft" On="uninstall" Directory="Microsoft" />
<RemoveFolder Id="Excel" On="uninstall" Directory="Excel" />
<RemoveFolder Id="XLSTART" On="uninstall" Directory="XLSTART" />
<RegistryValue Root="HKCU" Key="Software\MySoftware" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
I would suggest you use the per-machine xlstart folder instead - if it still exists. I am not sure it does. The the addin is loaded for every user on the box on every launch. Generally I prefer this. It has been ages since I looked at this, so this could have changed in newer Office versions - in fact I am sure it has, but the details are unclear to me.
System Folder Properties: There are a number of System Folder Properties that can be used in MSI files to specify installation location - LocalAppDataFolder is just one of them: https://learn.microsoft.com/en-us/windows/win32/msi/property-reference#system-folder-properties
Figured it out. You need to install to the INSTALLDIR and then use CopyFile
<!-- place it in C:\Program Files (x86)\Microsoft Office\Root\Office16\XLSTART\ -->
<Component Id="ExcelMacro_xla" Guid="26D21093-B617-4fb8-A5E7-016493D46055" DiskId="1">
<File Id="ExcelXLA" Name="AutoTagExcelMacro.xlam" ShortName="XLMacro.xla" Source="$(var.srcFolder)\AutoTagExcelMacro.xlam">
<CopyFile Id='CopyXlMacro' DestinationProperty='XLPATH' DestinationName='AutoTagExcelMacro.xlam'/>
</File>
</Component>

WIX - Rename shortcut in MSP

I am not that experienced with WiX and I am having a problem when renaming a shortcut during update via MSP. In my previous MSI I have created a desktop shortcut using the following
<DirectoryRef Id="TARGETDIR">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="MyShortcut" Guid="38EF1A86-5D1B-4D78-AD66-DD1AA6635A9B" Win64="$(var.Variables_Win64)" MultiInstance="no">
<Shortcut Id="MyShortcut"
Directory="DesktopFolder"
Icon="MyIcon"
Name="My Application"
Description="Runs my application"
Target="[URL]" />
<RemoveFolder Id='DesktopFolder' On='uninstall'/>
</Component>
</Directory>
</DirectoryRef>
In my MSP I want to rename the schortcut as such
<DirectoryRef Id="TARGETDIR">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="MyShortcut" Guid="38EF1A86-5D1B-4D78-AD66-DD1AA6635A9B" Win64="$(var.Variables_Win64)" MultiInstance="no">
<Shortcut Id="MyShortcut"
Directory="DesktopFolder"
Icon="MyIcon"
Name="My New Application"
Description="Runs my new application"
Target="[URL]" />
<RemoveFolder Id='DesktopFolder' On='uninstall'/>
</Component>
</Directory>
</DirectoryRef>
What I get when I run my upgrade is a new desktop shortcut as well as the orphaned old shortcut. I understand why this is happening from this post why two shortcuts after Major upgrade (migration)? but I am not sure how I can work around this behaviour and either update the original shortcut name or delete the orphaned one instead. I cannot build an MSI it has to be an MSP so any advice would be welcome.
Thank you in advance ;-)
The solution appears to be add in a RemoveFile but with the full name including extension to the shortcut. I had initially tried this approach before posting but had not specified the .lnk on the name so it did not work.
<DirectoryRef Id="TARGETDIR">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="MyShortcut" Guid="38EF1A86-5D1B-4D78-AD66-DD1AA6635A9B"
Win64="$(var.Variables_Win64)" MultiInstance="no">
<Shortcut Id="MyShortcut"
Directory="DesktopFolder"
Icon="MyIcon"
Name="My New Application"
Description="Runs my new application"
Target="[URL]" />
<RemoveFolder Id='DesktopFolder' On='uninstall'/>
<RemoveFile Id='LegacyShortcut ' Name='My Application.lnk' On='install'/>
</Component>
</Directory>
</DirectoryRef>

WiX Proper Creation of Desktop Shortcut

There are two answers on Create shortcut to desktop using WiX
Both these answers lack any real explanation of what is going on. What is the difference between these two methods of creating shortcuts? The first method falls in line with WiX - Create shortcut documentation.
The second method has a MergeRedirectFolder which I can't seem to find any documentation on, and I don't understand why the second example doesn't require the registry setting since according to WiX Documentation, a registry setting:
is required as a Shortcut cannot serve as the KeyPath for a component when installing non-advertised shortcuts for the current users.
Does this mean that the second method is an advertised shortcut? Or is it an answer that assumes the user is installing per machine? Or am I lost in the sauce? (Quite possible - second day trying to use WiX, since Microsoft forced me down this path.)
The first one:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut"
Name="Text under your icon"
Description="Comment field in your shortcut"
Target="[MYAPPDIRPROPERTY]MyApp.exe"
WorkingDirectory="MYAPPDIRPROPERTY"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software/MyAppName"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</Directory>
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="MyCompany" Name="MyCompany">
<Directory Id="MYAPPDIRPROPERTY" Name="MyAppName">
</Directory>
</Directory>
</Directory>
The second one:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" SourceName="Desktop" />
<Directory Id="MergeRedirectFolder">
<Component Id="MyExeComponent" Guid="*">
<File Id="MyExeFile" Source="$(var.ExeSourcePath)" KeyPath="yes">
<Shortcut
Id="DesktopShortcut"
Directory="DesktopFolder"
Name="$(var.ShortcutName)"
WorkingDirectory="MergeRedirectFolder" />
</File>
</Component>
</Directory>
</Directory>
Caveat: Per Doc's comment, since neither example specified the Advertise attribute, neither should create an advertised shortcut. I don't remember what led me to write the answer below; it seems likely to be incorrect. I'll leave the answer in tact in case there is some subtle truth behind it.
The first example creates an advertised shortcut; the second creates a non-advertised shortcut. The rules for the two types of shortcuts are described with the Shortcut Table Target column.
A non-advertised shortcut is a standard Windows shortcut like you would create with Windows Explorer. An advertised shortcut enhances resiliency by verifying that all the components in the feature are installed when the shortcut is activated.

After install different versions of my application side-by-side, uninstall one version doesn't remove shortcut from program menu.

I created an installer using WIX. As part of the installation, two shortcuts (launch and uninstall) are added to "ProgramMenu->MyCompany->MyProductName".
After I install two versions of the same application side by side. I tried to use the uninstall shortcut to uninstall one version.
The uninstall removes all the files and folders for the version. But failed to remove the shortcuts. And when I click on uninstall again. The following error shows:
"This action is only valid for products that are currently installed"
Then I run the uninstall for the other version, this time both shortcuts for THAT version are removed successfully. But leave the shortcuts for the failed version stuck in "ProgramMenu->MyCompany->MyProductName" forever. I had to manually delete them.
Here is the code I use to create the shortcuts. Anything I did wrong?
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyShortcutDir" Name="MyCompany">
<Directory Id="MyProductShortcutDir" Name="MyProduct">
<Component Id="cmpMyProductShortcut" Guid="*">
<Shortcut Id="MyAppShortcut" Name="My App" Description="My Application" Target="[INSTALLFOLDER]MyApp.exe" />
<RemoveFolder Id="RemoveMyCompanyShortcutDir" On="uninstall" Directory="MyCompanyShortcutDir" />
<RegistryValue Root="HKCU" Key="Software\My Company\My Product\" Name="Installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
<Component Id="cmpUninstall" Guid="*">
<Shortcut Id="UninstallShortcut" Name="Uninstall" Description="Uninstall My App"
Target="[System64Folder]msiexec.exe" Arguments="/x [ProductCode] /Lv d:\uninstall.log " Directory="MyProductShortcutDir" />
<RegistryValue Root="HKCU" Key="[Software\My Company\My Product\" Name="Uninstall" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="removeShortcut" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
I solved this issue myself, basically two things needed:
Change the ProductCode to *, this allows side-by-side install of two versions.
Make sure the Component Guid for Shortcut to be * as well

Why Start menu shortcut is not removed after uninstallation?

When i installed .msi file, I am getting generated shortcuts on start menu and desktop, but when i am uninstalling the desktop shortcut getting removed but start menu. My code is bellow. Please help me to solve my problem. I have spent almost 1 day behind this.
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuSubfolder" Name="Kiosk">
<Component Id="ApplicationShortcuts" Guid="12345678-1234-1234-1234-333333333333">
<Shortcut Id="ApplicationShortcut1" Name="Kiosk" Description="Solusoft Product" Target="[INSTALLDIR]AMP\1.0.0.0\mpkiosk.exe" WorkingDirectory="INSTALLDIR"/>
<RegistryValue Root="HKCU" Key="Software\Kiosk" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="ApplicationShortcut1" On="uninstall"/>
</Component>
</Directory>
</Directory>
In my case, on the component, I had GUID="*" and the shorcuts weren't removed.
I used a hardcoded GUID like: Guid="cc509cb7-c1a1-46cf-8c62-7cbb0017783c" and the shortcuts were removed.
Regards.
You have a mistake in your code.
Instead of:
<RemoveFolder Id="ApplicationShortcut1" On="uninstall"/>
Use:
<RemoveFolder Id="ProgramMenuSubfolder" On="uninstall"/>
This should do it.
In my case, I was trying different options, and had a commented out section that had the same GUID. Changing it to a different GUID, even though the other was commented out, worked.
There is the code below that i'm using in my project. Hope, it will helps. I think you could use 'RemoveFile' instead 'RemoveFolder' and don't forget to put 'Name' attribute inside.
<RegistryKey Action="createAndRemoveOnUninstall" Root="HKCU"
Key="Software\$(var.ManufacturerEng)\$(var.ProductName)\$(var.ApplicationName)">
<RegistryValue Name="ShortcutService"
Type="integer" Value="1"
KeyPath="yes">
</RegistryValue>
</RegistryKey>
<Shortcut Advertise="no" Directory="ApplicationProgramsFolder"
Name="ServiceCC"
Target="[INSTALLLOCATION]Service.exe"
Id="SHORTCUT_serv"
WorkingDirectory="INSTALLLOCATION">
</Shortcut>
<RemoveFile Id="remove_serviceshort" Name="ServiceCC" On="uninstall"/>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
</Component>
In my case it was a copy paste error. I was using the same Guid for the component as another product I had created a shortcut in that folder for. Hence on uninstall the removal of the icon failed