2017-11-15 2 views
0

cmake 및 cpack을 사용하여 C++ 코드베이스에서 WiX 도구 세트를 사용하여 msi 파일을 만듭니다. 이 설정은 지난 6 개월 동안 훌륭하게 작동하지만 이제는 산발적으로 작동하지 않습니다.WiX가 msi 파일을 생성했습니다. 이상한 주요 업그레이드 동작

내 설치 프로그램은 동일한 업그레이드 코드로 이전 제품을 제거하여 내 제품이 하나만 설치되도록합니다 (항상 주요 업그레이드). 나는 이틀 전에 SCCM을 통해 내 사용자에게 최신 버전을 배포했으며 모든 설치의 10 %에 다음과 같은 문제점이 있습니다.

이전 설치 제거가 잘못된 것 같습니다. 설치 제거 프로세스가 파일을 제거하지만 루트 디렉토리와 bin 디렉토리를 남겨 두었지만 모든 파일은 제거됩니다. WMI를 통해 이전 제품의 설치를 쿼리 할 때 설치되어 있다고 말하면 이상합니다. installations의 다른 90 %는 모든 위대한 작품. 나는 또한 그것을 국부적으로 재현 할 수 없다.

로그 파일이 있는데, 오작동 설치 파일인지 확실하지 않습니다.

로그 파일이 너무 길어서 회의적으로 만 사용하는 스 니펫을 게시합니다.

MSI (s) (0C:9C) [15:21:35:083]: Component: CM_CP_runtime.bin.main2.exe; 
Installed: Absent; Request: Null; Action: Null 
... 
    MSI (s) (0C:78) [15:21:43:591]: Executing op: FileCopy(SourceName=-dbqfin2.dll|FreeImage.dll,SourceCabKey=CM_FP_runtime.bin.FreeImage.dll,DestName=FreeImage.dll,Attributes=512,FileSize=6201856,PerTick=65536,,VerifyMedia=1,,,,,CheckCRC=0,Version=3.17.0.0,Language=1033,InstallMode=58982400,,,,,,,) 
    MSI (s) (0C:78) [15:21:43:591]: File: C:\Program Files\LDS Studio\bin\FreeImage.dll; To be installed; Won't patch; No existing file 

조치 : Null은 조작이 없다는 것을 나타내지 만 그 이유는 확실하지 않습니다. 설치를 다시 시작할 때 이전 버전이 없기 때문에 모든 것이 잘 작동합니다. 나는 Visual Studio에서 cmake로 이식하고 dll에 버전을 추가하는 것을 잊었을 때 (이전의 dll에는 버전이 있었고 새로운 버전에는 버전이 없었기 때문에 msi는 그렇게 생각합니다.) 새 버전이 아니며 REINSTALLMODE 기본 모드 'omus'에서 건너 뜁니다. 그 이후로 우리는 아무것도 바뀌지 않았고, 2 일 전까지는 모든 것이 잘 작동합니다. 여기

내 wix_main.wxs이

<Product Id="$(var.CPACK_WIX_PRODUCT_GUID)" 
    Name="$(var.CPACK_PACKAGE_NAME)" 
    Language="1033" 
    Version="$(var.CPACK_PACKAGE_VERSION)" 
    Manufacturer="$(var.CPACK_PACKAGE_VENDOR)" 
    UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)"> 

    <Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine"/> 

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/> 

    <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" /> 
    <Upgrade Id="$(var.CPACK_WIX_UPGRADE_GUID)"> 
     <UpgradeVersion 
      Minimum="1.0.0.0" Maximum="99.0.0.0" 
      Property="PREVIOUSVERSIONSINSTALLED" 
      IncludeMinimum="yes" IncludeMaximum="no" 
     /> 
    </Upgrade> 

    <WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/> 
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/> 

    <?ifdef CPACK_WIX_PRODUCT_ICON?> 
    <Property Id="ARPPRODUCTICON">ProductIcon.ico</Property> 
    <Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/> 
    <?endif?> 

    <?ifdef CPACK_WIX_UI_BANNER?> 
    <WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/> 
    <?endif?> 

    <?ifdef CPACK_WIX_UI_DIALOG?> 
    <WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/> 
    <?endif?> 

    <FeatureRef Id="ProductFeature"/> 

    <UIRef Id="$(var.CPACK_WIX_UI_REF)" /> 

    <?include "properties.wxi"?> 
    <?include "product_fragment.wxi"?> 

    <CustomAction Id="RegisterExtensions" 
        FileKey="CM_FP_runtime.bin.main.exe" 
        ExeCommand="-regext" 
        Execute="deferred" 
        Return="check" 
        HideTarget="no" 
        Impersonate="no" 
        /> 
    <CustomAction Id="UnregisterExtensions" 
        FileKey="CM_FP_runtime.bin.main.exe" 
        ExeCommand="-unregext" 
        Execute="deferred" 
        Return="ignore" 
        HideTarget="no" 
        Impersonate="no" 
        /> 

    <InstallExecuteSequence> 
     <RemoveExistingProducts Before='InstallInitialize'> 
      NOT REMOVE 
     </RemoveExistingProducts> 
     <Custom Action="RegisterExtensions" After="InstallFiles"> 
      NOT REMOVE 
     </Custom> 
     <Custom Action="UnregisterExtensions" After="InstallInitialize"> 
      Installed AND (REMOVE = "ALL") 
     </Custom> 
    </InstallExecuteSequence> 
