Wix Script Installation - Not happening Jenkins - 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.

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 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.

Stopping and uninstalling a different service when user uninstalls

Is there anyway to check to see if a service is installed, and if so, stop it and uninstall it when my application is being uninstalled using WiX 3.7? I don't want WiX to install the service though - just uninstall it.
I have WiX setup to install several application components, but the application itself CAN spawn a Windows Service (depending on features selected during install). I'm not really sure what the best way to clean that up is - I guess just to have my setup check if that service exists and remove it upon uninstall.
I'm not sure if I would need a CustomAction for that. I'm fairly familiar with installing services with WiX, but not JUST removing them (if it exists).
Here is my setup project. Just to give a little additional background on this, this is an auto-updater/launcher application. It takes a series of XML files to tell it how to update/prepare an application. If you choose the "MyApp Printer" feature, for example, it would install an extra XML file that tells my application how to hash check the local files against a web service and then install and start the "MyApp Printer" Windows Service for that component. The Windows Service that is located inside my actual WiX Setup Project is something completely different, and that works fine when uninstalling so please disregard that one.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="MyApp ID" Language="1033" Version="1.0.0.0" Manufacturer="MyApp ID" UpgradeCode="932dbe1f-e112-4bd0-8f60-b81850fb465b">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<WixVariable Id="WixUILicenseRtf" Value="EULA.rtf" />
<Feature Id="ProductFeature" Title="MyApp ID Setup Core" Level="1" Absent="disallow" Display="expand">
<ComponentGroupRef Id="ProductComponents" />
<ComponentRef Id="MyAppStartMenuFolderRemove" />
<Feature Id="MyAppClientFeature" Title="MyApp ID Windows Client" Level="1" Absent="allow">
<ComponentGroupRef Id="MyAppClientComponents" />
<ComponentRef Id="MyAppStartMenuIcon" />
</Feature>
<Feature Id="MyAppPrinterFeature" Title="MyApp ID Printer App" Level="2" Absent="allow">
<ComponentGroupRef Id="MyAppPrinterComponents" />
<ComponentRef Id="PrinterStartMenuIcon" />
</Feature>
</Feature>
<UIRef Id="WixUI_FeatureTree" />
<UIRef Id="WixUI_ErrorProgressText" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyAppBaseFolder" Name="MyAppID">
<Directory Id="INSTALLFOLDER" Name="MyAppLauncher">
<Directory Id="UPDATESCRIPTSFOLDER" Name="Scripts" />
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="MyApp ID"/>
</Directory>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="PrinterStartMenuIcon">
<Shortcut Id="PrinterStartMenuShortcut"
Name="MyApp ID Printer UI"
Description="Manage the MyApp ID Printer Service"
Icon="MyAppPrinterIcon"
Target="[INSTALLFOLDER]AutoUpdater.exe"
Arguments="MyAppPrinter"
WorkingDirectory="INSTALLFOLDER">
<Icon Id="MyAppPrinterIcon" SourceFile="$(var.AutoUpdater.Launcher.TargetDir)\Resources\MyApp_printer_white.ico" />
</Shortcut>
<RegistryValue Root="HKCU" Key="Software\Microsoft\MyApp.CardPrinter.Service" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Component Id="MyAppStartMenuIcon">
<Shortcut Id="MyAppStartMenuShortcut"
Name="MyApp ID"
Description="Run the MyApp ID Windows Client software"
Target="[INSTALLFOLDER]AutoUpdater.exe"
Arguments="MyAppClient"
WorkingDirectory="INSTALLFOLDER"/>
<RegistryValue Root="HKCU" Key="Software\Microsoft\MyApp.WindowsClient" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
<Component Id="MyAppStartMenuFolderRemove">
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\Microsoft\MyApp.WindowsClient" Name="installedFolder" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="LibrariesComponent" Guid="7ED3B3B3-A984-44ED-9BA3-841F53CEA114">
<File Source="$(var.AutoUpdater.Foundation.TargetPath)" Vital="yes" KeyPath="yes" />
<File Source="$(var.AutoUpdater.Module.TargetPath)" Vital="yes" />
<File Source="$(var.AutoUpdater.Module.WebService.TargetPath)" Vital="yes" />
</Component>
<Component Id="ServiceComponent" Guid="CAB8D997-5798-4B9D-8CA0-78AACE58932E">
<File Source="$(var.AutoUpdater.Service.TargetPath)" Vital="yes" KeyPath="yes" />
<File Source="$(var.AutoUpdater.Service.TargetDir)\AutoUpdater.Service.exe.config" Name="AutoUpdater.Service.exe.config" Vital="yes" />
<ServiceInstall Name="ServiceComponentInstall" Id="ServiceComponentInstall" DisplayName="MyApp ID Launcher" Account="LocalSystem" ErrorControl="normal" Type="ownProcess" Start="auto" Vital="yes" />
<ServiceControl Name="ServiceComponentInstall" Id="ServiceComponentControl" Start="install" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
<Component Id="LauncherComponent">
<File Source="$(var.AutoUpdater.Launcher.TargetPath)" Vital="yes" />
<File Source="$(var.AutoUpdater.Launcher.TargetDir)\Resources\MyApp_printer_white.ico" Name="MyApp_printer_white.ico" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="MyAppClientComponents" Directory="UPDATESCRIPTSFOLDER">
<Component Id="MyAppClientXml">
<File Source="$(var.AutoUpdater.Service.TargetDir)\Scripts\MyAppClient.xml" Name="MyAppClient.xml" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="MyAppPrinterComponents" Directory="UPDATESCRIPTSFOLDER">
<Component Id="MyAppPrinterXml">
<File Source="$(var.AutoUpdater.Service.TargetDir)\Scripts\MyAppPrinter.xml" Name="MyAppPrinter.xml" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
I hope that wasn't too confusing :). Thanks in advance!
EDIT:
Thank you Rob, the solution was to add the <ServiceControl> element to the last Fragment:
<Fragment>
<ComponentGroup Id="MyAppPrinterComponents" Directory="UPDATESCRIPTSFOLDER">
<Component Id="MyAppPrinterXml">
<File Source="$(var.AutoUpdater.Service.TargetDir)\Scripts\MyAppPrinter.xml" Name="MyAppPrinter.xml" />
<ServiceControl Id="NukeMyAppPrinterService" Name="MyApp ID Printer Service" Remove="uninstall" Stop="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
It will work whether or not that "MyApp ID Printer Service" is installed or not. I love the easy solutions!
Can't say I've done this myself (this is a pretty unique scenario) but the ServiceControl element should do the work just fine:
<ServiceControl Id='NukeService' Name='YourServiceName'
Remove='uninstall' Stop='uninstall' />

Setting directory of ComponentGroupRef in Wix?

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>

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