Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
卸载时跳过自定义操作(WiX)_Wix_Windows Installer - Fatal编程技术网

卸载时跳过自定义操作(WiX)

卸载时跳过自定义操作(WiX),wix,windows-installer,Wix,Windows Installer,我正在为现有产品编写MSI。在以前的版本中,有一个自定义操作没有限制为仅在安装时运行,现在在卸载w/MajorUpgrade时失败 在新安装程序中,有没有办法告诉WiX在卸载时跳过特定的自定义操作?是的,您可以从新安装程序中自动执行此操作 解决方案: 1) 您需要修复构建当前安装程序版本的项目中的问题,并从该项目中再次构建良好的MSI。在这种情况下,您只需要MSI数据库,通常只有几KB(即包含所有安装文件的CAB文件等) 2) 在新的安装程序中,您需要一个在RemoveExistingProdu

我正在为现有产品编写MSI。在以前的版本中,有一个自定义操作没有限制为仅在安装时运行,现在在卸载w/MajorUpgrade时失败


在新安装程序中,有没有办法告诉WiX在卸载时跳过特定的自定义操作?

是的,您可以从新安装程序中自动执行此操作

解决方案:

1) 您需要修复构建当前安装程序版本的项目中的问题,并从该项目中再次构建良好的MSI。在这种情况下,您只需要MSI数据库,通常只有几KB(即包含所有安装文件的CAB文件等)

2) 在新的安装程序中,您需要一个在RemoveExistingProducts标准操作之前运行的自定义操作,该操作将为计算机上的早期版本重新设置MSI。您的自定义操作必须执行以下命令:

msiexec.exe/fv“

您试图重新设置的MSI是您在步骤1中构建的新MSI。您需要将此MSI作为资源包含在新版本安装程序中(以及将来的版本,以防某些用户跳过此版本),并将提取此MSI文件的完整路径作为参数传递给您自定义操作

基本上,您要做的是使用正确的MSI(您在自定义操作中设置了正确的条件)自动执行重新编译旧安装的步骤。现在,当RemoveExistingProducts标准操作将执行时,Windows Installer将使用新缓存的MSI触发旧版本的卸载,该MSI在自定义操作中设置了正确的条件,并成功卸载。

中接受的回答似乎不完全有效,因为无法从另一个msi包运行msiexec命令

第一部分仍然正确。您必须修复wix项目中的问题,并生成一个具有相同ProductCode/版本且仅具有MSI数据库的新包。我们将使用此软件包重新设置上一个软件包,以便能够成功卸载它

在新安装程序中,需要执行两个步骤:

  • 重铸以前的msi
  • 启动新msi(产品更新)
  • 我找到的唯一方法是创建一个Wix包,按顺序链接这两个步骤

    1-可以通过一个独立的可执行文件执行重新编译操作,该可执行文件包含对msiexec/fv valid_recache.msi的简单调用。下面是一个C++例子:

    #include <Windows.h>
    
    int main()
    {
        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    
        SHELLEXECUTEINFO shExecInfo;
        shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
        shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE;
        shExecInfo.hwnd = NULL;
        shExecInfo.lpVerb = L"open";
        shExecInfo.lpFile = L"cmd";
        shExecInfo.lpParameters = L"/c msiexec /fv path_to\\recache.msi";
        shExecInfo.lpDirectory = NULL;
        shExecInfo.nShow = SW_SHOW;
        shExecInfo.hInstApp = NULL;
        ShellExecuteEx(&shExecInfo);
        WaitForSingleObject(shExecInfo.hProcess, INFINITE);
    }
    
    #包括
    int main()
    {
    CoInitializeX(空,Conit_APARTMENTTHREADED | Conit_DISABLE_Ole1de);
    SHELLEXECUTEINFO-shExecInfo;
    shExecInfo.cbSize=sizeof(SHELLEXECUTEINFO);
    shExecInfo.fMask=SEE_MASK_NOCLOSEPROCESS| SEE_MASK_UNICODE;
    shExecInfo.hwnd=NULL;
    shExecInfo.lpVerb=L“打开”;
    shExecInfo.lpFile=L“cmd”;
    shExecInfo.lpParameters=L“/c msiexec/fv路径_至\\recache.msi”;
    shExecInfo.lpDirectory=NULL;
    shExecInfo.nShow=SW_SHOW;
    shExecInfo.hInstApp=NULL;
    ShellExecuteEx(&shExecInfo);
    WaitForSingleObject(shExecInfo.hProcess,无限);
    }
    
    2-像往常一样从项目中创建新的msi(使用新产品代码和更高版本号)

    将Wix捆绑包项目中的两个步骤结合起来,如下所示(有用链接):

    
    
    最后,通过调用以下命令生成捆绑包:

    candle.exe-ext-WixBalExtension-ext-wixutil扩展包.wxs

    light.exe-ext-WixBalExtension-ext-wixutil扩展包。wixobj


    请注意,捆绑包将具有.exe扩展名而不是msi。

    不幸的是,旧的卸载程序已被执行,但在主要升级之前,您可以先修补上一个。这非常有效,但您必须确保产品代码相同(可能是版本)。如果您有ProductID=“*”,请在注册表中查找ProductCode(例如,HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall)并找到它,然后临时将*更改为它。
    <?xml version="1.0" encoding="UTF-8"?>
    <Wix 
      xmlns="http://schemas.microsoft.com/wix/2006/wi"
      xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
      xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
    
      <Bundle 
        Name="your_name" 
        Version="1.0.0" 
        Manufacturer="your_organization" 
        UpgradeCode="your_uuid" 
        Copyright="your_copyright" 
        AboutUrl="your_url">
    
        <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLargeLicense">
          <bal:WixStandardBootstrapperApplication
            LicenseUrl=""
            LogoFile="your_logo"
            ShowVersion="yes"
            SuppressOptionsUI="yes"/>
        </BootstrapperApplicationRef>
    
        <!--Do registry search to find the current msi package version-->
        <util:RegistrySearch 
          Root="HKLM" 
          Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}"
          Value="Version"
          Variable="CurrentMsiPackageVersion"
          Result="value" 
          Win64="yes" />
    
        <Chain>
          <!--Do recaching only if the current version is the invalid one-->
          <ExePackage 
              Id="Patch" 
              SourceFile="MsiRecache.exe"
              Vital="yes"
              InstallCondition="(CurrentMsiPackageVersion="invalid_msi_version")">
    
              <Payload Name="recache.msi" SourceFile="relative_path_to\recache.msi"/>
          </ExePackage>
    
          <!--Launch new installation-->
          <MsiPackage 
            Id="your_id"
            SourceFile="your_setup.msi"
            DisplayInternalUI="yes"
            Vital="yes"/>
        </Chain>
      </Bundle>
    </Wix>