</Product> 

나는 사람들이있는 OnlyDetect 모드를 다루는 일부 블로그 게시물을 발견했습니다하지만 난 모르겠어요 파일입니다 내 컴퓨터에서 재현 할 수 없기 때문에 도움이 될 수 있습니다.

아마도 REINSTALLMODE ()로 전환하면 내 최후의 수단이 될 수 있지만, 이것이 내 마지막 수단이 될 것입니다.

내가 찾은이 블로그 게시물 https://jpassing.com/2007/06/16/where-to-place-removeexistingproducts-in-a-major-msi-upgrade/ =>는 내가

<RemoveExistingProducts After='InstallInitialize'> 
       NOT REMOVE 
      </RemoveExistingProducts> 

<RemoveExistingProducts Before='InstallInitialize'> 
       NOT REMOVE 
      </RemoveExistingProducts> 

에서 변경해야 할 일 수 있었다 ???

아마 누군가가 문제를 도와 줄 수

인사말
통카

+0

업그레이드 후에도 이전 제품이 계속 남아 있으면 업그레이드가 실패하고 롤백되고 다시 설치되었음을 의미합니다. 이것은 REINSTALLMODE, RemoveExistingProducts (조건이 필요 없음) 또는 Action = Null이 아닙니다. 새로운 제품이 설치되었는지, 이전 제품이 설치되었는지는 말하지 않았습니다. REP가 트랜잭션 외부에있을 경우 발생할 수 있습니다. 롤백 사용자 지정 작업이 없으므로 작업이 더욱 복잡해집니다. 정말 실패의 전체 로그가 필요하며 REP, InstallInitialize, UnRegisterExtensions의 정확한 순서는 서로 및 InstallValidate와 관련하여 명확하지 않습니다. – PhilDW

+0

제거가 실패하거나 이상한 일이 발생하여 종료되는 경우 이상한 행동이있었습니다. 이로 인해 업그레이드가 발생하고 이전 설치의 기능 상태가 업그레이드로 마이그레이션 되었기 때문에 핵심 기능 및 필수 기능이 설치되지 않은 것으로 표시되어 기능 및 구성 요소와 함께 설치된 제품이 설치되지 않았습니다. 'UpgradeVersion> 태그에 MigrateFeatures = 'no'를 추가하면 문제가 해결 될 수 있습니다. 제품의 구성 요소를 패키지화하고 구성하는 방법 이외의 기능을 실제로 사용하지 않는 경우에 수행 한 작업입니다. –

+0

(처음에는 문제를 일으키는 또 다른 미묘한 디자인 문제가 있음) –

답변

0

당신이 무엇을보고에 대한 가장 그럴듯한 설명은 RemoveExistingProducts (이전 제품의 제거가) 실패한다는 것입니다. 그러면 이전 제품을 복원하는 롤백이 발생합니다. 그런 다음 이전 제품이 설치되고 새 제품이 계속 설치됩니다.어떤 시점에서는 새 업그레이드 설치가 실패하고 롤백되며 이로 인해 이전에 설치 한 제품이 손상 될 수 있습니다. 이는 업그레이드의 트랜잭션 외부에서 RemoveExistingProducts를 업그레이드하는 일반적인 문제입니다. REP가 InstallInitize 이후에 있었던 경우 실패하고 업그레이드가 진행되지 않습니다.

(업그레이드 제품을 설치하고 트랜잭션이 완료되고 이전 제품의 제거가 시도되어 실패하기 때문에 InstallFinalize 이후 및 업그레이드 트랜잭션 외부에서 REP를 시퀀싱하는 경우와 유사한 문제가 발생할 수 있습니다. 오래된 제품을 복원하므로 구형 제품과 신제품이 모두 설치됩니다.)

REP가 실패한 이유와 이전 제품이 설치된 상태로 유지하는 이유를 확인하려면 업그레이드에 대한 자세한 MSI 로그를 작성해야합니다. 업그레이드가 실패했습니다 (그렇지 않은 경우 프로그램 & 기능에 표시되기 때문에). 또한 UpgradeExistingProducts를 업그레이드 트랜잭션 내에서 유지하는 것이 더 안전합니다.

관련 문제