无法删除其他安装程序安装的文件

时间:2013-04-12 13:17:10

标签: wix

我想:

  1. 创建目录。
  2. 运行另一个安装程序(而非MSI),将某些文件从第1点安装到目录中。
  3. 替换第2点安装的部分文件。
  4. 所有这些必须在我使用WiX(Windows Installer XML)帮助创建的安装下完成。

    下面是我的WiX文件的重要部分。问题是此安装不会替换我想要的文件。要删除文件,我使用带有Property属性的RemoveFile元素,因为这是除了在自定义操作中编写代码(我不想要)之外的唯一方法,以删除安装程序数据库中没有的文件。

    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder">
            <Directory Id="ManufacturerDirectory" Name="$(var.Manufacturer)">
                <Directory Id="ProductDirectory" Name="$(var.ProductName)">
                    <Directory Id="SubDirectory" Name="$(var.SubDirectoryName)">
                    </Directory>
                </Directory>
            </Directory>
        </Directory>
    </Directory>
    
    <!-- Create the directory at point 1. -->
    <Component
        Id="RemoveOldData" Guid="..."   KeyPath="yes" 
        Directory="ManufacturerDirectory">
        <CreateFolder Directory="ProductDirectory" />
    </Component>
    
    <!-- Following two components replace the file(s) (point 3). -->
    
    <Component
        Id="RemoveOldData" Guid="..."
        Directory="SubDirectory" KeyPath="yes"      
        >   
        <RemoveFile 
            Id="Remove_MyFile.exe" On="install"
            Property="SUBDIRECTORYPROPERTY" Name="MyFile.exe" />
    </Component>
    
    <Component
        Id="FilesToReplace" Guid="..."
        Directory="SubDirectory">
        <File 
            Id="MyFile.exe" Vital="yes" KeyPath="yes" DiskId="1"        
            Source="$(var.SourcePath)MyFile.exe" Name="MyFile.exe"
            />
    </Component>
    
    <Binary Id="WiseInstallation" SourceFile="$(var.WiseSourcePath)..." />
    
    <!-- Launch Wise installation at point 2. -->
    <CustomAction
        Id="LaunchWiseInstallation"
        BinaryKey="WiseInstallation"
        ExeCommand=""
        Return="check"
        Execute="deferred"
        Impersonate="yes" />
    
    <!-- Following custom action assigns a property.
    This needs to remove files that are not in the current installer database.
    To do it, the Property attribute of the RemoveFile element is needed. -->   
    <CustomAction
        Id="Assign_SUBDIRECTORYPROPERTY"
        Property="SUBDIRECTORYPROPERTY"
        Value="[SubDirectory]" />
    
    <InstallExecuteSequence>
        <Custom Action="Assign_SUBDIRECTORYPROPERTY" After="InstallInitialize" >
            NOT Installed</Custom>
        <Custom Action="LaunchWiseInstallation" After="CreateFolders" >
            NOT Installed</Custom>
        <RemoveFiles Sequence="3720"/>
        <RemoveFolders Sequence="3730"/>
    </InstallExecuteSequence>
    

    Orca的观点中的InstallExecuteSequence:

    • ValidateProductID 700
    • CostInitialize 800
    • FileCost 900
    • CostFinalize 1000
    • InstallValidate 1400
    • InstallInitialize 1500
    • Assign_SUBDIRECTORYPROPERTY 1501
    • ProcessComponents 1600
    • UnpublishFeatures 1800
    • RemoveRegistryValues 2600
    • RemoveShortcuts 3200
    • CreateFolders 3700
    • LaunchWiseInstallation 3701
    • RemoveFiles 3720
    • RemoveFolders 3730
    • InstallFiles 4000
    • CreateShortcuts 4500
    • WriteRegistryValues 5000
    • RegisterUser 6000
    • RegisterProduct 6100
    • PublishFeatures 6300
    • PublishProduct 6400
    • InstallFinalize 6600

    我还检查了安装日志文件:

    • SUBDIRECTORYPROPERTY属性分配得很好;
    • 正确遵循了InstallExecuteSequence;
    • 安装完成且没有错误。

    但是文件没有被删除或替换!

2 个答案:

答案 0 :(得分:1)

首先,MSI无法安装另一个MSI,因此#2中的安装包不能是MSI。如果不是,则安排启动其他安装包的自定义操作,如下所示:

<InstallExecuteSequence>
   <Custom Action='LaunchOtherInstaller' After='CreateFolders' />
</InstallExecuteSequence>

CreateFolders操作发生在InstallFiles操作之前,因此您的安装程序应该能够介入。

答案 1 :(得分:0)

首先,我意识到MSI不能直接删除其他安装程序安装的文件(MSI与否) - 它只适用于安装过程中数据库中提到的文件(即自己安装的文件或之前安装的文件)本身的版本)。但是通过自定义操作,它可以。因此,如果没有自定义操作,就无法实现第3点。所以正确的顺序可以是这样的:

<InstallExecuteSequence>
  <Custom 
    Action="LaunchWiseInstallation" 
    After="CreateFolders" 
    >
    NOT Installed
    </Custom>
  <Custom 
    Action="DeleteOldData" 
    After="LaunchWiseInstallation" 
    >
    NOT Installed
    </Custom>
</InstallExecuteSequence>

其中DeleteOldData是一个CustomAction元素,指向包含实际删除文件的自定义操作的DLL或.exe。可以提到的是,也许DeleteOldData自定义操作应该具有在脚本中运行的Execute =“deferred”属性,并且应该具有Impersonate =“yes”属性以避免UAC限制和文件访问。如果安装程序由具有高于LocalSystem预先版权的管理权限的用户运行,则后者为真。

RemoveFile标记只能用于MSI数据库中提到的文件 - 而不能用于随机文件。所以在这种情况下没用。