Setting directory of ComponentGroupRef in Wix? - path

I have used the Heat tool to generate a wxs file based on a folder whose contents I want to install. This gives me a large file like this:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="dir1FC8A0605F7DF8B33E3EECB0A1270FA2" Name="DirectoryName" />
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="ComponentGroupId">
<Component Id="cmp1FB67A60B41F3170889B7E5739A23560" Directory="dir1FC8A0605F7DF8B33E3EECB0A1270FA2" Guid="{2DC3B790-D29C-4090-B4CF-5C27687C6ABE}">
<File Id="filF1E1262E52254B1846C7CB2393126A6F" KeyPath="yes" Source="PathToFile" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
In my main Wix file, Product.wxs, I have a feature that references the above ComponentGroup that was created by Heat. The feature looks something like this:
<Feature Id="FeatureId" Title="FeatureTitle" Level="1" AllowAdvertise="no" Absent="disallow" Description="Feature description.">
<ComponentGroupRef Id="ComponentGroupId" />
</Feature>
This is working but when I run my installer, the files within the component group are placed in the root of the C drive (i.e. C:\DirectoryName) but I would like them to go into Program Files (e.g. C:\Program Files\DirectoryName).
Any ideas?
Thanks,
Alan

You can pass the Id of the directory you want to reference to heat with the -dr argument like
heat -dr AutogeneratedComponentsDir
Or DirectoryRefId attribute if you are using the HeatDirectory task in msbuild.
Then just define the location of that directory in your main Product.wxs.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="YourProduct">
<Directory Id="AutogeneratedComponentsDir"/>
</Directory>
</Directory>
</Directory>

Related

Wix only registers one Service even though I declare 3

My .wxs file has a piece like this
<Directory Id="UDPMonitorFiles" Name="UDP Monitor">
<Component Id="UDPMonitorFiles" Guid="*">
<File Id="UDP_UDPMonitor.exe"
Source="$(var.UDP Monitor.TargetDir)\UDP Monitor.exe"/>
<File Id="UDP_UDPMonitor.exe.config"
Source="$(var.UDP Monitor.TargetDir)\UDP Monitor.exe.config"/>
<ServiceInstall
Id="UDPServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="DiskManagement"
DisplayName="Epicentral UDP Monitor"
Description="Epicentral UPD Printer Monitoring Service"
Start="demand"
Account="LocalSystem"
ErrorControl="ignore"
Interactive="no">
</ServiceInstall>
</Component>
</Directory>
<Directory Id="S2SCallerServiceFiles" Name="S2S Caller Service">
<Component Id="S2SCallerServiceFiles" Guid="*">
<File Id="S2SCallerService.exe"
Source="$(var.S2SCallerService.TargetDir)\S2SCallerService.exe"/>
<File Id="S2SCallerService.exe.config"
Source="$(var.S2SCallerService.TargetDir)\S2SCallerService.exe.config"/>
<File Id="S2S.xml"
Source="$(var.S2SCallerService.TargetDir)\S2S.xml"/>
<File Id="S2S_log4net.dll"
Source="$(var.S2SCallerService.TargetDir)\log4net.dll"/>
<ServiceInstall
Id="S2SCallerServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="DiskManagement"
DisplayName="Epicentral S2S Caller Service"
Description="Epicentral S2S Caller Service"
Start="demand"
Account="LocalSystem"
ErrorControl="ignore"
Interactive="no">
</ServiceInstall>
</Component>
</Directory>
<Directory Id="HealthWatcherServiceFiles" Name="Health Watcher Service">
<Component Id="HealthWatcherServiceFiles" Guid="*">
<File Id="HealthWatcherService.exe"
Source="$(var.HealthWatcherService.TargetDir)\HealthWatcherService.exe"/>
<File Id="HealthWatcherService.exe.config"
Source="$(var.HealthWatcherService.TargetDir)\HealthWatcherService.exe.config"/>
<ServiceInstall
Id="HealthWatcherServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="DiskManagement"
DisplayName="Epicentral Health Watcher Service"
Description="Epicentral Health Watcher Service"
Start="demand"
Account="LocalSystem"
ErrorControl="ignore"
Interactive="no">
</ServiceInstall>
</Component>
</Directory>
That somehow only registers one service even though there are 3 projects with their own entry. If I comment out the one which installs (HealthWatcherServiceInstaller) then S2SCallerServiceInstaller is registered instead.
Any ideas how this could happen?
The ServiceInstall/#Name attribute is the name of the service. You have set all of the services to have the same name. You need to specify different names for each service.

