Wix在卸载时删除appdata文件夹

时间:2016-05-13 14:40:14

标签: wix windows-installer f#-fake

我正在使用Wix 3.11并尝试了许多不同的方法和方法,似乎无法弄清楚为什么Wix没有删除我的 ApplicationDataFolder 文件夹。在安装过程中,我在用户的 ApplicationDataFolder 位置创建了该文件夹。

我的应用程序使用日志记录并将其与目录中的其他一些内容一起存储。在卸载期间,应用程序文件夹中的所有内容都将被删除,但带有日志和其他文件的appdata文件夹保持不变。

我无法弄清楚为什么或我错过了什么。

WXS模板

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <Product Id="*" UpgradeCode="9e578e3d-0119-425c-8633-f54ffaaa4929" Name="@product.name@" Version="@product.version@" Manufacturer="@product.company@" Language="1033">
    <Package InstallerVersion="400" Compressed="yes" InstallScope="perMachine" Comments="@product.version@" Description="@product.description@"/>
    <Media Id="1" Cabinet="SomeApp.cab" EmbedCab="yes" />

    <!-- Installer Properties -->
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
    <PropertyRef Id="WIX_IS_NETFRAMEWORK_46_OR_LATER_INSTALLED"/>

    <!-- Installer Resources -->
    <Icon Id="ApplicationIcon" SourceFile="SomeApp 4\SomeApp 4_vista.ico"/>
    <Property Id="ARPPRODUCTICON" Value="ApplicationIcon" />

    <Property Id="INSTALLDIR">
        <RegistrySearch Key="SOFTWARE\Acme\SomeApp" 
                        Root="HKCU" Type="raw" 
                        Id="APPLICATIONFOLDER_REGSEARCH" Name="installation-path" />
    </Property>

    <WixVariable Id="WixUILicenseRtf" Value="SomeApp 4\license.rtf" />
    <WixVariable Id="WixUIBannerBmp" Value="WixUIBannerBmp.bmp" />
    <WixVariable Id="WixUIDialogBmp" Value="WixUIDialogBmp.bmp" />

    <!-- Check Existing Install -->
    <Upgrade Id="9e578e3d-0119-425c-8633-f54ffaaa4929">
        <UpgradeVersion Minimum="@product.version@" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
        <UpgradeVersion Minimum="0.0.0" Maximum="@product.version@" IncludeMinimum="yes" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED"/>   
    </Upgrade>
    <Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>

    <!-- Prerequisites -->
    <Condition Message="This application requires .NET Framework 4.6 or newer. Please install the .NET Framework then run this installer again.">
      <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_46_OR_LATER_INSTALLED]]>
    </Condition>

    <Condition Message="This application requires at least Windows 7 or Windows Server 2008 R2. Please upgrade your computer to a supported operating system and run this installer again.">
      <![CDATA[Installed OR (VersionNT >= 601)]]>
    </Condition>

    <!-- Define the directory structure -->
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="ProgramFiles">
        <Directory Id="INSTALLDIR" Name="@product.company@">
            @product.applicationfiles@
            @product.servicefiles@
        </Directory>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="@product.name@"/>
        <Directory Id="ServiceProgramsFolder" Name="@product.name@"/>
      </Directory>
      <Directory Id="DesktopFolder" Name="Desktop" /> 
      <Directory Id="LocalAppDataFolder">
        <Directory Id="ApplicationDataFolder" Name="Acme" />
      </Directory>            
    </Directory>

    <DirectoryRef Id="ApplicationProgramsFolder">
        <Component Id="ApplicationShortcut" Guid="1e578e4d-0229-425c-8633-f54ffaaa4901">
            <Shortcut Id="ApplicationStartMenuShortcut" 
                Name="SomeApp 4.6" 
                Description="@product.company@ @product.name@ @product.version@"
                Target="[INSTALLDIR]SomeApp 4\SomeApp.UserInterface.exe"
                WorkingDirectory="INSTALLDIR"
                Icon ="ApplicationIcon"/>       
            <Shortcut Id="ApplicationStartMenuShortcut2" 
                Name="SomeApp 4.6 (Multiple Instances)" 
                Description="@product.company@ @product.name@ @product.version@"
                Target="[INSTALLDIR]SomeApp 4\SomeApp.UserInterface.exe"
                Arguments="MultipleInstance=True"
                WorkingDirectory="INSTALLDIR"
                Icon ="ApplicationIcon"/>  
            <Shortcut Id="ApplicationStartMenuShortcut3" 
                Name="SomeApp 4.6 (Notifications)" 
                Description="@product.company@ @product.name@ @product.version@"
                Target="[INSTALLDIR]SomeApp 4\SomeApp.UserInterface.exe"
                Arguments="Notifications=True"
                WorkingDirectory="INSTALLDIR"
                Icon ="ApplicationIcon"/>                   
            <Shortcut Id="HelpStartMenuShortcut" 
                Name="SomeApp 4.6 Help" 
                Target="[INSTALLDIR]SomeApp 4\Documentation\SomeApp.chm"
                WorkingDirectory="INSTALLDIR"/>                 
            <Shortcut Id="UninstallProduct"             
                      Name="Uninstall SomeApp 4.6"
                      Target="[SystemFolder]msiexec.exe"
                      Arguments="/x [ProductCode]"
                      Description="Uninstall @product" />                    
            <Shortcut Id="desktopshortcut" 
                      Directory="DesktopFolder" 
                      Name="SomeApp 4.6" 
                      WorkingDirectory="INSTALLDIR" 
                      Target="[INSTALLDIR]SomeApp 4\SomeApp.UserInterface.exe" />
            <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
            <util:RemoveFolderEx On="uninstall" Property="ApplicationDataFolder" />                       
       </Component>
    </DirectoryRef>

    <DirectoryRef Id="ServiceProgramsFolder">
       <Component Id="ServiceShortcut" Guid="9e578e3d-0229-425c-8633-f54ffaaa4901">
            <Shortcut Id="ServiceStartMenuShortcut"
                Name="@product.name@ Reporting Service" 
                Description="@product.name@ Reporting Service"
                Target="[INSTALLDIR]Reporting\SomeApp.ReportingService.exe"
                WorkingDirectory="INSTALLDIR"
                Icon ="ApplicationIcon"/>
            <RemoveFolder Id="ServiceProgramsFolder" On="uninstall"/>                    
            <RegistryValue Root="HKCU" Key="Software\Microsoft\Acme\SomeApp" Name="service-installed" Type="integer" Value="1" KeyPath="yes"/>                   
       </Component>
    </DirectoryRef>   

    <DirectoryRef Id="INSTALLDIR">
        <Component Id="CleanupMainApplicationFolder" Guid="*">
            <RegistryValue Root="HKCU" Key="SOFTWARE\Acme\SomeApp" Name="installation-path" Type="string" Value="[INSTALLDIR]" KeyPath="yes" />
            <util:RemoveFolderEx On="uninstall" Property="INSTALLDIR" />                
            <util:RemoveFolderEx On="uninstall" Property="ApplicationDataFolder" />                
        </Component>
    </DirectoryRef>

    <!--  Feature: SomeApp Application -->            
    <Feature Id="Feature.Application"
                     Title="SomeApp 4 - Application"
                     Description="SomeApp is an asset management and maintenance application designed to optimize asset value and improve manufacturing productivity."
                     ConfigurableDirectory="INSTALLDIR"
                     Level="1"
                     AllowAdvertise="no">
                    @product.applicationcomponents@
                    <ComponentRef Id="ApplicationShortcut" />                    
                    <ComponentRef Id="CleanupMainApplicationFolder" />                    
    </Feature>

    <!--  Feature: Reporting Service -->
    <Feature Id="Feature.Service"
                     Title="SomeApp 4 - Reporting Service"
                     Description="This service generates and delivers reports that have been scheduled in the SomeApp Maintenance Management System."
                     ConfigurableDirectory="INSTALLDIR"
                     Level="3"
                     AllowAdvertise="no">
                    @product.servicecomponents@    
                    <ComponentRef Id="ServiceShortcut" />                    
        <Component Id="ReportingServiceInstaller" Guid="B72CAA3F-F2DB-48D2-90DD-061209AB2CE5" Directory="INSTALLDIR">
            <CreateFolder />
            <File Id="ReportingService.exe" Name="ReportingService.exe" KeyPath="yes" Source="@product.sourcedir@\Reporting\SomeApp.ReportingService.exe"/>
            <ServiceInstall Id="ReportingServiceInstaller"
                Type="ownProcess"
                Vital="yes"
                Name="SomeApp Reporting Service"                    
                DisplayName="SomeApp - Reporting Service"
                Description="This service generates and delivers reports that have been scheduled in the SomeApp Maintenance Management System."
                Start="auto"
                Account="NT AUTHORITY\LocalService"
                ErrorControl="ignore"
                Interactive="no" />
        </Component>     

    </Feature>

    <CustomAction Id="Cleanup_logfile" Directory="INSTALLDIR" 
    ExeCommand="cmd /C &quot;rmdir %LOCALAPPDATA%\Acme /s /q&quot;" 
    Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />

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

    <InstallExecuteSequence>
        <RemoveExistingProducts After="InstallValidate"/>
    </InstallExecuteSequence>   

    <UIRef Id="WixUI_FeatureTree" />
    <UI>
      <DialogRef Id="FilesInUse" />
      <DialogRef Id="MsiRMFilesInUse" />
      <!-- Add the GUI logic for installation -->
    </UI>
  </Product>
