Atihska
Atihska

Reputation: 5126

How to uninstall a service completely from an application in the next upgrade which isn't a major upgrade

I am trying to uninstall an installed service that has several components but not able to. Could anyone please help me with the uninstalling tags too? I did a lot of searches but couldn't run anything successfully.

Just putting ServiceControl tag and removing all the components work? I tried that but didn't work. How do you deal with components and dependencies? Need logic and syntax help.

Below is my code that installs the service in the previous version. Please let me know of the tags that I have to add to remove this.

<Directory Id="dirxxx" Name="oldname">
                <!-- oldname service-->
              <Component Id="cmpOldNameService" Guid="bbb"
                  SharedDllRefCount="no" KeyPath="no" NeverOverwrite="no" Permanent="no" Transitive="no"
                  Win64="no" Location="either">
              <RemoveFile Id="ccc" On="uninstall" Name="z.dll"/>
              <File Id="ccc" KeyPath="no" Source="$(var.xSource)\OldNameService\a.dll"/>
              <File Id="ddd" KeyPath="no" Source="$(var.xSource)\OldNameService\b.dll"/>
              <File Id="eee" KeyPath="no" Source="$(var.xSource)\OldNameService\c.dll"/>
              <File Id="fff" KeyPath="no" Source="$(var.xSource)\OldNameService\d.dll"/>
              <File Id="ggg" KeyPath="no" Source="$(var.xSource)\OldNameService\e.dll"/>
              <File Id="hhh" KeyPath="no" Source="$(var.xSource)\OldNameService\f.dll"/>
              <File Id="iii" KeyPath="yes" Source="$(var.xSource)\OldNameService\g.exe"/>
              <File Id="jjj" KeyPath="no" Source="$(var.xSource)\OldNameService\h.dll"/>
              <File Id="kkk" KeyPath="no" Source="$(var.xSource)\OldNameService\i.dll"/>
              <ServiceInstall Id="OldNameService" DisplayName="OldName Service" Name="NewName"
                ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" Description="OldName Service">
                <ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes"/>
              </ServiceInstall>

              <ServiceControl Id="OldNameServiceControl" Name="NewName"
                Start="install" Stop="uninstall" Remove="uninstall" Wait="no"/>

            </Component>

              <Component Id="lll" Guid="mmm" NeverOverwrite="yes">
                <File Id="nnn" KeyPath="yes" Source="$(var.xSource)\OldNameService\OldName.exe.config"/>
                <util:XmlFile Id="UpdateOldNamelogFileName"
                              File="[#nnn]"
                              Action="setValue"
                              ElementPath="/configuration/appSettings/add[\[]@key='logFile'[\]]/@value"
                              Value="[ooo]oldname_YYYYMM.log" />
              </Component>