Wix Script Installation - Not happening Jenkins

We are using Wix script for installation through Jenkins. Ours is 64-bit OS. If executed through command prompt Windows\system32 desktop folder is dispalyed as C:\Users\XXXXX\Desktop\ which will do the installation properly. But if we run through Jenkins Desktop folder is C:\Windows\SysWOW64\config\systemprofile\Desktop\ . In later case installation and shortcut creation is improper. How to overcome this ?? What might be the reason?? Thank you in advance for any help. Here is the WIX SCRIPT
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="1.0.0.0"
Language="1033" Name="Product" Manufacturer="ABC">
<Package InstallerVersion="200" Compressed="yes"
Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="Product">
<Component Id="XYZ" Guid="*">
<File Id="XYZ.exe" Source="D:\Repo\Solution\XYZ\bin\Debug\XYZ.exe">
</File>
</Component>
</Directory>
</Directory>
<Directory Id="DesktopFolder" Name="XYZ">
<Component Id="ApplicationShortcuts" Guid="*">
<Shortcut Id="ApplicationShortcut1" Name="XYZ"
Description="Product Shortcut"
Target="[APPLICATIONROOTDIRECTORY]XYZ.exe"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\XYZ"
Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="XYZ"/>
<ComponentRef Id="ApplicationShortcuts"/>
</Feature>
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
</Product>
</Wix>
It seems Jenkins is running as SYSTEM account. If you want to run Jenkins as user XXXXX so that the installation goes fine as it went while running as user XXXXX, then just try running Jenkins with the same user. To do that, go to Run > type services.msc > select Jenkins > (Right-click and select) Properties > Click on Log On tab > Select This account
Now enter the user name with which you want to run Jenkins and its password. Now restart Jenkins. You can now give a try to your WiX script.

Wix 3.8: Installer not uninstalling previous version or installing new version