</Wix>

1 个答案:

答案 0 :(得分:2)

我有一个项目使用util:RemoveFolderEx,它正常工作。我能看到的唯一区别是我在运行时将属性显式设置为安装目录的值。我的猜测是“INSTALLDIR”和“ApplicationDataFolder”实际上不是属性,因为它们存储在msi的Directory表中而不是属性表中。 (使用ORCA检查)

尝试

<SetProperty Id='AcmeAppDataFolderToRemove' Value='[ApplicationDataFolder]' After='AppSearch'/>

然后将您的util:RemoveFolderEx更改为

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

看看是否有效。 (您可能需要使用Value ='ApplicationDataFolder'而[]不确定。)

<小时/>

为了回应你的编辑,我去看了一下RemoveFolderEx页面,这看起来很重要

  

实现RemoveFolderEx的自定义操作通过将临时行写入RemoveFile表来为您指定的根文件夹的每个子文件夹执行此操作。由于它可能会显着影响Windows Installer的文件成本核算,因此必须在CostInitialize标准操作之前写入临时行。遗憾的是,MSI不会在您的包中创建Directory层次结构的属性,直到稍后,在CostFinalize操作中。

我认为将其设置为目录可行但显然这些目录在RemoveFolderEx操作实际执行时还没有值。因此,当尝试解析属性或设置属性时,它们实际上只是空的。

我的安装程序所做的不同以及实际做的是我通过RegistrySearch获取我设置属性的值。

<Property Id="INSTALLDIR">
    <RegistrySearch 
        Id='InstallDirRegistrySearch' 
        Type='raw'
        Root='HKLM' 
        Key='SOFTWARE\$(var.OEMRegistryRootKeyName)' 
        Name='SDKPath' />
</Property>
<SetProperty Id='SDKFolderToRemove' Value='[INSTALLDIR]\$(var.OEMProduct) SDK' After='AppSearch'/>

所以我会尝试将appdata目录写入注册表项并通过注册表搜索将值传入属性,然后在removefolderex中使用该属性,您可能不需要setproperty,我只是因为我需要它INSTALLDIR下的文件夹,但在您的情况下,您可以将注册表项设置为正确的文件夹。