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>
我在这里看到了一些类似的问题,但是 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>