I have created a Wix installer that is meant to replace an installer that was created in Visual Studio, and is supposed to update a previous version of the software it is installing. I kept the same upgrade code that was used in the previous installer for mine, so I thought that this code would work:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="Product"
Language="1033"
Version="1.0.6.0"
Manufacturer="Company"
UpgradeCode="PREVIOUSLY-USED-UPGRADE-CODE">
<Package InstallerVersion="301"
Compressed="yes"
InstallScope="perMachine"
Manufacturer="Company"
Description="Installs Product"
Keywords="Installer,MSI" />
<Media Id="1"
Cabinet = "Product.cab"
EmbedCab = "yes"/>
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of Product is already installed." AllowDowngrades="no"/>
<Directory Id ="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="CompanyFolder" Name ="Company">
<Directory Id="INSTALLDIR" Name="Product" />
</Directory>
</Directory>
</Directory>
<Feature Id ="ProductFeature"
Title = "Product Feature"
Level = "1">
<ComponentGroupRef Id="ProductComponents"/>
</Feature>
<ComponentGroup Id="ProductComponents" Directory="INSTALLDIR">
<Component Id="cmpCOMAdminW2K" Guid="*">
<File Id="COMAdminW2K" Vital="yes" KeyPath="yes" Name="Interop.COMAdminW2K.dll" Source="Local\Path\To\Interop.COMAdminW2K.dll" />
<!-- Several registry entry updates -->
</Component>
<Component Id="cmpCustomSerializer" Guid="*">
<File Id="CustomSerializer" Vital="yes" KeyPath="yes" Name="AREANAME.Serialization.CustomSerializer.v2.0.dll" Source="Local\Path\To\AREANAME.Serialization.CustomSerializer.v2.0.dll" />
</Component>
<Component Id="cmpProductServer" Guid="*">
<File Id="ProductServer" Vital="yes" KeyPath="yes" Name="AREANAME.ProductServer.Shared.v2.0.dll" Source="Local\Path\To\AREANAME.ProductServer.Shared.v2.0.dll" />
</Component>
<Component Id="cmpRemotingHelper" Guid="*">
<File Id="RemotingHelper" Vital="yes" KeyPath="yes" Name="AREANAME.TechPC.RemotingHelper.v2.0.dll" Source="Local\Path\To\ND1.TechPC.RemotingHelper.v2.0.dll" />
</Component>
<Component Id="cmpProduct" Guid="*">
<File Id="Product" Vital="yes" KeyPath="yes" Name="AREANAME.TechPC.Service.Product.v2.0.exe" Source="Local\Path\To\AREANAME.TechPC.Service.Product.v2.0.exe" />
<ServiceInstall
Id="Product"
Name="ServiceName"
DisplayName="Full Service Name"
Start="auto"
ErrorControl="normal"
Type="ownProcess"/>
<ServiceControl
Id="startAndStopUsrPres"
Name="ServiceName"
Start="install"
Stop="both"
Remove="uninstall"
Wait="yes"/>
</Component>
<Component Id="cmpProductConfig" Guid="*">
<File Id="ProductConfig" Vital="yes" KeyPath="yes" Name="AREANAME.TechPC.Service.Product.v2.0.exe.config" Source="Local\Path\To\AREANAME.TechPC.Service.Product.v2.0.exe.config" />
<RemoveFile Id="RemoveProductConfig" Name="AREANAME.TechPC.Service.Product.v2.0.exe.config" On ="install"/>
</Component>
<Component Id="VersionRegistryEntry" Guid="*">
<RegistryKey Root="HKLM"
Key="Software">
<RegistryKey Key="Company"
ForceCreateOnInstall="yes">
<RegistryKey Key="Product"
ForceCreateOnInstall="yes">
<RegistryValue Id="ProductVersionEntry"
KeyPath ="yes"
Action ="write"
Name="Version"
Value="1.0.6.0"
Type="string"/>
</RegistryKey>
</RegistryKey>
</RegistryKey>
</Component>
</ComponentGroup>
</Product>
</Wix>
*Above code is obviously redacted.
The installer will be run on almost all of my company's machines through a software management system, so I have been testing my installer with the following command line:
msiexec.exe /i <ProductInstaller>.msi /quiet /l*v log.txt
That brings me to the problem. Some of you may have noticed that I have a "RemoveFile" tag inside the component containing my config file. I have it there because that file was not always getting updated when the installer ran. This, coupled with the MajorUpgrade schedule, allowed me to remove that file out of the target directory and ensure that the new config file was always getting put in that location. That fix seemed to work in my tests. The program files all appeared to be correct whenever I tried to run the installer on a machine that had a previous version of the program. However, even with all of the correct files in the correct location, the service would not start, either automatically or by manually attempting to start it within services.msc. Additionally, whenever I tried to run the following to uninstall:
msiexec.exe /x <ProductInstaller>.msi /quiet /l*v log.txt
I received the error message "This action is only available for products that are currently installed."
I'm not sure what to make of that since the new files are where they are supposed to be, and the old files are gone.
With all of that information, my question is somewhat vague: "What am I missing in order to have an installer that puts all files in the proper location and starts the service on install, and stops the service and removes the files on uninstall?"
Any assistance would be appreciated, and I would be happy to provide portions of the log files upon request to anybody who thinks that they would help in helping me to figure out what's going on.
Thank you!
-Seth
It was, in fact, that renamed .dll that was causing the problem.

Separate build for each device

