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.
Related
I created a wix installer using heat cmd.
On uninstall all files are removed but not all folders are removed.
this the relevant part of my code:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.PlatformProgramFilesFolder)">
<Directory Id="companyDir" Name="companyName">
<Directory Id="INSTALLFOLDER" Name="AppName">
<Directory Id="INSTALLDIR" >
<Directory Id="bin" Name="bin">
<!-- Auto-start via Registry -->
<Component Id="AppNameAutoStartUp" Guid="MYGUID">
<Condition>AUTOMATIC_START_UP=1 OR Installed</Condition>
<RegistryValue Id="App.rst" Root="HKCU" Action="write" Key="Software\Microsoft\Windows\CurrentVersion\Run" Name="AppName" Value="[#AppName.exe] -sc" Type="string" />
</Component>
</Directory>
<Directory Id="docs" Name="Docs">
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
<Directory Id="CommonAppDataFolder">
<Directory Id="ConfCompanyDir" Name="Company">
<Directory Id="CONFINSTALLFOLDER" Name="AppName">
<Directory Id="CONFINSTALLDIR" >
<Directory Id="conf" Name="conf">
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
<!-- Shortcuts and Directories for Shortcuts -->
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="AppName">
<Component Id="ProgramFilesShortcut" Guid="MYGUID">
<Condition>DESKTOP_SHORTCUT = 1</Condition>
<Shortcut Id="desktopAppName" Directory="DesktopFolder" Name="AppName" Target="[#AppName.exe]" WorkingDirectory="bin" Icon="AppIcon.ico">
</Shortcut>
<RemoveFolder Id="ProgramFilesShortcut" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
<Component Id="ProgramMenuDir" Guid="MYGUID">
<Shortcut Id="startmenuAppName" Directory="ProgramMenuFolder" Name="AppName" Target="[#AppName.exe]" Icon="AppIcon.ico" WorkingDirectory="bin" Arguments="-s">
<!-- Set the AppID in order to get toasts to work -->
<ShortcutProperty Key="System.AppUserModel.ID" Value="Company.AppName" />
</Shortcut>
<RemoveFolder Id="ProgramMenuDir" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
The Docs folder is removed on uninstall but the bin folder is not removed (although it is empty, all the files are removed).
Does anyone have any idea why it is not removed?
I added code like this to your Feature element:
<Component Directory='INSTALLDIR'>
<RemoveFolder Id='CleanupApplicationFolder' On='uninstall' />
</Component>
So you should change INSTALLDIR to main folder (and it should uninstall all).
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"/>
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.
I am getting the error
"The directory TestDir is in the user profile but is not in the RemoveFile table"
Basically I want my app to install into the local Common "All Users" folder instead of the Program Files folder.
so I have my directory structure as
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="CommonAppDataFolder">
</Directory>
<Directory Id="SystemFolder"/>
<Directory Id="StartupFolder"/>
<Directory Id="DesktopFolder"/>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuVendorFolder" Name="Orion Integration">
</Directory>
</Directory>
<Directory Id="LocalAppDataFolder">
<Directory Id="ORIONDIR" Name="Orion Integration">
<Directory Id="INSTALLDIR" Name="TestApp">
<Directory Id="TestDir" Name="Test">
<Component Id="BUILDINGFLOORMODELSDIR_C" Guid="A6BD61D8-FAC8-4D7D-881E-58CC2C4F9753"
SharedDllRefCount="no" KeyPath="no" NeverOverwrite="no" Permanent="no" Transitive="no"
Location="either">
<RegistryValue
Root="HKCU"
Key="Software\Orion Integration\Orion CMS"
Name="InstalledBuildingFloorModels"
Type="integer"
Value="1" />
<CreateFolder/>
<RemoveFolder Id="BUILDINGFLOORMODELSDIR" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
...........
I have placed RemoveFIle in the compnent section and still getting errors
You need to specify a directory using the <RemoveFolder /> element.
Instead of
<RemoveFolder Id="BUILDINGFLOORMODELSDIR" On="uninstall"/>
try
<RemoveFolder Id="TestDir" On="uninstall"/>
I'm having trouble setting the working directory of a shortcut created as part of a WiX script. Here are the basics:
<!-- create a start menu shortcut. -->
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="My Name">
<Component Id="ApplicationShortcut" Guid="822A26AF-5231-4EDA-A18D-5DF15020BD94">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="My Name"
Description="My Description"
Target="[INSTALLLOCATION]My.exe"
WorkingDirectory="INSTALLLOCATION" />
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
<!-- Install the app. -->
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="My Name">
<Component Id="ProductComponent" Guid="4740357A-69D3-4626-A0F7-D0667C93A2CE">
<File Id="My.exe" Name="My.exe" Source="My.exe" />
</Component>
</Directory>
</Directory>
This jives with examples I've seen, and the shortcut gets created, and it points to the right exe, but the shortcut has no working directory specified, and so the app doesn't find its local resources.
You don't need to say [INSTALLLOCATION] because the ShortCut table defines the WkDir column describes "The name of the property that has the path of the working directory for the shortcut."
I would reccomend trying this:
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="My Name">
</Directory>
</Directory>
<!-- Install the app. -->
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="My Name">
<Component Id="ProductComponent" Guid="4740357A-69D3-4626-A0F7-D0667C93A2CE">
<File Id="My.exe" Name="My.exe" Source="My.exe" />
<Shortcut Id="ApplicationStartMenuShortcut"
Advertise="yes"
Name="My Name"
Description="My Description"
Directory="ApplicationProgramsFolder"
WorkingDirectory="INSTALLLOCATION">
<Icon Id="My.exe" SourceFile="My.exe" />
<Shortcut>
</Component>
</Directory>
</Directory>
I think you need square brackets around your INSTALLLOCATION in the working directory attribute.