WiX / MSI动态添加CopyFile元素

时间:2015-12-25 16:00:08

标签: wix windows-installer file-copying

我是Windows编程中的菜鸟,但我必须创建一个棘手的MSI安装程序,通过WiX工具集安装插件。 安装程序应通过Windows注册表API检测运行所有已安装的特定软件版本及其插件目录。之后,它应该在一个单独的页面(对话框)上显示所有这些页面,并带有相应的复选框。用户应该选择他们希望插件安装到哪个版本。

我已经创建了一个自定义操作(在C ++中并将其放入MSI数据库中的DLL中),它与注册表API进行交互,然后遍历结果并将临时记录添加到数据库表中:

  • 添加路径属性以保留插件路径;
  • 将记录添加到CheckBox表中;
  • 为他们添加属性以保持其状态;
  • 为他们添加条件,而不是检查他们的属性状态并启用/禁用它们;
  • 根据州的情况添加事件以重置路径属性。

它在AppSearch之后运行

<InstallUISequence>
   <Custom Action="PopulateVersions" After="AppSearch">Not Installed</Custom>
</InstallUISequence>

然后单击“下一步”按钮(我知道它是一个错误的地方来执行此类操作)执行自定义操作,过滤掉活动属性路径获取第一个并执行SetTargetPath操作(它工作正常)。对于其余的操作,操作会将适当的临时记录插入:

  • DuplicateFile表,其中DestFolder是属性名称;
  • 组件表,复制原始组件中的所有字段值,将Component_Parent字段值设置为原始值;
  • 目录表。每个路径属性一个记录,Direcory_Parent是TARGETDIR;

它仅将插件安装到引用的第一个属性路径(已传递给SetTargetPath操作)。

很好......我添加了一些CopyFile元素,这些元素引用我的自定义属性(我声明了一些特性以防止由于未知属性导致的MSI构建错误)到WiX标记仅用于测试:

    <Property Id="PathProperty0" Value="{}"/>
    <Property Id="PathProperty1" Value="{}"/>
    <Property Id="PathProperty2" Value="{}"/>

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFiles64Folder">
        <Directory Id="INSTALLLOCATION" Name="MyPluginDir">
          <Component Id="PluginExt" Guid="C112184A-307C-5E15-994F-0DFDA9DD427E">
            <File Id="MyPlugin" Name="MyPlugin.dll" Source="MyPlugin.dll" Vital="yes" />
            <CopyFile Id="MyPlugin_Copy1" FileId="MyPlugin" DestinationProperty="PathProperty1"/>
            <CopyFile Id="MyPlugin_Copy2" FileId="MyPlugin" DestinationProperty="PathProperty2"/>
          </Component>
        </Directory>
      </Directory>
    </Directory>

现在ProgressDialog说&#34; {}&#34;是无效路径,但所有属性都设置为有效路径(我在调试中检查了这一点)! 在显示要求访问同一MSI文件的提升UAC提示后,似乎忘记或忽略所有临时数据库更改/属性更改。单击“安装”按钮(带有屏蔽图标)后会出现提示。可能它再次读取数据库并且没有找到任何更改,因为它们在内存或缓存中,我不知道。

我做错了什么或如何正确安装?恕我直言,我的实现过于复杂。我需要你的帮助。

2 个答案:

答案 0 :(得分:2)

我发现至少有两个错误:

  1. 您希望在运行时更改的路径的属性应为PUBLIC properties(即,其名称不得包含小写字母。此外,它们可能应列在{{3}中} property,您可以通过在源中使用或不使用值声明它们并指定SecureCustomProperties属性来确保。

  2. 您为与目录相关的属性指定的值实际上是{}。这是一个不寻常的值,很少是正确的。通常,您需要一个空字符串。例外情况是当您处于Secure上下文并且需要指定导致空字符串值的非空字符串时,例如属性设置Formatted。 wix源的ControlEvent元素不是这样的上下文。

  3. 我不确定您所描述的方法的完全复杂性(我无法完全考虑它),但我确实希望鼓励您以编程方式创建表格数据的一般方法让Windows Installer完成剩下的工作。这种方法非常重要,可以给出一个名称:Property

    根据半自定义操作的指导,您可能希望在InstallUISequence和InstallExecuteSequence中安排PopulateVersions操作(特别是一旦它使用RemoveFile执行清理),以确保安装,维护和静默删除全部获得正确的表格数据。

答案 1 :(得分:2)

我认为你让这个过于复杂。您可以使用一堆AddInVersionXXXX子功能创建AddIns功能,并在功能条件中使用AppSearch的结果,然后显示自定义设置对话框。

在我的IsWiX中,我做了类似的事情,除了我总是安装到检测到的每个版本。诀窍是如果目录属性没有值,CopyFile将优雅地跳过副本。这很简单,可以在这里看到:

http://iswix.codeplex.com/SourceControl/latest#main/Source/Installer/IsWiXNewAddInMM/IsWiXNewAddInMM.wxs