使 WIX 安装程序将文件放置在 AppData 中 [英] Make WIX installer place files in AppData

查看:18
本文介绍了使 WIX 安装程序将文件放置在 AppData 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为 windows 的以太坊客户端编写一个 dapp.为了使用户可以使用 dapp,我必须将特定文件放在 appdata 的文件夹中.所以我应该在 %appdata%ParityEthereumdappsmydappname 中放置一些文件.但我总是在使用 WIX 时遇到奇怪的错误,最后一个是

<块引用>

错误 93 ICE64:目录 dapp 在用户配置文件中但不在列在 RemoveFile 表中.

我有以下 myapp.wixproj

<?xml version="1.0" encoding="utf-8"?><Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><属性组><配置条件="'$(Configuration)' == ''">调试</Configuration><平台条件="'$(Platform)' == ''">x86</Platform><ProductVersion>3.10</ProductVersion><ProjectGuid>8beed2e4-8784-4cb5-8648-cdf55c5defe6</ProjectGuid><SchemaVersion>2.0</SchemaVersion><OutputName>FairsDapp</OutputName><OutputType>包</OutputType></属性组><PropertyGroup Condition="'$(Configuration)|$(Platform)' =='Debug|x86'"><OutputPath>bin$(Configuration)</OutputPath><IntermediateOutputPath>obj$(Configuration)</IntermediateOutputPath><DefineConstants>调试</DefineConstants></属性组><PropertyGroup Condition="'$(Configuration)|$(Platform)' =='Release|x86'"><OutputPath>bin$(Configuration)</OutputPath><IntermediateOutputPath>obj$(Configuration)</IntermediateOutputPath></属性组><属性组><DefineConstants>HarvestPath=dapp</DefineConstants></属性组><项目组><编译包含="Product.wxs"/><编译包含="Dapp.wxs"/></项目组><导入项目="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' "/><Import Project="$(MSBuildExtensionsPath32)MicrosoftWiXv3.xWix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)MicrosoftWiXv3.xWix.targets') "/><目标名称="EnsureWixToolsetInstalled" 条件="'$(WixTargetsImported)' !='true'"><Error Text="必须安装 WiX Toolset v3.11(或更新版本)构建工具才能构建此项目.要下载 WiX 工具集,请参阅 http://wixtoolset.org/releases/"/></目标><目标名称="BeforeBuild"><热目录DirectoryRefId="安装文件夹"输出文件="Dapp.wxs"目录="dapp"ComponentGroupName="SourceComponentGroup"ToolPath="$(WixToolPath)"PreprocessorVariable="var.HarvestPath"AutogenerateGuids="true"/></目标></项目>

并关注wxs:

<?xml version="1.0" encoding="UTF-8"?><蜡xmlns="http://schemas.microsoft.com/wix/2006/wi"><Product Id="*" Name="Dapp" Language="1049" Version="1.0.0.3" Manufacturer="Me" UpgradeCode="fb09dccc-6606-4b5d-8dcb-28146c28663a" Codepage="1251"><Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine"/><MediaTemplate EmbedCab="yes"/><Feature Id="ProductFeature" Title="FDapp" Level="1"><ComponentGroupRef Id="ProductComponents"/></功能></产品><片段><目录 ID="TARGETDIR" 名称="SourceDir"><目录 ID="AppDataFolder"><目录 ID="Parity"><目录 ID="dapps"><目录 ID="INSTALLFOLDER" Name="F2"></目录></目录></目录></目录></目录></片段><片段><ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"></ComponentGroup></片段></维克斯>

我发现我必须使用 heat 任务来创建正确的文件树,但现在我被简单的任务复制这些文件到用户机器上"所困.

解决方案

我不熟悉这种类型的应用程序(用于 windows 的以太坊客户端的 dapp) - 所以我担心建议必须是通用的.

每用户文件和注册表设置:通常,MSI 很难将文件部署到用户配置文件和 HKCU 设置.正如 Chris 指出的那样,它基本上只适用于安装 MSI 的用户,除非您主动添加构造以将文件复制到所有用户配置文件,即使这样它也有点笨重.

方法:我很久以前就这个主题写了一个很长的答案:从管理员配置文件中创建当前用户配置文件中的文件夹和文件(冗长而详尽,但没有任何自动解决方案).

<块引用>

首选方法:在涉及太多复杂性之前,最简单的方法通常是使用您的应用程序在第一次启动时为每个用户复制用户配置文件- 而不是使用安装程序来安装用户特定的文件.

这要求有一个单独的应用程序可执行文件来启动,通常是通过它自己的快捷方式 - 它可能不是?例如,它通常不适用于插件.

  • 方法 1:在每台机器上安装模板文件,然后将它们复制到每个机器上应用程序启动时用户的用户资料.

  • 方法 2:或者我喜欢直接从服务器下载文件或数据库并放入用户配置文件 - 也是在首次启动时.

应用更新?:有一些方法可以确保您可以重新复制文件(如果有)如下所述更改您的模板:http://forum.installsite.net/index.php?showtopic=21552(2019 年 2 月转换为 WayBack Machine 链接).

<小时>

错误:您报告的具体问题与需要针对每个用户的注册表项路径和针对用户配置文件位置的所有文件夹的 RemoveFolder 条目有关:

 <Directory Id="AppDataFolder"><目录 ID="Parity"><目录 ID="dapps"><目录 ID="INSTALLFOLDER" 名称="F2"><组件Guid="{77777777-7777-7777-7777-7777777777DD}" Feature="MainApplication"><RegistryKey Root="HKCU" Key="软件TestManufacturerTestApp"><RegistryValue Name="Flag" Value="1" Type="string" KeyPath="yes"/></注册表键><RemoveFolder Id="RemoveINSTALLFOLDER" Directory="INSTALLFOLDER" On="uninstall"/><RemoveFolder Id="RemoveParity" Directory="Parity" On="uninstall"/><RemoveFolder Id="Removedapps" Directory="dapps" On="uninstall"/><文件来源="Test.exe"/></组件></目录></目录>

