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_Installation_Windows Installer_Custom Action - Fatal编程技术网

卸载WiX时删除文件

卸载WiX时删除文件,wix,installation,windows-installer,custom-action,Wix,Installation,Windows Installer,Custom Action,卸载应用程序时,我希望将安装程序配置为删除原始安装后添加的所有文件。卸载程序似乎只从MSI文件中删除最初安装的目录和文件,并将以后添加的所有内容保留在应用程序文件夹中。换句话说,我想在卸载时清除目录。如何执行此操作?使用On=“卸载”。下面是一个例子: 更新 它没有100%起作用。它删除了这些文件,但是没有其他目录- 安装后创建的已删除。对此有何想法?——普里贝罗 不幸的是,Windows Installer不支持删除包含子目录的目录。在这种情况下,您必须求助于自定义操作。或者,如果您知道

卸载应用程序时,我希望将安装程序配置为删除原始安装后添加的所有文件。卸载程序似乎只从MSI文件中删除最初安装的目录和文件,并将以后添加的所有内容保留在应用程序文件夹中。换句话说,我想在卸载时清除目录。如何执行此操作?

使用On=“卸载”。下面是一个例子:


更新

它没有100%起作用。它删除了这些文件,但是没有其他目录- 安装后创建的已删除。对此有何想法?——普里贝罗


不幸的是,Windows Installer不支持删除包含子目录的目录。在这种情况下,您必须求助于自定义操作。或者,如果您知道子文件夹是什么,请创建一组RemoveFolder和RemoveFile元素。

为此,我只创建了一个自定义操作,以便在卸载时调用

WiX代码如下所示:


$InstallerCustomActions=2
$InstallerCustomActions=2
InstallerCustomActions.DLL中OnBeforeUninstall方法的代码如下所示(在VB中)

卸载前受保护的覆盖子项(ByVal将数据状态另存为System.Collections.IDictionary) MyBase.OnBeforeUninstall(保存状态) 尝试 Dim CommonAppData作为字符串=Me.Context.Parameters(“CommonAppData”) 如果CommonAppData.StartsWith(“\”)而不是CommonAppData.StartsWith(“\”),则 CommonAppData=“\”+CommonAppData 如果结束 Dim targetDir As String=Me.Context.Parameters(“targetDir”) 如果targetDir.StartsWith(“\”)而不是targetDir.StartsWith(“\”),则 targetDir=“\”+targetDir 如果结束 DeleteFile(“,targetDir)”从bin目录中删除 DeleteDirectory(“***”,“)”删除程序创建的任何额外目录 抓住 结束尝试 端接头 私有子删除文件(ByVal searchPattern作为字符串,ByVal deleteDir作为字符串) 尝试 在Directory.GetFiles(deleteDir,searchPattern)中将每个文件名作为字符串 File.Delete(文件名) 下一个 抓住 结束尝试 端接头 私有子DeleteDirectory(ByVal searchPattern作为字符串,ByVal deleteDir作为字符串) 尝试 对于Directory.GetDirectories(deleteDir,searchPattern)中的每个dirName作为字符串 Directory.Delete(dirName) 下一个 抓住 结束尝试 端接头
不是WIX专家,但可能的(更简单的)解决方案是运行WIX内置扩展的一部分吗

可以使用/S和/Q选项运行MS-DOS命令。


执行此任务的自定义操作很简单:


然后,您必须修改InstallExecuteSequence,正如许多地方记录的那样

更新: 对这种方法有疑问。结果是生成了一个自定义任务,但仍然认为这是一个可行的解决方案,但没有让细节发挥作用。

在WiX中使用Util扩展中的元素。

使用这种方法,所有的子目录也被删除(与之相反)。此元素将临时行添加到MSI数据库中的
RemoveFile
RemoveFolder
表中。

以下是@tronda建议的变体。我正在删除卸载期间由另一个自定义操作创建的文件“install.log”:

<Product>
    <CustomAction Id="Cleanup_logfile" Directory="INSTALLFOLDER"
    ExeCommand="cmd /C &quot;del install.log&quot;"
    Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />

    <InstallExecuteSequence>
      <Custom Action="Cleanup_logfile" Before="RemoveFiles" >
        REMOVE="ALL"
      </Custom>
    </InstallExecuteSequence>
</Product>

REMOVE=“全部”

据我所知,我不能使用“RemoveFile”,因为此文件是在安装后创建的,并且不是组件组的一部分。

这将是一个更完整的建议答案,对我来说,它100%有效:

<Fragment Id="FolderUninstall">
    <?define RegDir="SYSTEM\ControlSet001\services\[Manufacturer]:[ProductName]"?>
    <?define RegValueName="InstallDir"?>
    <Property Id="INSTALLFOLDER">
        <RegistrySearch Root="HKLM" Key="$(var.RegDir)" Type="raw" 
                  Id="APPLICATIONFOLDER_REGSEARCH" Name="$(var.RegValueName)" />
    </Property>

    <DirectoryRef Id='INSTALLFOLDER'>
        <Component Id="UninstallFolder" Guid="*">
            <CreateFolder Directory="INSTALLFOLDER"/>
            <util:RemoveFolderEx Property="INSTALLFOLDER" On="uninstall"/>
            <RemoveFolder Id="INSTALLFOLDER" On="uninstall"/>
            <RegistryValue Root="HKLM" Key="$(var.RegDir)" Name="$(var.RegValueName)" 
                    Type="string" Value="[INSTALLFOLDER]" KeyPath="yes"/>
        </Component>
    </DirectoryRef>
</Fragment>

在产品要素下:

<Feature Id="Uninstall">
    <ComponentRef Id="UninstallFolder" Primary="yes"/>
</Feature>

此方法使用卸载时要删除的文件夹的所需路径设置注册表值。
最后,INSTALLFOLDER和registry文件夹都将从系统中删除。请注意,注册表的路径可以位于其他配置单元和其他位置。

谢谢Pavel。然而,它并没有100%起作用。它删除了这些文件,但是没有删除任何附加目录(安装后创建的目录)。有什么想法吗?哦,这些目录下的文件都没有被删除。当你在主要升级时将文件(例如配置文件)保存在“MyAppFolder”中时,你会遇到这种方法的问题。升级将删除所有文件。您的代码是否可以在MyAppFolder中创建目录?当我在
之后添加目录时,编译失败
找到孤立组件“MyAppFolder”。
@PhilipRego请参阅CommonAppDataFolder文档。我喜欢此选项栏,因为安装程序中包含cmd.exe。当然,每台机器都会有它,您只需要使用DirectorySearch来查找它!:)不要这样做。1) 您正在将
cmd.exe
嵌入到安装程序中。2) 您正在脚本生成期间对系统进行更改3)没有回滚选项4)无法正确处理锁定的文件我怀疑从Windows安装分发文件是否合法。目前还不清楚它是否能在运行不同版本Windows的目标系统上运行。尚未分发任何文件。它使用安装在操作系统上的文件。我确实使用了此解决方案,并做了一些更改以删除整个目录:execomand=“cmd/C RD”[INSTALLFOLDER]“/s/q”@Dennis how to delete INSTALLFOLDER,在win 10上它会被删除,但在Windows server 2012上它不会被删除。这是一个很好的解决方案。谢谢我尝试了很多事情,没人会觉得有那么难
<CustomAction Id="DeleteFolder" BinaryKey="CommandPrompt" 
              ExeCommand='/c rmdir /S /Q "[CommonAppDataFolder]MyAppFolder\PurgeAppFolder"' 
              Execute="immediate" Return="check" />
<Product>
    <CustomAction Id="Cleanup_logfile" Directory="INSTALLFOLDER"
    ExeCommand="cmd /C &quot;del install.log&quot;"
    Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />

    <InstallExecuteSequence>
      <Custom Action="Cleanup_logfile" Before="RemoveFiles" >
        REMOVE="ALL"
      </Custom>
    </InstallExecuteSequence>
</Product>
<Fragment Id="FolderUninstall">
    <?define RegDir="SYSTEM\ControlSet001\services\[Manufacturer]:[ProductName]"?>
    <?define RegValueName="InstallDir"?>
    <Property Id="INSTALLFOLDER">
        <RegistrySearch Root="HKLM" Key="$(var.RegDir)" Type="raw" 
                  Id="APPLICATIONFOLDER_REGSEARCH" Name="$(var.RegValueName)" />
    </Property>

    <DirectoryRef Id='INSTALLFOLDER'>
        <Component Id="UninstallFolder" Guid="*">
            <CreateFolder Directory="INSTALLFOLDER"/>
            <util:RemoveFolderEx Property="INSTALLFOLDER" On="uninstall"/>
            <RemoveFolder Id="INSTALLFOLDER" On="uninstall"/>
            <RegistryValue Root="HKLM" Key="$(var.RegDir)" Name="$(var.RegValueName)" 
                    Type="string" Value="[INSTALLFOLDER]" KeyPath="yes"/>
        </Component>
    </DirectoryRef>
</Fragment>
<Feature Id="Uninstall">
    <ComponentRef Id="UninstallFolder" Primary="yes"/>
</Feature>