2014-04-28 24 views
10

我很努力讓MajorUpgrade,ServiceControl,.config文件很好地一起工作。 After my other question,我現在有點反過來了。WiX重大升級的Windows服務,保存.config,並避免重啓

之前,文件沒有被覆蓋,因爲AssemblyFileVersions是靜態的,所以我解決了這個問題。現在1),即使Schedule="afterInstallExecute"KeyPath='yes'的.config文件仍然被覆蓋即使現有文件的修改日期比文件創建日期不同,它被設置爲的keyPath。我目前不得不覆蓋.config文件並在安裝後重新啓動服務。

2)即使我修復,我仍然有一個問題避免重新啓動。如果我說Schedule="afterInstallInitialize"那麼我相信.config文件肯定會與服務一起被刪除得太早。如果我說Schedule="afterInstallExecute"那麼服務不會停止,安裝後需要重新引導。 (是的,對嗎?)在安裝之前手動停止服務讓我避免重新啓動。添加net stop自定義操作可能會取代我想的ServiceControl,但正確獲取所有條件似乎很複雜。

3)作爲獎勵,我想不是升級期間所有刪除服務。我能否停止服務,更換二進制文件,然後再次啓動服務?這將避免重新輸入服務帳戶憑證的升級。但是,當然,它仍然需要在第一次安裝時進行安裝,並在刪除功能時進行卸載。

下面是它的肉(這也將在後面捆綁,在某種程度上重要的情況下):

<MajorUpgrade DowngradeErrorMessage="A newer version is already installed." 
       Schedule="afterInstallExecute" /> 

<ComponentGroup Id="ServiceCG"> 
    <Component Id="Service" Guid='*' Win64='yes' Directory='INSTALLDIR'> 
     <File Id='ServiceEXE' Source='$(var.root)Service.exe' /> 
     <ServiceInstall Id="ServiceInstall" 
          Name="MyService" 
          DisplayName="My Server" 
          Type="ownProcess" 
          Start="auto" 
          ErrorControl="normal" 
          Description="My Server Service" 
          Interactive="no" 
          Account="[...]" 
          Password="[...]" /> 
     <ServiceControl Id="StopService" Name="MyService" Start="install" 
         Stop="uninstall" Wait="yes" Remove="both" /> 
     <util:User Id="UpdateServiceAccountLogonAsService" UpdateIfExists="yes" 
        CreateUser="no" Name="[SERVICEACCOUNTFULL]" 
        LogonAsService="yes"/> 
    </Component> 
    <Component Id="ServiceConfig" Guid='*' Win64='yes' Directory='INSTALLDIR'> 
     <File Id='FileServiceConfig' KeyPath='yes' 
       Source='$(var.root)Service.exe.config' /> 
    </Component> 
</ComponentGroup> 

相關,但沒有答案:

WiX的3.8版.1128.0

+0

您使用的是哪個版本的wix?知道這可能會幫助你得到有用的答案。 –

+0

WiX版本3.8.1128.0 –

+0

WiX版本與此問題無關。涉及的所有元素都映射到Windows Installer表並且沒有其他自定義擴展。這是MSI潛在的行爲,這很重要。 –

回答

5

編輯:看來同樣的問題的這種解釋,或在同一主題至少,可能會更容易理解:Msiexec: automatic rollback to previous version on installation failure


你撞你的頭靠在幾個核心MSI使用問題在這裏。

  1. 文件版本:安裝過程中的默認文件覆蓋模式(由REINSTALLMODE property)中定義不能替代都是平等的版本默認的文件。這可以通過設置REINSTALLMODE =「emus」來改變。這將替換版本文件的版本相同的文件。如果修改和創建日期不同,未版本控制的文件將被保留。
  2. 升級行爲:像克里斯說,這似乎是恢復到默認文件實際上因重大升級配置卸載並重新安裝。如果RemoveExistingProducts放置在InstallExecuteSequence的後面,則只能在主要升級中進行文件保存。然後,不會卸載發行版之間的共享文件,並且點1中描述的文件版本控制規則適用於覆蓋。
  3. 服務配置保存:服務憑證信息避免再入是,在InstallExecuteSequence早期卸載重大升級的通病。換句話說,該產品已卸載,然後重新安裝擦除已更改的文件。我不建議這樣做,但有些人認爲這一解決方案:How to only stop and not uninstall windows services when major upgrade in wix?羅布Mensching是維克斯和逆戟鯨的作者 - 我想他是在暗示該解決方案作爲一個選項,而不一定是推薦請問鏈接。後肯定)。與正確的組件引用和卸載在這個問題通常是完全避免,這是再一個優選的方法中,InstallExecuteSequence晚放置(正常組分引用防止從卸載完全離開服務設置的部件和改變配置文件完好 - 當且僅當, 組件引用是正確的 - 請參閱下面對此概念的描述)。然而,我的首選方法仍然是使用一個單獨的MSI爲服務安裝和配置如果您正在使用的用戶帳戶來運行服務 - 那麼它是一個自包含部署單元,可以包括在引導程序和自行更新,最重要的是:它不受任何其他應用程序更改或修補程序的干擾。最後我想指出的是,使用用戶帳戶運行的服務並不是建議的方法,因爲安全和部署的原因都是如此。

組件引用:是指分配給MSI組件的GUID,以及他們如何必須相符,並且在任何時候通過所有的升級只有一個(絕對)路徑。這裏有幾個例子可以更好地討論這個問題:Change my component GUID in wix?

我沒有提到將MSI組件安裝服務設置爲永久的選項,以防止它們在卸載時被移除,原因很簡單,這不是很好練習。然後文件和註冊將保留在最終卸載,並且您需要自定義操作來清理。非常不好的做法,並會導致大量額外的工作和懸掛組件引用的問題。

+0

對於1,.config文件的版本如何?我不相信重寫'REINSTALLMODE'是必要的。並且'ServiceControl'應該如何與'',以便不需要重啓?通過升級,服務是否停止,然後在安裝期間啓動一次,在卸載期間再啓動一次?使用'',所以初始安裝失敗,因爲GAC的程序集仍然在服務啓動時在GAC Temp目錄中。 –

+0

.config文件沒有版本。替換邏輯不會替換修改的文件(創建和修改日期不同)。關於GAC,請閱讀此內容並真正評估您對GAC的優先級:http://stackoverflow.com/questions/2451123/when-should-i-deploy-my-assemblies-into-the-gac –

+0

這些程序集隨着時間推移而版本化,並且在孤立的應用程序域中並行運行。 –

4

文件創建/ mod規則僅適用於安裝/重新安裝組件。它不會阻止組件被卸載。您的主要升級計劃很早,這意味着先前的版本已完全卸載,然後安裝新版本。這就是爲什麼你的文件被覆蓋,當你不希望它。稍後安排RemoveExistingProducts以避免此問題。

將您的停止屬性設置爲安裝和卸載。這兩個改變應該可以解決你的問題。

+0

ServiceControl應該如何與一起設置,以便不需要重啓?通過升級,服務是否停止,然後在安裝期間啓動一次,在卸載期間再啓動一次?當並且不管Wait = yes/no時,初始安裝失敗,因爲當服務時GAC的程序集仍在GAC Temp目錄中開始。 –