WIX :Adding a shortcut to StartMenu folder Windows 10 - wix

I have an application that will install a shortcut to Start Menu folder. It is working perfectly in Win7. But shortcut is not coming when I install the application in Windows 10 machine. The shortcut entry in my WIX file is given below.
<Component Id="cmptest" Guid="*" KeyPath="yes">
<Shortcut Id="test.exe2" Directory="StartMenuFolder"
Name="test" Target="[#test.exe]" Hotkey="0" IconIndex="0" Show="normal" />
</Component>

Before getting into too much detail:
Are you sure the shortcut really isn't there? The Windows 10 start menu is so strange that I find I have to look twice very often to find shortcuts that are actually there. Just checking.
For that matter, are you sure the install actually completes in Windows 10? Perhaps it rolls back and you didn't notice?
The Directory StartMenuFolder does not compile for my test project, until I add it as a directory under TARGETDIR myself:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="StartMenuFolder" />
</Directory>
I assume you already have this folder added there to make your setup compile. You could also try ProgramMenuFolder for testing and see if the shortcut shows up.
Where is the rest of your WiX source? I can't see if you actually install the file you reference: #test.exe? Does the component that hosts that file actually get installed on Windows 10?
And for some extra strangeness: I haven't seen this much, but since the problem manifests itself on Windows 10, maybe have a read of this answer and see if it rings any bells: Wix Uninstall Shortcut not working
Essentially some shortcuts are hidden auto-magically in Windows 8 and probably upwards. I don't see any reason why your shortcut should be hidden though.

I have been able to get the shortcuts for to show up using the ProgramMenuFolder suggested by Stein Asmul for testing. Below is my setup which is working, with the exception being that my icons not showing up.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Barcode Printer App" />
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="BarcodePrinterAppShortcuts" Name="Barcode Printer App" />
</Directory>
</Directory>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Id="BarcodeAppExe" Source="$(var.BarcodePrinterHelperApp.TargetPath)" >
<Shortcut Id="BarcodeAppShortcut"
Directory="BarcodePrinterAppShortcuts"
Name="Barcode Printer App"
WorkingDirectory="INSTALLFOLDER"
Advertise="yes"
Icon="icon.ico"
IconIndex="0"
>
</Shortcut>
</File>
<RemoveFolder Id="DeleteTheBarcodeAppShortcut"
Directory="BarcodePrinterAppShortcuts"
On="uninstall" />
</Component>
</ComponentGroup>
<Component Id="UninstallShortcut" Guid="*" Directory="BarcodePrinterAppShortcuts">
<Shortcut Id="UninstallThisProduct"
Name="Uninstall Barcode Printer App"
Description="Uninstalls Barcode Printer App"
Target="[System64Folder]msiexec.exe"
Arguments="/x [ProductCode]" />
<RegistryValue Root="HKCU" Key="Software\Powerserve\BarcodePrinterApp" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>

It could be permission issue. Try to run your installation As Administrator (or, open Command Prompt as Administrator) and run your installation from there. Also, you may want to check User Account Control settings and lower the slider if it's too restrictive.

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 toolset: How to remove Shortcut on install?