<块引用>

这只是 MSI 的惯例和怪癖之一.如前所述,每台机器安装所有文件并将它们复制到用户配置文件应用程序.它将从任何设置中解开它们未来的干扰.那么你就不需要处理这些 RemoveFolder 问题了.

<小时>

I'm writing a dapp for ethereum client for windows. In order to make dapp available for user I have to place specific files in the folder in appdata. So I just should place some files in %appdata%ParityEthereumdappsmydappname. But I always get weird errors with WIX, the last one is

Error 93 ICE64: The directory dapp is in the user profile but is not listed in the RemoveFile table.

I have following myapp.wixproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.10</ProductVersion>
    <ProjectGuid>8beed2e4-8784-4cb5-8648-cdf55c5defe6</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>FairsDapp</OutputName>
    <OutputType>Package</OutputType>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin$(Configuration)</OutputPath>
    <IntermediateOutputPath>obj$(Configuration)</IntermediateOutputPath>
    <DefineConstants>Debug</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin$(Configuration)</OutputPath>
    <IntermediateOutputPath>obj$(Configuration)</IntermediateOutputPath>
  </PropertyGroup>
  <PropertyGroup>
    <DefineConstants>HarvestPath=dapp</DefineConstants>
  </PropertyGroup>      
  <ItemGroup>
    <Compile Include="Product.wxs" />
    <Compile Include="Dapp.wxs" />
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
  <Import Project="$(MSBuildExtensionsPath32)MicrosoftWiXv3.xWix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)MicrosoftWiXv3.xWix.targets') " />
  <Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
    <Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
  </Target>
  <Target Name="BeforeBuild">
  <HeatDirectory
    DirectoryRefId="INSTALLFOLDER"
    OutputFile="Dapp.wxs"
    Directory="dapp"
    ComponentGroupName="SourceComponentGroup"
    ToolPath="$(WixToolPath)"
    PreprocessorVariable="var.HarvestPath"
    AutogenerateGuids="true" />
  </Target>
</Project>

And following wxs:

<?xml version="1.0" encoding="UTF-8"?>
<Wix
    xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="Dapp" Language="1049" Version="1.0.0.3" Manufacturer="Me" UpgradeCode="fb09dccc-6606-4b5d-8dcb-28146c28663a" Codepage="1251">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
        <MediaTemplate EmbedCab="yes"/>
        <Feature Id="ProductFeature" Title="FDapp" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>
    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="AppDataFolder">
                <Directory Id="Parity">
                    <Directory Id="dapps">
                        <Directory Id="INSTALLFOLDER" Name="F2"></Directory>
                    </Directory>
                </Directory>
            </Directory>
        </Directory>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"></ComponentGroup>
    </Fragment>
</Wix>

I found that I have to use heat task to create a correct files tree, but now I'm stuck with simple task "copy these files on user machine".

解决方案

I am unfamiliar with this type of application (dapp for ethereum client for windows) - so the advice has to be generic I am afraid.

Per-User Files & Registry Settings: In general deploying files to the user profile and HKCU settings is difficult with MSI. As Chris points out it basically just works for the user installing the MSI, unless you actively add constructs to get files copied to all user profiles, and even then it is sort of clunky.

Approaches: I wrote a long answer a long time ago on the subject: Create folder and file on Current user profile, from Admin Profile (long and elaborate, but without any automagic solutions).

Preferred Approach: Before getting involved in too much complexity, the easiest approach is generally to use your application to copy the userprofile files in place for every user on first launch - instead of using the setup to install user-specific files.

This requires that there is a separate application executable to launch, generally via its own shortcut - which it might not be? It generally does not work for addins for example.

  • Approach 1: Install template files per-machine and then copy them to each user's userprofile on application launch.

  • Approach 2: Alternatively I like to download files directly from a server or database and put in the userprofile - also on first launch.

Apply Updates?: There are ways to ensure that you can re-copy files if there are changes to your templates as described here: http://forum.installsite.net/index.php?showtopic=21552 (Feb 2019 converted to WayBack Machine link).


Errors: The specific problem you report has to do with the need for a per-user registry key path and a RemoveFolder entry for all folders targeting userprofile locations:

  <Directory Id="AppDataFolder">
    <Directory Id="Parity">
      <Directory Id="dapps">
        <Directory Id="INSTALLFOLDER" Name="F2">
          <Component Guid="{77777777-7777-7777-7777-7777777777DD}" Feature="MainApplication">

            <RegistryKey Root="HKCU" Key="SoftwareTestManufacturerTestApp">
              <RegistryValue Name="Flag" Value="1" Type="string" KeyPath="yes" />
            </RegistryKey>

            <RemoveFolder Id="RemoveINSTALLFOLDER" Directory="INSTALLFOLDER" On="uninstall" />
            <RemoveFolder Id="RemoveParity" Directory="Parity" On="uninstall" />
            <RemoveFolder Id="Removedapps" Directory="dapps" On="uninstall" />

            <File Source="Test.exe" />
          </Component>
        </Directory>
      </Directory>

This is just one of MSI's conventions and quirks. As already stated, install all files per-machine and copy them to the userprofile with the application instead. It will dis-entangle them from any setup interference in the future. Then you do not need to deal with these RemoveFolder issues.


这篇关于使 WIX 安装程序将文件放置在 AppData 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