<!--Recovery-Interval needs to be added in both cases new install as well as upgrades-->     


                  <Component Id="qqq" Guid="r-r-r-r-r" NeverOverwrite="yes">
                      <Condition><![CDATA[INSTALDIR <> "" AND NOT REMOVE AND POSTV1 = ""]]></Condition>
                      <CreateFolder /> 

                      <util:XmlConfig Id="RecoveryInterval" Action="create" ElementPath="config/settings" File="[INSTALDIR]\oldname\OldNameService.exe.config" Node="element" On="install" Name="add" Sequence="1">
                          <util:XmlConfig Id="RecoveryInterval2" ElementId="RecoveryInterval" Name="key" Value="Recovery-Interval" File="[INSTALDIR]\oldname\OldNameService.exe.config" />
                          <util:XmlConfig Id="RecoveryInterval3" ElementId="RecoveryInterval" Name="value" Value="3600" File="[INSTALDIR]\oldname\OldNameService.exe.config" />
                      </util:XmlConfig>
                  </Component>

                  <!-- Analytics-->
                  <Component Id="eee" Guid="f-f-f-f-f" NeverOverwrite="yes">
                      <Condition><![CDATA[(INSTALDIR <> "") AND NOT REMOVE]]></Condition>
                      <CreateFolder />                          
                      <!-- Analytics-->
                      <util:XmlConfig Id="EnableAnalytics" Action="create" ElementPath="config/settings" File="[INSTALDIR]\oldname\OldNameService.exe.config" Node="element" On="install" Name="add" VerifyPath="/config/settings/add[\[]@key='EnableAnalytics'[\]]">
                          <util:XmlConfig Id="EnableAnalytics2" ElementId="EnableAnalytics" Name="key" Value="VEnableAnalytics" File="[INSTALDIR]\oldname\OldNameService.exe.config" />
                          <util:XmlConfig Id="EnableAnalytics3" ElementId="EnableAnalytics" Name="value" Value="1" File="[INSTALDIR]\oldname\OldNameService.exe.config" />
                      </util:XmlConfig>

                      <util:XmlConfig Id="AnalyticsTrackingId" Action="create" ElementPath="config/settings" File="[INSTALDIR]\oldname\OldNameService.exe.config" Node="element" On="install" Name="add" VerifyPath="/config/settings/add[\[]@key='AnalyticsTrackingId'[\]]">
                          <util:XmlConfig Id="AnalyticsTrackingId2" ElementId="AnalyticsTrackingId" Name="key" Value="AnalyticsTrackingId" File="[INSTALDIR]\oldname\OldNameService.exe.config" />
                          <util:XmlConfig Id="AnalyticsTrackingId3" ElementId="AnalyticsTrackingId" Name="value" Value="YwByAE3eVweXAAcAVwBasBUAAgAMsB0AAwAbzz==" File="[INSTALDIR]\oldname\OldNameService.exe.config" />
                      </util:XmlConfig>
                  </Component>

                  <!-- Added to handle upgrade scenario for assembly binding redirect for Newtonsoft.json -->
                  <Component Id="cmpNewtonsoftVersionUpgrade" Guid="{a-60CA-d-w-f}" NeverOverwrite="yes">
                      <Condition><![CDATA[(INSTALDIR <> "") AND NOT REMOVE]]></Condition>
                      <CreateFolder/>
                      <util:XmlConfig Id="AddRuntimeElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="element" Name="runtime" On="install"
                                      ElementPath="configuration"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/assemblyIdentity[\[]@name='Newtonsoft.Json'[\]]"
                                      Sequence="1" />
                      <util:XmlConfig Id="AddAssemblyBindingElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="element" Name="assemblyBinding" On="install"  ElementPath="configuration/runtime"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/assemblyIdentity[\[]@name='Newtonsoft.Json'[\]]"
                                      Sequence="2"/>
                      <util:XmlConfig Id="AddDependentAssemblyElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="element" Name="dependentAssembly" On="install"
                                      ElementPath="configuration/runtime/assemblyBinding"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/assemblyIdentity[\[]@name='Newtonsoft.Json'[\]]"
                                      Sequence="3"/>
                      <util:XmlConfig Id="AddAssemblyIdentityElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="element" Name="assemblyIdentity" On="install"
                                      ElementPath="configuration/runtime/assemblyBinding/dependentAssembly"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/assemblyIdentity[\[]@name='Newtonsoft.Json'[\]]"
                                      Sequence="4">
                          <util:XmlConfig Id="AddNameKey"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddAssemblyIdentityElement" Name="name" Value="Newtonsoft.Json" />
                          <util:XmlConfig Id="AddPublicKeyToken"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddAssemblyIdentityElement" Name="publicKeyToken" Value="30ad4fe6b2a6aeed" />
                          <util:XmlConfig Id="AddCulture"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddAssemblyIdentityElement" Name="culture" Value="neutral" />
                          <util:XmlConfig Id="AddXmlnsOnAssemblyIdentity"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddAssemblyIdentityElement" Name="xmlns" Value="urn:schemas-microsoft-com:asm.v1" />
                      </util:XmlConfig>
                      <util:XmlConfig Id="DeleteBindingRedirectElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="delete" Node="element" Name="bindingRedirect" On="install"
                                      ElementPath="configuration/runtime/assemblyBinding/dependentAssembly[\[]assemblyIdentity[\[]@name='Newtonsoft.Json'[\]][\]]"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect[\[]@oldVersion='0.0.0.0-6.0.0.0'[\]]"
                                      Sequence="5" />
                      <util:XmlConfig Id="DeleteBindingRedirectElementoldserviceOnv4"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="delete" Node="element" Name="bindingRedirect" On="install"
                                      ElementPath="configuration/runtime/assemblyBinding/dependentAssembly[\[]assemblyIdentity[\[]@name='Newtonsoft.Json'[\]][\]]"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect[\[]@oldVersion='0.0.0.0-8.0.0.0'[\]]"
                                      Sequence="6" />
                      <util:XmlConfig Id="AddBindingRedirectElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="element" Name="bindingRedirect" On="install"
                                      ElementPath="configuration/runtime/assemblyBinding/dependentAssembly[\[]assemblyIdentity[\[]@name='Newtonsoft.Json'[\]][\]]"
                                      VerifyPath="/configuration/runtime/assemblyBinding/dependentAssembly/bindingRedirect[\[]@oldVersion='0.0.0.0-9.0.0.0'[\]]"
                                      Sequence="7">
                          <util:XmlConfig Id="AddOldVersionKey"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddBindingRedirectElement" Name="oldVersion" Value="0.0.0.0-9.0.0.0" />
                          <util:XmlConfig Id="AddNewVersionKeyS3Uploader"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddBindingRedirectElement" Name="newVersion" Value="9.0.0.0" />
                          <util:XmlConfig Id="AddXmlnsOnBindingRedirectS3Uploader"
                                          File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                          ElementId="AddBindingRedirectElement" Name="xmlns" Value="urn:schemas-microsoft-com:asm.v1" />
                      </util:XmlConfig>
                      <util:XmlConfig Id="AddNameSpaceToyElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="value" Name="xmlns" Value="urn:schemas-microsoft-com:asm.v1" On="install"
                                      ElementPath="/configuration/runtime/assemblyBinding"
                                      Sequence="8" />
                      <util:XmlConfig Id="AddNameSpaceToDependentAssemblyElement"
                                      File="[INSTALDIR]\oldname\OldNameService.exe.config"
                                      Action="create" Node="value" Name="xmlns" Value="urn:schemas-microsoft-com:asm.v1" On="install"
                                      ElementPath="/configuration/runtime/assemblyBinding/dependentAssembly[\[]assemblyIdentity[\[]@name='Newtonsoft.Json'[\]][\]]"
                                      Sequence="9" />

                  </Component>
