wix installer platform dependency issues - wix

I am trying to create one installer (one MSI file) for both x86 and x64. I would like the installation process to install only relevant files based on the target machine platform.
Till now I had one only MSI for x86 and it worked as expected.
Now I added this section:
<!-- Details to support both x86 and x64 platforms-->
<?if $(var.Platform) = x64 ?>
<?define ProductName = "MyApp (64 bit)" ?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define ExportReleaseComponentGroup = "Export64ReleaseComponentGroup" ?>
<?define MyApplication = "$(var.x64SourcePath)\MyApp.exe" ?>
<?else ?>
<?define ProductName = "MyApp" ?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define ExportReleaseComponentGroup = "Export32ReleaseComponentGroup" ?>
<?define MyApplication = "$(var.win32SourcePath)\MyApp.exe" ?>
<?endif ?>
Now I get some errors:
In a x64 machine it is installed under Program Files (x86) folder. I am compiling the SetupProject in x86, can it be the reason for that? relevant code:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.PlatformProgramFilesFolder)">
The application does not run when installation ends. relevant code:
<!--CA to launch the exe after install-->
<Property Id="WixShellExecTarget" Value="$(var.MyApplication)" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
A desktop shortcut and a start menu shortcut is not created. relevant code:
<Component Id="ProgramFilesShortcut" Guid="{My-Guid}">
<Condition>MY_DESKTOP_SHORTCUT</Condition>
<Shortcut Id="desktopMyApp" Directory="DesktopFolder" Name="MyApp" Target="$(var.MyApplication)" WorkingDirectory="bin" Icon="MyIcon.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="{My-Guid}">
<Shortcut Id="startmenuMyApp" Directory="ProgramMenuFolder" Name="MyApp" Target="$(var.MyApplication)" Icon="MyIcon.ico" WorkingDirectory="bin" Arguments="-s">
<!-- Set the AppID in order to get toasts to work -->
<ShortcutProperty Key="System.AppUserModel.ID" Value="MyCompany.MyApp" />
</Shortcut>
<RemoveFolder Id="ProgramMenuDir" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
Any idea what am I doing wrong?

You are using compile-time variables so you are producing an MSI for either a 32-bit or a 64-bit installations. An MSI package must target either one or the other. In some cases, it doesn't matter but the design is to get components that do matter in the right place.
It could be possible to share the source between separate 32-bit and 64-bit builds.
Once you have the two MSI, you can use a WiX Bootstrapper project to bundle them and install the appropriate one on the target system.

Related

wix 3 installer: Unresolved bind-time variable !(bind.fileVersion.Name.exe)