There are plenty of Blackberry devices available. Some devices are touch enabled phones.
Since the BlackBerry phone models are different from each other, do I need to have a separate build for each device?
If not, what is the procedure for developing a BlackBerry app for different BlackBerry devices?
If you don't want to use updated feature of the updated OS,then its fine.You can create single code for each device.
But if you want to use the latest feature like touch event etc.then you have to implement code for both-touch and non-touch ,create .cod file for each and define path for each in application.alx file.
As given below.
<application id="bgapp1">
<name >
</name>
<description >
</description>
<version >
1.0.0
</version>
<vendor >
BlackBerry Developer
</vendor>
<copyright >
Copyright (c) 2011 BlackBerry Developer
</copyright>
<fileset Java="1.54" _blackberryVersion="[4.5.0,4.5.1)">
<directory >
4.5.0
</directory>
<files >
bgapp1.cod
</files>
</fileset>
<fileset Java="1.54" _blackberryVersion="[4.6.0,4.6.1)">
<directory >
4.6.0
</directory>
<files >
bgapp1.cod
</files>
</fileset>
<fileset Java="1.54" _blackberryVersion="[4.6.1,4.6.2)">
<directory >
4.6.1
</directory>
<files >
bgapp1.cod
</files>
</fileset>
<fileset Java="1.54" _blackberryVersion="[4.7.0,4.7.1)">
<directory >
4.7.0
</directory>
<files >
bgapp1.cod
</files>
</fileset>
<fileset Java="1.54" _blackberryVersion="[5.0.0)">
<directory >
5.0.0
</directory>
<files >
bgapp1.cod
</files>
</fileset>
<fileset Java="1.54" _blackberryVersion="[6.0.0)">
<directory >
6.0.0
</directory>
<files >
bgapp1.cod
</files>
</fileset>
</application>
There are several factors that you have to consider due to the differences between BlackBerry devices. Here are a few factors to consider;
-Operating System (e.g. 4.6, 5.0, 6.0): There may be features in newer OSs that you might want to take advantage of that are not available on an older OS. You can wrap code in pre-processor directives or have separate files wherever your code base deviates in this respect. BB OS 4.7 introduced touch screen capabilities.
-Screen Resolution: You might need to modify your layout, images you use such as background graphics or other UI elements based on the available screen real estate. Some popular resolutions are 320x240, 480x360, devices yet to release are expected to be 800x480.
The typical development procedure involves you setting up a separate build for each device configuration (resolution and os combination, as several devices share the same configuration). You can use Ant and BB-Ant-Tools for that.
If you're just starting BB development, I recommend that you invest your efforts in BB 5.0+, if not 6.0 as a minimum. For most people, this is good advice (tried and true on my part).

Can anyone give me a example of modifying windows environment system variables in WIX?

I still don't know how to add the installdir into the PATH of the Windows System Variables after I went through the WIX tutorial.
I tried to use
Environment Id='UpdatePath' Action='create' Name='PATH' System='yes' Value='[INSTALLDIR]'
But there was no change in the Path after I installed the program. I can hardly find sample code of WIX anywhere.
Please help me, thanks a lot!
You should be able to use:
<Environment Id="PATH" Name="PATH" Value="[INSTALLDIR]" Permanent="yes" Part="last" Action="set" System="yes" />
This should add a new entry to the environment path, set to [INSTALLDIR].
Another thing to note is, Environment need to be placed inside a component with directory, e.g.
<DirectoryRef Id="TARGETDIR">
<Component Id="Path" Guid="{xxx-xxx-xxx-xxx}">
<Environment Id="PATH" Name="PATH" Value="[INSTALLDIR]" Permanent="no" Part="last" Action="set" System="no" />
</Component>
</DirectoryRef>
Details of Wix Element described at Environment Element
Had the same exact problem, this have worked for me:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="DataBaseds_Service_Installer" />
</Directory>
</Directory>
<ComponentGroup Id="Components" Directory="INSTALLFOLDER">
...some components
</ComponentGroup>
<DirectoryRef Id="TARGETDIR">
<Component Id="MYSQL_PASSWORD" Guid="..."
<Environment Id=HERE YOU CAN ADD THIS :)/>
</Component>
</DirectoryRef>

Resources