Windows 安装程序在卸载时未删除所有文件

Windows Installer not deleting all files on uninstall

我在这里看到了一些类似的问题,但是 none 给出的解决方案非常清楚或对我有用。

我有一个安装程序(使用 WiX 创建)可以安装某些文件和文件夹。但是,当 运行 安装的应用程序时,这会创建一些文件夹并将一些文件复制到其中。卸载时不会删除这些文件和文件夹。

到目前为止已编辑以显示代码:

这个安装目录 属性:

<Property Id="INSTALLDIR">
        <RegistrySearch Id='Registry' Type='raw' Root='HKLM' Key='Software$(var.Manufacturer)$(var.ProductName)' Name='Location' />
    </Property>

应在注册表中设置安装位置的此组件:

<Component Id="Registry" Guid="*">
                    <RegistryKey Root="HKMU" Key="Software$(var.Manufacturer)$(var.ProductName)">
                        <RegistryValue  Name="Location" 
                                        Type="string" 
                                        Value="[INSTALLDIR]" 
                                        Action="write" 
                                        KeyPath="yes" />
                    </RegistryKey>
                    <util:RemoveFolderEx On="uninstall" Property="INSTALLDIR" />
                </Component>

这确实在注册表中创建了一条记录,其中包含安装位置,但我不确定如何调整此代码以记录 'public' 目录并将其删除 - 我不知道在哪里util:RemoveFolderEx 应该去(在哪个组件内)

我见过的最清楚的教程是this one(除了它确实有一个明显的错误)。

替换此块:

<!-- 
  RemoveFolderEx requires that we "remember" the path for uninstall.
  Read the path value and set the APPLICATIONFOLDER property with the value.
-->
<Property Id="APPLICATIONFOLDER">
  <RegistrySearch Key="SOFTWARE$(var.Manufacturer)$(var.SkuName)" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="Path" />
</Property>

这个:

<!-- 
  RemoveFolderEx requires that we "remember" the path for uninstall.
  Read the path value and set the FOLDERTOREMOVE property with the value.
-->
<Property Id="FOLDERTOREMOVE">
  <RegistrySearch Key="SOFTWARE$(var.Manufacturer)$(var.SkuName)" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="Path" />
</Property>

和这个块:

<util:RemoveFolderEx On="uninstall" Property="APPLICATIONFOLDER" />

这个:

<util:RemoveFolderEx On="uninstall" Property="FOLDERTOREMOVE" />

你应该有一个工作测试。

给出了使用两个不同属性的原因 here and here(以及其他地方)。

如果您可以从您在安装过程中设置的其他值导出路径,Windows 安装程序将为您保留,例如 ARPINSTALLLOCATION,那么您可以调整上述实现以获得什么您无需创建自己的注册表项。

基于 B. Murri 的回答:

示例:您的应用程序在 'installdir/public' 中安装新文件或文件夹。这些文件没有被删除,因为它们不是由安装程序添加的。

首先,您需要创建一个注册表值,用于存储 public 目录的安装位置。这是为了防止用户更改安装目录。

<!-- Note that the RegistryValue Value is being set to the 'public' directory ID -->
<DirectoryRef Id='INSTALLDIR'>
        <Component Id="RemovePublicDir" Guid="your-guid-here">
            <RegistryKey Root="HKCU" Key="Software$(var.Manufacturer)$(var.ProductName)">
                <RegistryValue  Name="Location" 
                                Type="string" 
                                Value="[PUBLIC]" 
                                Action="write" 
                                KeyPath="yes" />
            </RegistryKey>
            <CreateFolder Directory="PUBLIC"/>
            <util:RemoveFolderEx Property="FINDPUBLICDIR" On="uninstall"/>
            <RemoveFolder Id="PUBLIC" On="uninstall"/>
        </Component>
    </DirectoryRef>

您现在需要添加一个 属性,稍后将搜索此注册表值。确保上面的 Root 值与下面的匹配:

<Property Id="FINDPUBLICDIR">
    <RegistrySearch Id='Registry' Type='raw' Root='HKCU' Key='Software$(var.Manufacturer)$(var.ProductName)' Name='Location' />
</Property>

将您的制造商名称和产品名称添加到变量中,如下所示:

<?define Manufacturer = "My Company"?>
<?define ProductName = "Test Application"?>

现在确保在功能标记中调用此组件:

<Feature Id="FeatureId">
    <ComponentRef Id="RemovePublicDir" />
</Feature>