I'm trying to use the binding "bind.fileVersion" from Wix3. (ie: 3.11.1)
For some me reason, I get the following error message:
Unresolved bind-time variable !(bind.fileVersion.TestWix3.exe).
My goal is to fill the 'Product Id' line. Especially the Version="$(var.VERSION)" information.
Here's the content of my "Product.wxs" file:
<?xml version="1.0" encoding="UTF-8"?>
<?define LongName = "Test wix 3" ?>
<?define Manufacturer = "Test" ?>
<?define ProductUpgradeCode = "5fc3e435-fad3-4c1d-997f-3483beffe0a4" ?>
<?define MAINEXE=$(var.TestWix3.TargetFileName)?>
<?define VERSION="!(bind.fileVersion.$(var.MAINEXE))"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="$(var.LongName)" Language="1036" Codepage="1252" Version="$(var.VERSION)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.ProductUpgradeCode)">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="Wix3Installer" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Wix3Installer" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
</ComponentGroup>
</Fragment>
</Wix>
Here is the screenshot of my solution in VS2017 Community.
Here is the error:
Any idea why the binding of (bind.fileVersion) does not work ?
The FileId part of the bind variable is representing the <File Id="..."> Id. ie:
!(bind.fileVersion.TestWix3.exe)
...
<Component Id="MainProduct">
<File Id="TestWix3.exe" KeyPath="yes" Source="$(var.TestWix3.TargetPath)"/>
... other stuff maybe ...
</Component>
Currently your component and file definitions are TODO so you can't use this type of bind variable yet.
The syntax is !(bind.fileVersion.FileId) -- note the lowercase f.
Your define ?define MAINEXE=$(var.TestWix3.TargetFileName)?
translates to:
create a variable with Name MAINEXE and set it to the value of another variable.
There is no variable defined TestWix3.TargetFileName
Your second define created a variable with Name VERSION and uses the undefined MAINEXE
using the defines like this instead
?define MAINEXE=sample.exe?
?define VERSION="!(bind.fileVersion.$(var.MAINEXE))"?
compiles no problem
I ommitted the <&lt >&gt before and after ?
In our case (C++ program), this bind.FileVersion error message apparently was fixed by adding Win32 rc VERSIONINFO resources that were actually missing in the relevant library project (I'd think that WiX requires proper version declaration of a binary to e.g. make its installation/upgrade decisions etc.).

get "FileVersion" from a file that will not be installed

A well known trick to get a variable based on a file file version is
<?define ProductVersion = !(bind.FileVersion.filProductVersion) ?>
where
<Fragment>
<ComponentGroup Id="MyCG">
<Component Id="cmpabc" Directory="INSTALLDIR" Guid="YOUR-GUID-HERE">
<File Id="filProductVersion" KeyPath="yes" Source="$(var.MyRootFolder)\fileIAmGoingToInstall.dll" />
</Component>
Is there anyway to set a variable based on the file version of a file I do NOT want to install?
I've tried this:
MyWxs.wxs
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Binary Id="binaryProductVersionId" SourceFile="$(var.MyRootFolder)\FileIDoNotWantToInstall.dll" />
</Fragment>
</Wix>
MyWxi.wxi
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define ProductVersion = !(bind.FileVersion.binaryProductVersionId) ?>
</Include>
But I get:
Severity Code Description Project File Line Suppression State
Error Unresolved bind-time variable !(bind.FileVersion.binaryProductVersionId).
You can try to place a condition inside the component that always be false.
<Component Id="cmpabc" Directory="INSTALLDIR" Guid="YOUR-GUID-HERE">
<File Id="filProductVersion" KeyPath="yes" Source="$(var.MyRootFolder)\fileIAmGoingToInstall.dll" />
<Condition>IGNORE = "0"</Condition>
</Component>
where IGNORE can be a property or use variable $(var.IGNORE)

Wix installer does not overwrite previous version of an executable

I have a very simple installer - copy a single dll to a Program Files subfolder and register it with regsvr32.exe. Works great, but if an older version of the dll is installed, "Repair" does not overwrite the existing dll. The dll is signed and its version (build) number is always incremented (e.g. 2.0.0.123 - > 2.0.0.124).
Looking at the previous similar posts, I added RemoveExistingProducts and specified ProductId as "*". Uninstalling and then installing the newer version works fine, but I really need Repair to update the existing dll.
Is there anything else I need to do?
Thank you!
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!--
When creating a new install for the next version, these fields must be modified
-->
<?define ProductVersion = "2.0.00" ?>
<?define ProductId64 = "*" ?>
<?define ProductId32 = "*" ?>
<?define PackageId = "45F34788-66AC-441C-B666-707FFA7F1EE9" ?>
<!-- Product name as you want it to appear in Add/Remove Programs-->
<?if $(var.Platform) = x64 ?>
<?define ProductName = "XYZ (64 bit)" ?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define ProductId = "$(var.ProductId64)" ?>
<?define MainDllName = "XYZ64.dll" ?>
<?define MainDllSource = "..\..\bin\Win64\Release\XYZ64.dll" ?>
<?else ?>
<?define ProductName = "XYZ (32 bit)" ?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define ProductId = "$(var.ProductId32)" ?>
<?define MainDllName = "XYZ.dll" ?>
<?define MainDllSource = "..\..\bin\Win32\Release\XYZ.dll" ?>
<?endif ?>
<?define UpgradeCode = "{C3763742-7C1C-4AB7-A404-F030B7550E97}" ?>
<Product Id="$(var.ProductId)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="Advanced Messaging Systems LLC" UpgradeCode="$(var.UpgradeCode)">
<Package Id="$(var.PackageId)" InstallerVersion="200" Compressed="yes" Description="XYZ Installer package" InstallPrivileges="elevated"/>
<!-- No restore point -->
<Property Id="MSIFASTINSTALL" Value="3" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.PlatformProgramFilesFolder)">
<Directory Id="INSTALLLOCATION" Name="XYZ">
<Component Id="XYZDll" Guid="E2CBEE41-6C0E-4A84-95C1-7282747B4A3D">
<File Id='MainDll' Name="$(var.MainDllName)" DiskId='1' Source="$(var.MainDllSource)" SelfRegCost="0" />
<!-- TODO: Insert files, registry keys, and other resources here. -->
</Component>
</Directory>
</Directory>
</Directory>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
<!-- Note: Custom actions to install/uninstall the dll using regsvr32.exe -->
<CustomAction Id="RegisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s "[INSTALLLOCATION]$(var.MainDllName)"'
Return="check">
</CustomAction>
<CustomAction Id="UnregisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s /u "[INSTALLLOCATION]$(var.MainDllName)"'>
</CustomAction>
<Feature Id="ProductFeature" Title="XYZ" Level="1">
<ComponentRef Id="XYZDll" />
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="Product.Generated" />
</Feature>
<InstallUISequence>
<Custom Action="WixCloseApplications" Before="AppSearch"/>
</InstallUISequence>
<InstallExecuteSequence>
<!-- Uninstall previous version before installing this one. -->
<RemoveExistingProducts Before="InstallInitialize"/>
<SelfRegModules/>
</InstallExecuteSequence>
<Icon Id="XYZ.ico" SourceFile="..\Graphics\XYZ.ico"/>
<Property Id="ARPPRODUCTICON" Value="XYZ.ico" />
<!-- UI -->
<UIRef Id="WixUI_InstallDir"/>
<UIRef Id="WixUI_ErrorProgressText" />
<WixVariable Id="WixUILicenseRtf" Value="..\EULA\license.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="..\Graphics\banner.jpg" />
<WixVariable Id="WixUIDialogBmp" Value="..\Graphics\logo.jpg" />
<!-- End UI -->
</Product>
</Wix>
UPDATE. The following worked for me after modifying the upgrade entries:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!--
When creating a new install for the next version, these fields must be modified
-->
<?define ProductVersion = "2.0.4" ?>
<?define ProductId64 = "*" ?>
<?define ProductId32 = "*" ?>
<?define PackageId = "*" ?>
<!-- Product name as you want it to appear in Add/Remove Programs-->
<?if $(var.Platform) = x64 ?>
<?define ProductName = "XYZ (64 bit)" ?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define ProductId = "$(var.ProductId64)" ?>
<?define MainDllName = "XYZ64.dll" ?>
<?define MainDllSource = "..\..\bin\Win64\Release\XYZ64.dll" ?>
<?else ?>
<?define ProductName = "XYZ (32 bit)" ?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?define ProductId = "$(var.ProductId32)" ?>
<?define MainDllName = "XYZ.dll" ?>
<?define MainDllSource = "..\..\bin\Win32\Release\XYZ.dll" ?>
<?endif ?>
<?define UpgradeCode = "{C3763742-7C1C-4AB7-A404-F030B7550E97}" ?>
<Product
Id="$(var.ProductId)"
Name="$(var.ProductName)"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="Advanced Messaging Systems LLC"
UpgradeCode="$(var.UpgradeCode)"
>
<Package Id="$(var.PackageId)"
InstallerVersion="200"
Compressed="yes"
Description="XYZ Installer package"
InstallPrivileges="elevated"
/>
<!-- No restore point -->
<Property Id="MSIFASTINSTALL" Value="3" />
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="1.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="$(var.ProductVersion)"
IncludeMaximum="no"
Property="PREVIOUSFOUND" />
</Upgrade>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.PlatformProgramFilesFolder)">
<Directory Id="INSTALLLOCATION" Name="XYZ">
<Component Id="XYZDll" Guid="E2CBEE41-6C0E-4A84-95C1-7282747B4A3D">
<File Id='MainDll' Name="$(var.MainDllName)" DiskId='1' Source="$(var.MainDllSource)" SelfRegCost="0" />
<!-- TODO: Insert files, registry keys, and other resources here. -->
</Component>
</Directory>
</Directory>
</Directory>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
<!-- Note: Custom actions to install/uninstall the dll using regsvr32.exe -->
<CustomAction Id="RegisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s "[INSTALLLOCATION]$(var.MainDllName)"'
Return="check">
</CustomAction>
<CustomAction Id="UnregisterDll"
Directory="INSTALLLOCATION"
ExeCommand='regsvr32.exe /s /u "[INSTALLLOCATION]$(var.MainDllName)"'>
</CustomAction>
<Feature Id="ProductFeature" Title="XYZ" Level="1">
<ComponentRef Id="XYZDll" />
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="Product.Generated" />
</Feature>
<InstallUISequence>
<Custom Action="WixCloseApplications" Before="AppSearch"/>
</InstallUISequence>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
<SelfRegModules/>
</InstallExecuteSequence>
<Icon Id="XYZ.ico" SourceFile="..\Graphics\XYZ.ico"/>
<Property Id="ARPPRODUCTICON" Value="XYZ.ico" />
<!-- UI -->
<UIRef Id="WixUI_InstallDir"/>
<UIRef Id="WixUI_ErrorProgressText" />
<WixVariable Id="WixUILicenseRtf" Value="..\EULA\license.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="..\Graphics\banner.jpg" />
<WixVariable Id="WixUIDialogBmp" Value="..\Graphics\logo.jpg" />
<!-- End UI -->
</Product>
</Wix>
If you want a major uprade, start with the WiX MajorUpgrade element. The general rules for an upgrade are:
Different ProductCode and PackageCode from older product.
Increment ProductVersion somewhere in the first three fields.
Same UpgradeCode as older product.
Do something (like Wix MajorUprade or Upgrade elements) to ensure that you have an upgrade in place.
A per user install will not upgrade a per system install, or vice versa.
In your original case, failure to follow rules 1 and 2 meant that Windows thought the same product was already installed and went into Repair mode. That should have been your first warning because a major upgrade looks like a fresh install, not a repair. If you have two entries in Programs&Features it means that one or more of those 4 requirements has not been met. If you get "Another version of this product is already installed" it means you didn't follow rule 1, and variations in behavior are about ProductCode and PackageCode values compared with the installed product.
I am surprised that this line actually is allowed by the Wix compiler and linker:
<?define PackageId = "45F34788-66AC-441C-B666-707FFA7F1EE9" ?>
If this actually works and goes through, which I haven't tested, it means your package has a hard coded package id. I thought Wix featured protection against this problem? Perhaps it does? We should check with the Wix community if it ever makes any sense to allow hard coded package guid. I suppose it could be necessary for debugging and testing purposes - but there should at least be a compiler warning.
The idea of a package GUID is that it should be unique for each compiled MSI file. It is simply there to uniquely identify a file. Two different MSI files with the same package guid will be treated by Windows Installer as the same file by definition. All kinds of x-files problems result. Accordingly a package GUID should always be auto-generated since it is simply supposed to be unique. Please try to resolve this problem first to check if this solves your overall problem. Set it equal to *.
My advice is to auto-generate package id and product id but to set a hard coded upgrade code. An upgrade code identifies a "family of products" and is useful for identifying any instance of your product regardless of language and version. It might be useful to use a separate upgrade code for your 64 vs 32 bit setups since both versions can be installed at the same time on some systems.
You might also want to eliminate the use of regsvr32.exe for self-registration and extract COM data from your dll for proper MSI support: MSI register dll - Self-Registration considered harmful. And perhaps also check this: Register ActiveX exe server using WiX (check out RegSpy2 if Heat doesn't work).
Also note that you can leave out a lot of source attributes from your Wix xml file and rely on Wix defaults instead of hard coding values.
Some further details on GUIDs and file replacement:
Change my component GUID in wix?
MSI Reference Counting: Two products install the same MSIs
Forcing an upgrade of a file that is modified during its initial installation
msi version numbers
File Versioning Rules
Replacing existing files (diagram, both files have version)
Plain English file versioning description by Aaron Stebner
Short answer (the other one became too messy): try removing this line and let the package ID be auto generated by setting it to "*":
<?define PackageId = "45F34788-66AC-441C-B666-707FFA7F1EE9" ?>
Note that you must stop using all previous MSI builds after uninstalling them all. This is due to the faulty hard coded package guid which can cause unpredictable and unforeseen problems.

Wix: Write register entries under HKCU\Software\Classes\Wow6432Node

I have a super simple installer to test if a installer can write register entries under HKCU\Software\Classes\Wow6432Node (the msi is target x86 and I'm testing it on a Win7 x64 machine).
The problem is: it just does not want to write anything under Wow6432Node at all. Following is the code:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="f671ee4d-dd0a-4f7f-a4d1-1d181d2f3002" Name="TestWow" Language="1033" Version="1.0.0.0" Manufacturer="X" UpgradeCode="5d030587-0b6f-4a55-b090-c97a4fd22d13">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perUser" InstallPrivileges="limited"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="XWix" Level="1">
<ComponentRef Id="TestWow" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir" />
</Fragment>
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Component Id="TestWow" Guid="f671ee4d-dd0a-4f7f-a4d1-1d181d2f3002">
**<RegistryKey Root="HKCU" Key="Software\Classes\TestWow">
<RegistryValue Name="Test" Value="Wow" Type="string" KeyPath="yes"/>
</RegistryKey>**
</Component>
</DirectoryRef>
</Fragment>
</Wix>
I've even tried to modify the registry part like:
<RegistryKey Root="HKCU" Key="Software\Classes\Wow6432Node\TestWow">
<RegistryValue Name="Test" Value="Wow" Type="string" KeyPath="yes"/>
</RegistryKey>
It still does not work.
Your help is much appreciated!
I don't think hkcu is virtualised in the same way as hklm. You need to ensure your component is marked as a 32 bit one and any virtualization will be taken care of for you.
You can create this key using custom action. Dot NET Framework 4.0 has a special feature (RegistryView) to read the 64 bit registry from 32 bit applications. Refer this document for more information. You need to write another custom action to remove this key in uninstall.
Custom Action:
[CustomAction]
public static ActionResult CustomAction1(Session session)
{
RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
key = key.OpenSubKey(#"Software\Classes\Wow6432Node", true);
key.CreateSubKey("TestWow").SetValue("Test", "Wow", RegistryValueKind.String);
return ActionResult.Success;
}
WiX:
<Binary Id="TestWow" SourceFile="CustomAction\TestProject\TestProject\bin\Release\TestProject.CA.dll" />
<CustomAction Id="TESTWOW" BinaryKey="TestWow" DllEntry="CustomAction1" Return="check" />
<Custom Action="TESTWOW" After="InstallInitialize" >Not Installed</Custom>

wix not updating executable

I am new to WIX. In fact, this is my first project. So it should not be surprising that I am having issues.
I had my installer all setup and ready to roll, but this morning I needed a change made to my service, so I made the change and compiled. I build the WIX project and installed it. I started my service up and ran it, but the old code was executed. As it turns out, the old version of my service is still installed. Does this mean that the new version of the service was not packaged or that there was some kind of upgrade rule that I am missing? For some reason the PDB file got updated, but not the EXE.
Below is my wxs file. Please be kind...
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define AppName="My Service"?>
<?define MfgName="My Company"?>
<?define SourcePath="..\My Service\bin\$(var.Configuration)"?>
<Product Name="$(var.AppName)" Language="1033" Version="1.0.0.0" Manufacturer="$(var.MfgName)"
Id="*" UpgradeCode="063de86b-f12b-4af1-91ff-ce0917fffd5c" Codepage="1252">
<Package Id="*" Keywords="Installer" Description="$(var.AppName) Installer"
Manufacturer="$(var.MfgName)" Comments="My Service blah blah blah"
InstallerVersion="200" Compressed="yes" InstallScope="perMachine" SummaryCodepage="1252" />
<!--
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
-->
<Media Id="1" Cabinet="setup.cab" EmbedCab="yes" DiskPrompt="CD-ROM #1"/>
<Property Id="DiskPrompt" Value="$(var.AppName) Installer [1]"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="CompanyFolder" Name="$(var.MfgName)">
<Directory Id="INSTALLFOLDER" Name="$(var.AppName)">
<Component Id="ServiceFile" Guid="3688d9ee-08ed-4dde-87d8-3b7a752a99bf">
<File Id="ServiceEXE" Name="My Service.exe" DiskId="1" Source="$(var.SourcePath)\My Service.exe" KeyPath="yes" Vital="yes" />
<File Id="ServicePDB" Name="My Service.pdb" DiskId="1" Source="$(var.SourcePath)\MY Service.pdb" KeyPath="no" Vital="yes"/>
<File Id="LibraryDLL" Name="library.dll" DiskId="1" Source="$(var.SourcePath)\library.dll" KeyPath="no" Vital="yes"/>
<File Id="LibraryPDB" Name="library.pdb" DiskId="1" Source="$(var.SourcePath)\library.pdb" KeyPath="no" Vital="yes"/>
<File Id="Config" Name="My Service.exe.config" DiskId="1" Source="$(var.SourcePath)\My Service.exe.config" KeyPath="no" Vital="yes"/>
<ServiceInstall Id="InstallService" Name="MyService" Type="ownProcess" ErrorControl="normal" Start="auto"
DisplayName="$(var.AppName)" Description="My Service blah blah blah">
<ServiceConfig OnInstall="yes" DelayedAutoStart="yes" />
</ServiceInstall>
<ServiceControl Id="ControlService" Name="MyService" Remove="both" Stop="both" Wait="no"/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id="MainFeature" Title="$(var.AppName) Setup" Level="1">
<ComponentRef Id="ServiceFile"/>
</Feature>
</Product>
</Wix>
If the installation was successful yet the file was not updated, you should log the install to see why. For example:
msiexec /i filename.msi /lvoicewarmupx log.txt
One reason for a file to not get updated is if Windows Installer checks the version of the existing file and it is newer than the version of the file you are trying to install.