We recently changed the name of our application from let's say test1app to test2app. So now when our customers update my application from the old version to this new one I want the shortcuts for test1app to get removed because I have already removed all the files with that name(I removed them with RemoveFile and RemoveFolder).
Is it possible to remove .lnk files with RemoveFile as well?
I have one shortcut on the desktop and one in the program files.
I have tried to remove the .lnk file with remove file but it does not get removed. I even tried to add a plain .txt file and remove it from the desktop but it does not get removed either so maybe I am calling the wrong Dictionary or something?
This is a snipped from my code:
`<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationStartMenuDirectory" Name="Test2"/>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>`
`<DirectoryRef Id="ProgramMenuFolder">
<Component Id="delete_test1_shortcuts" Guid="*">`
//Here I am trying to remove the shortcut from the Application start menu dir
`<RemoveFile Directory="ApplicationStartMenuDirectory" Id="test1.lnk_shortcut" Name="test1.lnk" On="install" />
<RegistryValue Root="HKCU" Key="Software\Company\test1" Name="installed" Type="integer" Value="1" KeyPath="yes"/>`
//Here I am trying to remove the desktop shortcut
`<RemoveFile Directory="DesktopFolder" Id="desktop_test1.lnk" Name="test1.lnk" On="install" />
</Component>`
`</DirectoryRef>`
//then reference the component
`<Feature Id="MainApplication" Title="testapp" Level="1">
<ComponentRef Id="delete_test1_shortcuts"/>
</Feature>`
The goal is that when the customers upgrade their version that the all the test1 shortcuts get removed so they only see the test2 shortcuts on install.
Please try this:
Remove the old component containing the old binary (EXE) AND the shortcut (and whatever other content is there).
Add a new component with the new binary (EXE) AND the new shortcut with the new name (important). Make sure it has a new component GUID.
This is all related to how component reference counting is done in MSI: Change my component GUID in wix?
Essentially: there is a 1:1 match between absolute installation path and the component GUID. If one changes, change the other and the older component will be uninstalled as a whole entity: all settings will be removed. There should be no overlapping resources between the components (not the same name shortcut for example).
I am not sure, why it did not work for you, I just had to do the same and the code below worked for me (some properties omitted for clarity). Wix 3.11.2
<DirectoryRef Id="ProgramMenuFolder">
<Component Id="StartMenuShortcut" Guid="{guid}">
<Shortcut Id="StartMenuShortcut"
Name="Myapp"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<!-- added the line below -->
<RemoveFile Id="RemoveOldStartMenuShortcut" On="install" Name="MyOldShortcut.lnk"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="DesktopShortcut" Guid="{guid}">
<Shortcut Id="DesktopShortcut"
Name="Myapp"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<!-- added the line below -->
<RemoveFile Id="RemoveOldDesktopShortcut" On="install" Name="MyOldShortcut.lnk"/>
</Component>
</DirectoryRef>

How to keep taskbar shortcut during update?

I have the following situation.
My product installs the binaries inside c:\Program Files (x86)\MyCompany\MyApp\ and a shortcut under C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MyCompany.
I build the msi using this great example: https://helgeklein.com/blog/2014/09/real-world-example-wix-msi-application-installer/
I just added the following piece of code
<!-- ApplicationShortcut-->
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="!(loc.ManufacturerName)">
<Component Id="ApplicationShortcut" Guid="F4B7EAFA-FF19-41B4-8267-3AEFC12235A7">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="!(loc.ApplicationName)"
Description="!(loc.ProductDescription)"
Target="[INSTALLDIR]MyApp.exe"
WorkingDirectory="INSTALLDIR"
/>
<RemoveFolder Id="RemoveApplicationProgramsFolder" Directory="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\!(loc.ManufacturerName)\!(loc.ApplicationName)" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
The problem is the following
I install the application the fist time, it will install the shortcut just fine
Now I start the app and choose Pin to taskbar, this will create a shortcut inC:\Users\\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar`
If I rebuild the msi and execute the setup again, the taskbar shortcut is not clickable anymore, because the shortcut in C:\Users\<user>\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar is missing
Is it possible to maintain the taskbar shortcut during an update?
I found the answer here: https://stackoverflow.com/a/33402698/98491
<InstallExecuteSequence>
<RemoveShortcuts>Installed AND NOT UPGRADINGPRODUCTCODE</RemoveShortcuts>
</InstallExecuteSequence>
This prevents shortcuts from being uninstalled during an update.
As described in the comments, the disadvantage is that, after uninstall, the TaskBarShortCut remains, but that is something that a user might expect. Having to recreate a pinned taskbar shortcut everytime he updates a software is not.

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