Wix: Stopping a Windows Service on uninstall - windows-services

When I uninstall my service I get the error where it says I have to stop such and such service before uninstalling. This is unsatisfactory - the uninstaller should automatically stop it.
I found a blog or newsgroup posting on this months ago and got it to work properly, but now it has stopped working for me. And I don't have a link to the post... maybe someone else know where it is? :) I guess I changed some subtle thing and it stopped working. I find Wix extremely difficult to troubleshoot.
I am using the following include to fetch the property X_ WIN_ SERVICE_ NAME (sorry I don't know how to avoid _ escaping here) from the registry. It doesn't matter on install because in that case I explicitly set it with an input file. This include is used before any components in my wxs file.
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?ifndef SetupXWinServiceRegistryProperties ?>
<?define SetupXWinServiceRegistryProperties ?>
<?define XWinServiceRegistryKey='Software\X\Y'?>
<Property Id="X_WIN_SERVICE_NAME">
<RegistrySearch Id="XWinServiceNameSearch"
Root="HKLM"
Key="$(var.XWinServiceRegistryKey)"
Name="ServiceName"
Type="raw"/>
</Property>
<?endif?>
</Include>
The following include component is used to save the registry value on install:
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?ifndef WriteXWinServiceRegistryProperties ?>
<?define WriteXWinServiceRegistryProperties ?>
<Component Id="CompWriteXWinServiceRegistryProps"
Guid="some guid">
<!-- Write properties to the registry. Then they will be
accessable during uninstall. -->
<RegistryValue Root="HKLM"
Key="$(var.XWinServiceRegistryKey)"
Name="ServiceName"
Type="string"
Value="[X_WIN_SERVICE_NAME]"
Action="write" />
</Component>
<?endif?>
</Include>
I have checked my system after install and the registry value is properly written there. The part in my component where the service is setup looks like:
<ServiceInstall Id="ServiceInstallXWinService"
Name="[X_WIN_SERVICE_NAME]"
Start="auto"
DisplayName="xxx"
Description="yyy"
Account="[X_WIN_SERVICE_USER]"
Password="[X_WIN_SERVICE_PASSWORD]"
Type="ownProcess"
ErrorControl="normal"
Vital="yes" />
<ServiceControl Id="ServiceInstallXWinService"
Name="[X_WIN_SERVICE_NAME]"
Stop="both"
Remove="uninstall"
Wait="yes" />
Any ideas?

Are you sure that the X_WIN_SERVICE_NAME property is set to the correct value on uninstall. Use a verbose log file to make sure that the search is setting the value correctly. Everything looks fine (although I don't know why you put everything in Include files instead of just using Fragments).

Related

JavaFX classpath definition to include WiX config file on Windows

On the last few weeks I've been working on a JavaFX Application to deploy for both Unix and Windows. At the moment, I'm trying to customize the install scripts/ config files.
On MacOS I simply included the script to the class path using <property> on my ANT build file like this:
<property name="classpath" location="package/macosx/App-dmg-setup.scpt"/>
But when I try to do the same on Windows, doesn't work (continues using the default config file). I've already tried absolute path, env.CLASSPATH instead of classpath, and some other alternatives, with no success.
Thanks a lot ;)
Cheers!
Ok sorry this question, actually I was inadvertently changing the basedir variable. The correct definition should only be:
<path id="fxant">
<filelist>
<file name="${java.home}\..\lib\ant-javafx.jar"/>
<file name="${java.home}\lib\jfxrt.jar"/>
<file name="${basedir}"/>
</filelist>
</path>
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant"
classpathref="fxant"/>
Without another (re)definition.
Once again, thanks!

SQLite.Interop.dll not getting picked up by OctoPack

I've got a relatively new MVC5 project being built with TeamCity and deployed by Octopus Deploy. Everything was great until I added SQLite through NuGet. When the project gets built, I get an x86\SQLite.Interop.dll and an x64\SQLite.Interop.dll under my bin directory and it runs fine.
The problem is that OctoPack doesn't pick up either file; so, my NuGet package that I deploy to my server doesn't have it. How does one fix this?
The fine folks at Octopus Deploy pointed me to this help page that got me most of the way there.
For anyone else who runs into this particular problem, I originally added this to my .nuspec file:
<files>
<file src="bin\x86\*.*" target="bin\x86" />
<file src="bin\x64\*.*" target="bin\x64" />
</files>
but nothing got copied; so, I changed it to this:
<files>
<file src="bin\x86\SQLite.interop.dll" target="bin\x86" />
<file src="bin\x64\SQLite.interop.dll" target="bin\x64" />
</files>
Then TeamCity had a build error because x86 and x64 were empty. It looks like OctoPack somehow runs before those files get copied. It's a hack that I hope to remove at some point, but I got things working by adding those two files to my project, and changing my nuspec file to this:
<files>
<file src="SQLiteFiles\x86\SQLite.interop.dll" target="bin\x86" />
<file src="SQLiteFiles\x64\SQLite.interop.dll" target="bin\x64" />
</files>
Also, don't forget to add OctoPackEnforceAddingFiles=true in TeamCity.
I did something similar, but I HATE checking in binaries to source control, so I added this to my nuspec file:
<files>
<file src="..\..\packages\System.Data.SQLite.Core.1.0.98.1\build\net45\x86\SQLite.interop.dll" target="x86" />
<file src="..\..\packages\System.Data.SQLite.Core.1.0.98.1\build\net45\x64\SQLite.interop.dll" target="x64" />
</files>
Just go yank them out of the packages dir, I guess you could do something like this:
<files>
<file src="..\..\packages\System.Data.SQLite.Core.*\build\net45\x86\SQLite.interop.dll" target="x86" />
<file src="..\..\packages\System.Data.SQLite.Core.*\build\net45\x64\SQLite.interop.dll" target="x64" />
</files>
And I think it'll work regardless of version
You need to add a nuspec file with a files element to tell octopack that it should include the SQLite.interop.dll binaries.
<files>
<file src="bin\x86\SQLite.interop.dll" target="x86" />
<file src="bin\x64\SQLite.interop.dll" target="x64" />
</files>
Then, you need to reorder the imports in your project file so that SQLite comes before Octopack, this will ensure that SQLite.interop.dll is copied before Octopack runs.
<Import Project="..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.105.2\build\net451\System.Data.SQLite.Core.targets')" />
<Import Project="..\packages\OctoPack.3.0.42\tools\OctoPack.targets" Condition="Exists('..\packages\OctoPack.3.0.42\tools\OctoPack.targets')" />
Finally, make sure to add the parameter OctoPackEnforceAddingFiles=true, this tells octopack to include the files targeted by the Files element in the nuspec file.

Check registry keys of a Software that is already installed in your system For WIX setup

I have a WIX setup. I want to promt message box for some prerequisites before installing my setup.
I am using below code to check registry keys for a particular software.
But it always prompt a message weather a software is installed or not.
<Condition Message="This application requires ReportViewer.">
<![CDATA[ReportViewerV10 OR ReportViewerWow64V10]]>
</Condition>
<util:RegistrySearch
Root="HKLM"
Key="SOFTWARE\Microsoft\ReportViewer\v10.0"
Value="Install"
Variable="ReportViewerV10"
Win64="yes"
/>
<util:RegistrySearch
Root="HKLM"
Key="SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0"
Value="Install"
Variable="ReportViewerWow64V10"
Win64="yes"/>
Can anyone guide me where i am doing wrong?
What should be registry keys for a software?
According to this documentation you don't have your Registry search parameters set up quite right. The following should yield better results.
<Property Id="NReportViewerV10">
<RegistrySearch Id="NetFramework20"
Root="HKLM"
Key="SOFTWARE\Microsoft\ReportViewer\v10.0"
Name="Install"
Type="raw" />
</Property>
<Property Id="ReportViewerWow64V10">
<RegistrySearch Id="NetFramework20"
Root="HKLM"
Key="SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0"
Name="Install"
Type="raw" />
</Property>

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.

ant: best way to setup system-dependent properties?

I have a number of file/executable locations that are likely to be different depending on which computer I am running them on, and I would like to abstract these out through ant properties somehow. What's the best way to do this? Is there a system-wide ant setup script that gets called? Or can I make such a script?
In addition to Vladimir's solution you might have a default properties file for each of the OS or other you might deploy your build system on. Use the ${os.name} (and other Java system properties) to set up a path. For example
<property file="build-${os.name}.properties">
These files can be maintained and checked in into your version control system as well.
I use the more or less standard build.properties and build-local.properties files.
The first contains default values, common to all environments, the second only the exceptions. The first one is checked into subversion while the other is not.
EDIT : copy/pasting Akr's excellent idea
In addition you might have a default properties file for each of the OS or other you might deploy your build system on. These files can be checked in into your version control system as well.
The Ant script would then include all the files as follow (remember: in Ant the first definition wins):
<property file="build-local.properties"/>
<property file="build.properties"/>
<property file="build-${os.name}.properties">
Setup an ant build file called properties.xml, in which you should define the properties that you want to customize.
Here is properties.xml boilerplate I am using for my projects ( I've adapted it from one of the books on Ant ):
<?xml version="1.0" encoding="UTF-8"?>
<project
name="workspace-properties"
>
<dirname
property="workspace-properties.basedir"
file="${ant.file.workspace-properties}"
/>
<!--
==========================================================
Load Environment Variables
==========================================================
-->
<!-- #Load environment variables -->
<property environment="env" />
<!-- this is here to deal with the fact that an IntelliJ IDEA build
has no ant home
-->
<property
name="ant.home"
value="${env.ANT_HOME}"
/>
<!-- get Unix hostname, and set to Windows comparable name -->
<!-- #Trick to get host name x-platform -->
<property
name="env.COMPUTERNAME"
value="${env.HOSTNAME}"
/>
<!--
==========================================================
Load property files
Note: the ordering is VERY important.
==========================================================
-->
<!-- #Allow even users property file to relocate -->
<property
name="user.properties.file"
location="${user.home}/.build.properties"
/>
<!-- Load the application specific settings -->
<!-- #Project specific props -->
<property file="build.properties" />
<!--
==========================================================
Define your custom properties here.
You can overwrite them through build.properties and
${user.home}/.build.properties
==========================================================
-->
<property name="myexec1" location="/usr/bin/myexec1"/>
<property name="myexec2" location="/usr/bin/myexec2"/>
</project>
Important thing here is to come up with as many useful default property values as possible, then you may even never come up with custom build.properties files.
Then you just <import> this file in your project's build.xml.
<project
name="my-project"
>
<!-- this is done, so you may import my-project somewhere else -->
<dirname
property="my-project.basedir"
file="${ant.file.my-project}"
/>
<import file="${my-project.basedir}/relative/path/to/properties.xml"/>
<target name="using.myexec1">
<echo message="myexec1=${myexec1}"/>
</target>
</project>
If you want a custom value for myexec1 in my-project, just drop a custom flat build.properties file in the same directory where build.xml is located.
The build.properties file may look like this:
myexec1=c:/custom/path/to/myexec1.exe

Resources