I have my bootstrapper project and I need to add a shortcut only when another third part msi is selected on bootstrapper's UI. So I end up with another little msi like this (removing not relevant data):
<Wix >
<Product >
<Package />
<MajorUpgrade />
<MediaTemplate />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="FolderName">
</Directory>
</Directory>
</Directory>
<Component Id="ApplicationShortcut" Guid="PUT-GUID-HERE" Directory="ApplicationProgramsFolder">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="App"
Description="desc"
Target='"[ProgramFiles64Folder]Folder1\Folder2\app.exe"'
Arguments=' -n name'
/>
<RemoveFolder Id="RemoveProgramMenuDir" Directory="ApplicationProgramsFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\ACME\App" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Feature Id="ProductFeature" Title="Shortcuts" Level="1">
<ComponentRef Id="ApplicationShortcut" />
</Feature>
</Product>
But I get
ICE71: The Media table has no entries.
That source doesn't compile anyway because of issues with missing languages, productcodes and so on. It would have helped if you'd posted a complete working example. After fixing those issues and seeing ICE71, you basically need to delete mediatemplate and add a proper media entry such as (in angle brackets)
Media Id="1" Cabinet="product.cab" EmbedCab="yes"
then all you get is warning LGHT1079 : The cabinet 'product.cab' does not contain any files. If this installation contains no files, this warning can likely be safely ignored. Otherwise, please add files to the cabinet or remove it.
I would just augment the third party MSI with a transform that creates a shortcut when that MSI is installed. This way you don't have to do anything special in the bootstrapper.
Related
I've got two different products (A, B) that install via custom wix installers. For some reason when A is installed and I try to install B, A is uninstalled as part of B installation and vice versa when B is installed, A uninstalls B.
I have very similar WIX files but each one has a different Product UpgradeCode. I've done a bit of searching and it seems everyone has the opposite problem where the upgrade is not uninstalling their product.
Any ideas about what else has to be changed would be much appreciated as I've been banging my head against the wall for hours.
This is one of my wix files. The main difference between this and the other is different cookiecutter variables (guid and formal_name) and "<-- CONTENT -->, <-- CONTENTREFS -->" contents section. Both applications do install to different locations.
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product
Id="*"
UpgradeCode="{{ cookiecutter.guid }}"
Name="{{ cookiecutter.formal_name }}"
Version="0.1.1"
Manufacturer="{{ cookiecutter.organization_name }}"
Language="1033">
<Package
InstallerVersion="200"
Compressed="yes"
Comments="Windows Installer Package"
/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Property Id="ARPHELPLINK" Value="https://www.myhome.com" />
<Property Id="ARPURLINFOABOUT" Value="Home Page" />
<Property Id="ARPNOREPAIR" Value="1" />
<Property Id="ARPNOMODIFY" Value="1" />
<MajorUpgrade AllowDowngrades="yes"
AllowSameVersionUpgrades="no"
IgnoreRemoveFailure="no"
Schedule="afterInstallInitialize" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="AppDir" Name="{{ cookiecutter.formal_name }}">
<!-- CONTENT -->
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="{{ cookiecutter.formal_name }}"/>
<Directory Id="DesktopFolder" Name="{{ cookiecutter.formal_name }}DesktopFolder"/>
</Directory>
</Directory>
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcutStartMenu" Guid="*">
<Shortcut Id="ApplicationShortcut1" Name="{{ cookiecutter.formal_name }}" Description="{{ cookiecutter.description }}" Target="[DIR_python]\python.exe" WorkingDirectory="AppDir" Arguments="app\start.py" />
<RegistryValue Root="HKCU" Key="Software\{{ cookiecutter.organization_name }}\{{ cookiecutter.formal_name }}" Name="installed" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="CleanUpShortCut1" Directory="ApplicationProgramsFolder" On="uninstall"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationShortcut2" Name="{{ cookiecutter.formal_name }}" Description="{{ cookiecutter.description }}" Target="[DIR_python]\python.exe" WorkingDirectory="AppDir" Arguments="app\start.py" />
<RegistryValue Root="HKCU" Key="Software\{{ cookiecutter.organization_name }}\{{ cookiecutter.formal_name }}DesktopFolder" Name="installed" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="CleanUpShortCut2" Directory="DesktopFolder" On="uninstall"/>
</Component>
</DirectoryRef>
<Feature Id="DefaultFeature" Level="1">
<!-- CONTENTREFS -->
<ComponentRef Id="ApplicationShortcutStartMenu"/>
<ComponentRef Id="ApplicationShortcutDesktop"/>
</Feature>
<Property Id="ALLUSERS" Value="1"></Property>
</Product>
Upgrade Code: This behavior is consistent with identical upgrade code, please verify if this is the case by using one of the approach shown here to list all upgrade codes for installed setups: How can I find the Upgrade Code for an installed MSI file?
MSI File Hard Facts: Alternatively - or preferably - check the Upgrade table of the actual MSI files involved whether they are installed or not.
Custom Action: I suppose it is also possible that there is a custom action in your installer which uninstalls the other product as a custom action step inserted somewhere in the installation sequences (only a few locations will work). Please inspect your MSI using Orca or some other MSI tool to determine what is in the tables: Custom Action and Upgrade. Please report any suspects.
Launcher: The MSI in question is not launched from a setup.exe is it? Or from a batch file or some automated system for deployment?
Update: Maybe have a look at this answer from yesterday. At least somewhat related: How to avoid having two versions of a product installed with Windows Installer / MSI?
This question is asking whether one of the ICE57 validators creates a false positive error report.
I am using WIX 3.9 to generate an installer. I want a per machine installation with non advertised shortcuts.
This WXS example installs a text file and a shortcut to open the text file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="ShortcutTest" Language="1033"
Version="1.0.0.0" Manufacturer="Widget Co"
UpgradeCode="--YOUR GUID1--">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="ProductFeature" Title="ShortcutTest" Level="1">
<ComponentRef Id="TextFile" />
<ComponentRef Id="ShortCut" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="ShortcutTest">
<Component Id="TextFile" Guid="--YOUR GUID2--">
<File Id="File" Name="TextFile.txt" Source="TextFile.txt" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="Shortcut Test">
<Component Id="ShortCut" Guid="--YOUR GUID3--">
<RegistryValue Root="HKMU" Key="Software\WidgetCo\ReadMeTextFile\TextFile" Name="Installed" Type="string" Value="yes" KeyPath="yes"/>
<Shortcut Id="Shortcut"
Name="Open Text File"
Description="Opens a text file"
Target="[INSTALLFOLDER]TextFile.txt"
WorkingDirectory="INSTALLFOLDER"/>
<RemoveFolder Id="ApplicationProgramsFolder" Directory="ApplicationProgramsFolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
If you build the above example into an MSI package, you get this Internal Consistency Evaluator (ICE) error:
D:\Robert\Documents\Visual Studio 2013\Projects\ShortcutTest\Product.wxs(27,0): error LGHT0204: ICE57: Component 'ShortCut' has both per-user data and a keypath that can be either per-user or per-machine.
ICE57 is implying an inconsistency between per-user and per-machine data. But, the key path of the component is HKMU, which in a per machine installation resolves to HKLM (HKEY_LOCAL_MACHINE). The location of the shortcut derives from 'ProgramMenuFolder', which in a per-machine installation resolves to C:\ProgramData\Microsoft\Windows\Start Menu\ (on Windows 8.1). None of the component's resources appear to have any per-user association.
You can build the installer package into an MSI by suppressing ICE57. The resulting MSI package installs without any obvious errors. Multiple users can log on and access the shortcut. Any user can un-install the package and all of the resources in the package are removed.
The answer to Wix create non advertised shortcut for all users / per machine has an interesting workaround, which is to author advertised shortcuts and then turn off advertising. Seems a round about way of creating un-advertised shortcuts.
A common fix for the ICE57 error is to change the <RegistryValue...> root to HKCU (HKEY_CURRENT_USER). However this creates an installer that can leave a user registry key behind when un-installed. For example if user A installs the package, a registry entry is added to user A's registry hive. If user B removes the package, the registry entry is not removed from user A's registry hive.
In this scenario is the ICE57 error a bug in the Internal Consistency Evaluators? Or is there something I have miss-understood?
While researching another problem I found this comment on http://sourceforge.net/p/wix/mailman/message/26687047/ from Rob Mensching:
IIRC, this is a bug in ICE57. The Windows Installer team didn't look at
ALLUSERS property when evaluating these values... that was a long time ago
though so my memory may have decayed a bit.
It looks like a bug in ICE57.
Move your Shortcut to the be a child of File and add the Adversite="yes" attribute. The RegistryValue should do the trick for converting the shortcut from perUser to perMachine.
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MyApp" />
</Directory>
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ApplicationProgramsFolder" Name="My App Name" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ComponentGroup_Core">
<Component Id="Component_App" Guid="INSERT_GUID_HERE" Directory="INSTALLFOLDER">
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[AppName]"
Name="AppInstalled" Type="string" Value="yes" KeyPath="yes"/>
<File Id="MyApp" Name="My Test App.txt">
<Shortcut Id="Shortcut"
Name="Open Text File"
Description="Opens a text file"
Directory="ApplicationProgramsFolder"
WorkingDirectory="INSTALLFOLDER" />
</File>
</Component>
<Component Id="Component_MenuFolder" Guid="INSERT_GUID_HERE"
Directory="ApplicationProgramsFolder">
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[AppName]"
Name="MenuFolderInstalled" Type="string" Value="yes"
KeyPath="yes"/>
<RemoveFolder Id="RemoveFolder_App" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
I have a WiX installation that also needs to write some registry keys, and I was wondering if there's a way to tell WiX/MSI to
only create a key if it doesn't exist yet
always create/overwrite another key, even if it exists
I tried something like this:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="TestRegistry" Language="1033" Version="1.0.2"
Manufacturer="Myself" UpgradeCode="PUT-GUID-HERE">
<Package InstallerVersion="200" Compressed="yes"
InstallScope="perUser" InstallPrivileges="limited" />
<MajorUpgrade DowngradeErrorMessage="A newer version installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="TestRegistry" Level="1">
<ComponentRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="dirManufacturer" Name="Manufacturer">
<Directory Id="INSTALLFOLDER" Name="TheProduct">
<Component Id="ProductComponents" Guid="*" DiskId="1">
<RegistryKey Root="HKCU" Key="Software\Manufacturer\TheProduct"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="Install Directory"
Value="[INSTALLFOLDER]" KeyPath="yes" />
<RegistryValue Type="string" Name="Product Version"
Value="[ProductVersion]" />
<RegistryValue Type="string" Name="Default Language" Value="en" />
<RegistryValue Type="string" Name="Web Site URL"
Value="https://product.manufacturer.info/" />
</RegistryKey>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>
and here, I'd like to always overwrite the Install Directory and Product Version keys with current values, but I would like to preserve other settings, like Default Language.
Is there any way to do this?
Right now, when I install 1.0.0 fresh on a new system, it creates the registry keys alright. When I uninstall it, they're gone - so far, so good.
But when I installed v1.0.1 and then - without uninstalling v1.0.1 - installed v1.0.2 on top of this, ALL the defined registry keys were updated and contained the default values defined in the WiX script - the changes I had made manually were wiped out.
You will need to break the registry values out to there own components and set the NeverOverwrite attribute on them
<Component Id="DefaultLangaugeComponent" Guid="*" NeverOverwrite="yes">
<RegistryKey Root="HKCU" Key="Software\Manufacturer\TheProduct"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="Default Language" Value="en" />
</RegistryKey>
</Component>
I am trying to configure an inherited WiX installer for use with my software.
The software logs to day-specific files in C:\SomePath\LogFiles like 2014-05-19.txt, 2014-05-18.txt, and so on (not really relevant to question, but perhaps worth noting that there will be files present that are created by the software, but not by the installer itself).
My WiX installer creates the LogFiles directory like this (lots of elements, GUIDs etc removed for readability):
<Wix>
<Product Id="SOME_GUID" Version="SOME_VERSION" UpgradeCode="OTHER_GUID">
<Feature Id="EMPTY_DIRECTORIES" Title="Empty Directories" Level="1" Display="hidden">
<ComponentRef Id="SomeFolder" />
<ComponentRef Id="LogFiles" />
<ComponentRef Id="SomeOtherFolder" />
</Feature>
<DirectoryRef Id="DIR_LOG_FILES">
<Component Guid="" Id="DELETE_DIR_LOG_FILES">
<RemoveFile Id="DELETE_DIR_LOG_FILES_FILES" Name="*.*" On="uninstall" />
<RemoveFolder Id="DELETE_DIR_LOG_FILES" On="uninstall" />
</Component>
</DirectoryRef>
</Product>
<Fragment>
<Directory Name="SoftwareName" Id="SOFTWARENAME">
<Directory Id="DIR_LOG_FILES" Name="LogFiles">
<Component Id="LogFiles" KeyPath="no" NeverOverwrite="no" Permanent="no" Win64="no" Location="local">
<CreateFolder>
<util:PermissionEx CreateChild="yes" CreateFile="yes" Delete="yes" Read="yes" ReadAttributes="yes" ReadExtendedAttributes="yes" ReadPermission="yes" Traverse="yes" GenericRead="yes" GenericWrite="yes" User="Everyone" />
</CreateFolder>
</Component>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="LoggingComponents" Directory="WHERE_THE_LOGGING_DLLS_LIVE">
<ComponentRef Id="DELETE_DIR_LOG_FILES" />
</ComponentGroup>
</Fragment>
</Wix>
I had hoped that this setup would cause the directory and contents to be deleted only on uninstall. Unfortunately the deletion seems to trigger on upgrade as well. Is there a way to configure WiX to tell the difference and react appropriately?
In your build process do you update the version of the dll's you want to produce as that should overwrite it. Do you have any remove file/folder tags as they could also cause an issue.
After installation of perUser msi package I cannot uninstall it.
When selecting (Browse) package - that I installed - there is an error: 'selected package is not valid package for this product'.
Here's my code:
<?xml version='1.0'?><Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Id='a871a539-5954-44b7-810d-caed5d09e4c5' Name='x' Language='1033'
Version='1.1.0.0' Manufacturer='M' UpgradeCode='a871a539-5954-44b7-810d-caed5d09e4c5'>
<Package Description='x'
Comments='x'
Manufacturer='x' InstallerVersion='200' Compressed='yes' InstallScope='perUser' />
<Media Id='1' Cabinet='product.cab' EmbedCab='yes' />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='AppDataFolder' Name='AppData'>
<Directory Id='xFolder' Name='x' />
</Directory>
</Directory>
<Component Id='xComponent' Guid='a871a539-5954-44b7-810d-caed5d09e4c5'
Directory='xFolder'>
<RemoveFolder Id="Removex" On="uninstall" />
<!-- registry entry to be used as keypath -->
<RegistryValue Root="HKCU"
Key="Software\M\x"
Name="component.xcomponent.installed"
Type="integer"
Value="1"
KeyPath="yes"/>
<File Id='myFile' Name='myFile.txt' DiskId='1' Source='myFile.txt' />
... files here
</Component>
<Feature Id='xFeature' Title='x feature' Level='1'>
<ComponentRef Id='xComponent' />
</Feature>
Installation process is ok - no errors. Files are in correct place. Registry key is added.
What am I doing wrong?
Yes - as Wim Coenen said - that question helped me resolve problem.
However instead of executing steps in that question I cleaned registry.
The problem was that I installed this package many times changing GUID and other parameters, so there was quite a mess in registry. I searched registry by Manufacturer and Name.
After cleaning up everything was ok.