How do I create a shortcut on the desktop from a wix setup project?
The shortcut is a non-advertised one.
Remember to put the component in your feature tag.
<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\MyCompany\MyApplicationName"
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">
<!-- main installation files -->
</Directory>
</Directory>
</Directory>
</Directory>
I think my way is easier, no need for you to create a registry key:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" SourceName="Desktop" />
<Directory Id="MergeRedirectFolder">
<Component Id="MyExeComponent" Guid="{PUT-GUID-HERE}">
<File Id="MyExeFile" Source="$(var.ExeSourcePath)" KeyPath="yes">
<Shortcut
Id="DesktopShortcut"
Directory="DesktopFolder"
Name="$(var.ShortcutName)"
WorkingDirectory="MergeRedirectFolder" />
</File>
</Component>
</Directory>
</Directory>
Thanks for example. In WIX 3.8 it still raises:
"Error 3 ICE43: Component ... has non-advertised shortcuts. It should use a registry key under HKCU as its KeyPath, not a file."
So I did this such way in a file with features:
<Component Id="cmp79F6D61F01DD1060F418A05609A6DA70"
Directory="dirBin" Guid="*">
<File Id="fil34B100315EFE9D878B5C2227CD1454E1" KeyPath="yes"
Source="$(var.SourceDir)\FARMS.exe" >
<Shortcut Id="DesktopShortcut"
Directory="DesktopFolder"
Name="FARMS $(var.FarmsVersion)"
Description="Local Land Services desktop application"
WorkingDirectory="INSTALLFOLDER"
Icon="FARMS.exe"
IconIndex="0"
Advertise="yes" >
<Icon Id="FARMS.exe" SourceFile="$(var.SourceDir)\FARMS.exe" />
</Shortcut>
</File>
</Component>
And mentioned desktop folder in a file with product definition:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop" />
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="FARMS" >
</Directory>
</Directory>
</Directory>
</Fragment>
It seems lot easier in this documentation.
First, you have to point your DesktopFolder,
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop"/>
Then you should create Shortcut component for file that you want to create shortcut of.
<Component Id="PutYourComponentIdHere" Directory="FileDirectory" Guid="*">
<File Id="NotYourComponentId" KeyPath="yes" Source="..\YourFileSource\YourExecutable.exe">
<Shortcut Id="desktopServer" Directory="DesktopFolder" Name="YourShourtcutName" WorkingDirectory='WhereShouldYourShortcutPoint' Advertise="yes"/>
</File>
</Component>
It worked for me. I need to put icon but thats easy part. Hope it works.
After too much effort, I used this way:
<Product ...>
<Feature Id="ProductFeature" Title="SetupProject" Level="1">
...
...
<ComponentRef Id="cmpDesktopShortcut" />
</Feature>
<Component Id="cmpDesktopShortcut" Guid="PUT-GUID-HERE" Directory="DesktopFolder" >
<Shortcut Id="MyDesktopShortcut"
Name="Setup Project"
Description="Opens the program."
Directory="DesktopFolder"
Target="[INSTALLFOLDER]App.exe"
WorkingDirectory="INSTALLFOLDER"/>
<RegistryValue Root="HKCU" Key="Software\My Company\Sample Application" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Product>
I believe that using a "Current User" (HKCU) registry key as Key Path causes problems on a multi-user machine tool. Because the registry key is only created for the current user and when a different user logs in, then the auto-repair of the installation kicks in.
Related
I have checked the answers here and the blog post at http://robmensching.com/blog/posts/2007/4/27/how-to-create-an-uninstall-shortcut-and-pass-all-the/, but I just cannot see what I am missing. I believe I am using MfgStartMenuFolder correctly. The error is at:
<Directory Id="MfgStartMenuFolder" Name="!(bind.property.Manufacturer)" />
In my main fragment I have:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="ManufacturerFolder" Name="!(bind.property.Manufacturer)" >
<Directory Id="INSTALLFOLDER" Name="!(bind.property.ProductName)" />
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" >
<Directory Id="MfgStartMenuFolder" Name="!(bind.property.Manufacturer)" />
</Directory>
</Directory>
In my fragment for Start Menu folder objects I have:
<DirectoryRef Id="MfgStartMenuFolder" >
<Component Id="ApplicationShortcut" Guid="MY-GUID" >
<Shortcut Id="ApplicationStartMenuShortcut"
Name="!(bind.property.ProductName)"
Description="Find Files (Reasonably) Fast"
Directory="MfgStartMenuFolder"
Target="[INSTALLFOLDER]\FinderOfFiles.exe"
WorkingDirectory="INSTALLFOLDER"
Icon="MyShortcutIcon" />
<RemoveFolder Id="RemoveMfgStartMenuFolder"
Directory="MfgStartMenuFolder"
On="uninstall" />
<RegistryValue Root="HKCU"
Key="Software\[Manufacturer]\[ProductName]\ProgramMenuShortcut"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes" />
</Component>
</DirectoryRef>
I am using WiX 3.11 and not using any add-ons like Wax.
I rewrote the whole sections, so this issue is moot.
I have created an installer of a c# application. Now I want to add a Desktop shortcut: I have followed the WiX official documentation as well as the other suggested answers on this site but still my installer doesn't create the shortcut.
No errors occur during the compilation. My .wsx file is the following:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="Myapp">
<Component Id="Trojan2CostCalculator.exe" Guid="*">
<File Id="Myapp.exe" Source="$(var.Myapp.TargetPath)" KeyPath="yes" Checksum="yes"/>
</Component>
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut"
Name="Myapp"
Description="Made by me"
Target="$(var.Myapp.TargetPath)Myapp.exe"
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software\Myapp"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes" />
</Component>
</Directory>
...
and I have added the component:
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentRef Id="ApplicationShortcutDesktop"/>
</Feature>
The installation succesfully completes but no shortcut is created. What am I missing?
I think your Shortcut's 'Target' is wrong. You're passing it the build time source path. It should be something like "[APPLICATIONROOTDIRECTORY]Myapp.exe". See - wixtoolset.org/documentation/manual/v3/xsd/wix/shortcut.html
I have an installer that creates a folder "_source" in the targetdir, which contains the "SAMPLE.exe" and other files. I am trying to generate a shortcut that will point to that exe but it seems to generate/copy that exe and place it in the target directory. Its able to run the executable but since other files are needed in the _source directory, it cannot continue. How do I point to the exe in _source without making a copy of that exe?
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" SourceName="Desktop"/>
<Directory Id="MergeRedirectFolder">
<Component Id="ApplicationShortcut" Guid="1D120AC7-6BAC-4F99-8611-029ED3F2EA3A">
<File Id="MyExeFile" Source="!(wix._source)\SAMPLE.exe" KeyPath="yes">
<Shortcut Id="DesktopShortcut" Directory="DesktopFolder" Name="SAMPLE" WorkingDirectory="MergeRedirectFolder"
Icon="SAMPLE.exe"
IconIndex="0"
Advertise="yes" >
<Icon Id="SAMPLE.exe" SourceFile="!(wix._source)\icon1.ico" />
</Shortcut>
</File>
</Component>
</Directory>
If you are attempting to install under program files, i would start with something like this:
<Product ...>
...
<Feature ...>
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Icon Id="SAMPLE.ico" SourceFile="!(wix._source)\icon1.ico" />
</Product>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MergeRedirectFolder" />
</Directory>
<Directory Id="DesktopFolder" SourceName="Desktop"/>
</Directory>
<ComponentGroup Id="ProductComponents" Directory="MergeRedirectFolder">
<Component Id="ApplicationShortcut" Guid="1D120AC7-6BAC-4F99-8611-029ED3F2EA3A">
<File Id="MyExeFile" Source="!(wix._source)\SAMPLE.exe" KeyPath="yes">
<Shortcut Id="DesktopShortcut" Directory="DesktopFolder" Name="SAMPLE" WorkingDirectory="MergeRedirectFolder"
Icon="SAMPLE.ico"
IconIndex="0"
Advertise="yes" />
</File>
</Component>
</ComponentGroup>
I have built a WiX installer for an application and in it I need to copy some files to a specific folder on the "C:" drive. I originally coded my directories like this:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompanyInstall" Name="MyCompany">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="[WindowsVolume]\MyCompany">
<Directory Id="MYCOMPANYMYSPECIALFOLDERDATAFOLDER" Name="MySpecialFolder">
<Directory Id="MYCOMPANYMYSPECIALFOLDERTRENDINGFOLDER" Name="Trending"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyProgramMenu" Name="MyCompany">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)"/>
</Directory>
</Directory>
<Directory Id="DesktopFolder"/>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="MYCOMPANYROOT">
<Component Id="CreateDirectories" Guid="60D9E460-89C8-42D2-8581-D858785A1817">
<CreateFolder Directory="MYCOMPANYROOT"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTDATAFOLDER"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTTRENDINGFOLDER"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<DirectoryRef Id="MYCOMPANYMYPRODUCTDATAFOLDER">
<Component Id="FirstFile.xml" Guid="E9879B51-1C74-47BF-A475-3B77D66297E2">
<File Id="FirstFile.xml" Source="$(var.TargetDir)FirstFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="SecondFile.xml" Guid="69A86F79-4596-4714-9FE7-628882ADA303">
<File Id="SecondFile.xml" Source="$(var.TargetDir)SecondFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="MyCompanyMyProductHelp.pdf" Guid="D2D3CDF1-61FA-4021-8F56-F23770580AA0">
<File Id="MyCompanyMyProductHelp.pdf" Source="$(var.TargetDir)Documents\MyCompany My Product Help.pdf" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<Icon Id="$(var.ProductName)Icon.EXE" SourceFile="$(var.TargetPath)"/>
</Fragment>
But on one computer in the office I kept getting the case that the files meant for "C:\MyCompany\MySpecialFolder\" were not copied. I then tried to hard code the "C:" drive like so:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompanyInstall" Name="MyCompany">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="C:\MyCompany">
<Directory Id="MYCOMPANYMYSPECIALFOLDERDATAFOLDER" Name="MySpecialFolder">
<Directory Id="MYCOMPANYMYSPECIALFOLDERTRENDINGFOLDER" Name="Trending"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyProgramMenu" Name="MyCompany">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)"/>
</Directory>
</Directory>
<Directory Id="DesktopFolder"/>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="MYCOMPANYROOT">
<Component Id="CreateDirectories" Guid="60D9E460-89C8-42D2-8581-D858785A1817">
<CreateFolder Directory="MYCOMPANYROOT"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTDATAFOLDER"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTTRENDINGFOLDER"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<DirectoryRef Id="MYCOMPANYMYPRODUCTDATAFOLDER">
<Component Id="FirstFile.xml" Guid="E9879B51-1C74-47BF-A475-3B77D66297E2">
<File Id="FirstFile.xml" Source="$(var.TargetDir)FirstFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="SecondFile.xml" Guid="69A86F79-4596-4714-9FE7-628882ADA303">
<File Id="SecondFile.xml" Source="$(var.TargetDir)SecondFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="MyCompanyMyProductHelp.pdf" Guid="D2D3CDF1-61FA-4021-8F56-F23770580AA0">
<File Id="MyCompanyMyProductHelp.pdf" Source="$(var.TargetDir)Documents\MyCompany My Product Help.pdf" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<Icon Id="$(var.ProductName)Icon.EXE" SourceFile="$(var.TargetPath)"/>
</Fragment>
But I got the same results.
Does anyone know why this won't work on only one machine?
Well I stumbled upon a fix. I don't understand why this fixes it, but it now works.
The key was to add the line:
<SetDirectory Id="MYCOMPANYROOT" Value="[WindowsVolume]MyCompany"/>
I would have thought that the "FileSource" attribute in the "Directory" tag would have done the trick, but alas it didn't.
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="[WindowsVolume]MyCompany">
I don't really understand why I needed this. If someone could explain, I would appreciate it.
Code follows:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompanyInstall" Name="MyCompany">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="[WindowsVolume]MyCompany">
<Directory Id="MYCOMPANYMYSPECIALFOLDERDATAFOLDER" Name="MySpecialFolder">
<Directory Id="MYCOMPANYMYSPECIALFOLDERTRENDINGFOLDER" Name="Trending"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyProgramMenu" Name="MyCompany">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)"/>
</Directory>
</Directory>
<Directory Id="DesktopFolder"/>
</Directory>
</Fragment>
<Fragment>
<!-- New line -->
<SetDirectory Id="MYCOMPANYROOT" Value="[WindowsVolume]MyCompany"/>
<!-- -->
<DirectoryRef Id="MYCOMPANYROOT">
<Component Id="CreateDirectories" Guid="60D9E460-89C8-42D2-8581-D858785A1817">
<CreateFolder Directory="MYCOMPANYROOT"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTDATAFOLDER"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTTRENDINGFOLDER"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<DirectoryRef Id="MYCOMPANYMYPRODUCTDATAFOLDER">
<Component Id="FirstFile.xml" Guid="E9879B51-1C74-47BF-A475-3B77D66297E2">
<File Id="FirstFile.xml" Source="$(var.TargetDir)FirstFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="SecondFile.xml" Guid="69A86F79-4596-4714-9FE7-628882ADA303">
<File Id="SecondFile.xml" Source="$(var.TargetDir)SecondFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="MyCompanyMyProductHelp.pdf" Guid="D2D3CDF1-61FA-4021-8F56-F23770580AA0">
<File Id="MyCompanyMyProductHelp.pdf" Source="$(var.TargetDir)Documents\MyCompany My Product Help.pdf" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<Icon Id="$(var.ProductName)Icon.EXE" SourceFile="$(var.TargetPath)"/>
</Fragment>
Have a read up on TARGETDIR, you will see that this links to ROOTDRIVE, which states:
If ROOTDRIVE is not set at a command line or authored into the
Property table, the installer sets this property. During an
administrative installation the installer sets ROOTDRIVE to the first
connected network drive it finds that can be written to. If it is not
an administrative installation, or if the installer can find no
network drives, the installer sets ROOTDRIVE to the local drive that
can be written to having the most free space.
So I suspect that on the single machine which you are having issues with, that it has another local drive with more space than c:
I had a similar problem.
On one of our machines WIX installed on E drive (flash disk) instead of C dive.
I have come across this answer which solve my problem: https://stackoverflow.com/a/8591139/1891969
Just replace the TARGETDIR value with "C:\".
<InstallExecuteSequence>
<Custom Action="FormatTargetDirectory" After="CostFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Directory="TARGETDIR" Value="[DRIVE_NAMES]" Id="FormatTargetDirectory"/>
Following some example code on the net, I got my first WiX installer to work. However, it placed my program menu shortcut directly on Program Menus. I really want to create a folder, Sample, in Program Menus for my link.
Original Code:
<Shortcut Id="startmenuSample" Directory="ProgramMenuFolder" Name="Sample 0.5"
WorkingDirectory='INSTALLDIR' Icon="Sample.exe" IconIndex="0" Advertise="yes">
Attempt at modifying code (fails with compiler error):
<Shortcut Id="startmenuSample" Directory="ProgramMenuFolder\Sample" Name="Sample 0.5"
WorkingDirectory='INSTALLDIR' Icon="Sample.exe" IconIndex="0" Advertise="yes">
Note the addition of \Sample.
How do I go about adding that link to a new folder in the Program Menu?
This is a sample test I did, when I was asked to do the same thing
<Package InstallerVersion="200" Compressed="yes" />
<WixVariable Id="Manufacturer" Value="StackOverFlowHelper"/>
<WixVariable Id="ShortProduct" Value="ShortCuts"/>
<Media Id="1" Cabinet="WixShortCut.cab" EmbedCab="yes" />
<Icon Id="ShortCutIcon" SourceFile="YOUR.ico"/>
<!-- The icon that appears in Add & Remove Programs. -->
<Property Id="ARPPRODUCTICON" Value="ShortCutIcon" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="ManufacturerFolder" Name="!(wix.Manufacturer)">
<Directory Id="INSTALLLOCATION" Name="!(wix.ShortProduct)">
<Component Id="ProductComponent" Guid="{YOUR_GUID}" KeyPath="yes">
<CreateFolder/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuManufacturer" Name="!(wix.ShortProduct)" />
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="ProgramFilesFolder">
<Component Id="ProgramMenuShortcuts" Guid="{YOUR_GUID}">
<CreateFolder Directory="ProgramMenuManufacturer"/>
<RemoveFolder Id="RemoveMenuShortcuts" Directory="ProgramMenuManufacturer" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\!(wix.Manufacturer)\!(wix.ShortProduct)" Name="InstalledStartMenuShortcuts" Type="integer" Value="1" />
</Component>
</DirectoryRef>
<DirectoryRef Id="INSTALLLOCATION" FileSource="Files">
<Component Id="WixShortCut" Guid="{YOUR_GUID}">
<File Id="Test.ShortCut" Vital="yes" Name="A_DOC.pdf" />
<CreateFolder />
<RegistryKey Root="HKCU" Key="Software\!(wix.Manufacturer)\!(wix.ShortProduct)" Action="createAndRemoveOnUninstall">
<RegistryValue Name="ShortCut" Value="1" Type="integer" KeyPath="yes"/>
</RegistryKey>
<!-- Shortcut in Start menu. -->
<Shortcut Id="ProgramMenuApplicationShortcut" Name="!(wix.ShortProduct)" Target="[#Test.ShortCut]"
Directory="ProgramMenuManufacturer" Show="normal" Icon="ShortCutIcon"/>
</Component>
</DirectoryRef>
<Feature Id="ProductFeature" Title="WixShortCuts" Level="1">
<ComponentRef Id="ProductComponent"/>
<ComponentRef Id="ProgramMenuShortcuts"/>
<ComponentRef Id="WixShortCut"/>
</Feature>
In Windows Installer you need to create a new directory under ProgramMenuFolder and then reference it.
<Directory Id="ProgramMenuFolder" >
<Directory Id="ProgramMenuDir" Name='My Folder'>
</Directory>
</Directory>
<Shortcut Id="startmenuSample" Directory="ProgramMenuFolder" Name="Sample 0.5"
WorkingDirectory='INSTALLDIR' Icon="Sample.exe" IconIndex="0" Advertise="yes">