</Directory> 

EXAMPLE TRIAL FOR 1 COMPONENT:

 <Component Id="cmpoldNameService" Guid="9-kj-4509-ko-B4F7700AFDCE"
                                 SharedDllRefCount="no" KeyPath="no" NeverOverwrite="no" Permanent="no" Transitive="yes"
                                 Win64="no" Location="either">
                          <Condition>FALSE</Condition>
                          <RemoveFolder Id="diytg" On="uninstall"/>
                          <RemoveFile Id="ghgj" On="uninstall" Name="a.dll"/>
                          <RemoveFile Id="uiu" On="uninstall" Name="b.dll"/>
                          <RemoveFile Id="hujhjn" On="uninstall" Name="c.dll"/>
                          <RemoveFile Id="okl" On="uninstall" Name="d.dll"/>
                          <RemoveFile Id="bbb" On="uninstall" Name="e.dll"/>
                          <RemoveFile Id="bbbb" On="uninstall" Name="f.dll"/>
                          <RemoveFile Id="kkkl" On="uninstall" Name="g.dll"/>
                          <RemoveFile Id="mmmm" On="uninstall" Name="h.dll"/>
                          <RemoveFile Id="nnn" On="uninstall" Name="i.exe"/>
                          <RemoveFile Id="bboo" On="uninstall" Name="j.dll"/>
                          <RemoveFile Id="ttt" On="uninstall" Name="k.dll"/>

                          <ServiceControl Id="OldNameServiceControl" Name="OldName"
                                          Start="install" Stop="both" Remove="both" Wait="yes"/>

                      </Component>

Upvotes: 0

Views: 80

Answers (1)

Christopher Painter
Christopher Painter

Reputation: 55571

MSI Minor Upgrades can't officially remove components or features. The workaround (Hack) is to keep the original components but supply them a zero byte file and set the Revaluate attribute (transitive bit in MSI) to true and give it a condition that will always evaluate to false. This way the Windows Installer transitions this component to not installed and the service is stopped and removed.

You'll have to keep this 0 byte fake component around until you do your next major upgrade. Then it can be removed.

To be honest, Minor Upgrades are very picky and if you don't already know these rules you might be better served by always doing major upgrades until you do. Minor upgrades can push you into a corner really hard if you let it.

Upvotes: 2

Related Questions