【问题标题】:WiX how to import/export data into C# Custom Action?WiX 如何将数据导入/导出到 C# 自定义操作中?
【发布时间】:2017-07-04 17:07:57
【问题描述】:

我需要:

  1. 从用户(从 UI)获取数据,并将该数据放入属性中
  2. 使用自定义操作将属性导入到某些 C# 代码中
  3. 对属性做一些事情(加密值),
  4. 将值返回导出到 WiX,我将在其中
  5. 创建一个注册表项并将加密的值放入其中

除了#4 之外,我可以完成该列表中的所有任务。也就是说,我似乎无法将 导出值导入 C# 代码。我认为问题出在时间上。

这是一个自定义操作的示例,用于将某些属性导入到某些 C# 代码中:

  <Property Id="VALUE" Value="value"/>
  <SetProperty Id="CustomAction_PassProperty"
               Value="VALUE=[VALUE]"
               Sequence="execute"
               Before="CustomAction_PassProperty"/> 

  <Binary Id="Binary_PassProps"
          SourceFile="$(var.CreateRegistryKey.TargetDir)CreateRegistryKey.CA.dll"/>

  <!-- Note that 'Impersonate="no"' elevates the privilege of the C# code, needed to create keys -->
  <CustomAction Id="CustomAction_PassProperty"
                BinaryKey="Binary_PassProps"
                DllEntry="CreateKeys"
                Execute="deferred"
                Impersonate="no"
                Return="check" 
                HideTarget="yes"/>

  <InstallExecuteSequence>
      <Custom Action="CustomAction_PassProperty"
              After="InstallInitialize"/>
  </InstallExecuteSequence>

请注意,该操作是在 InstallInitialize 之后完成的。

接下来,如何在 C# 代码中获取导入的属性并将其转换为变量:

    [CustomAction]
    public static ActionResult CreateKeys(Session session)
    {
        string value = session.CustomActionData["VALUE"];
        return ActionResult.Success;
    }

接下来,这是一个如何将 C# 代码中的变量作为属性导出回 WiX 的示例:

<Binary Id="Binary_CustomActionTemplate" 
        SourceFile="$(var.CustomAction.TargetDir)CustomAction.CA.dll"/>

<CustomAction Id="CustomAction_CustomActionTemplate" 
              BinaryKey="Binary_CustomActionTemplate" 
              DllEntry="CustomActionTemplate" 
              Execute="immediate" 
              Return="check"/>

<InstallUISequence>
    <Custom Action="CustomAction_CustomActionTemplate" After="LaunchConditions"/>
</InstallUISequence>

这一次动作是在LaunchConditions之后完成的。

最后,如何在 C# 中创建一个 Property,给它一个值,然后将它发送回 WiX:

    [CustomAction]
    public static ActionResult CreateKeys(Session session)
    {
        session["VALUE"] = "Hello, world.";
        return ActionResult.Success;
    }

我认为问题在于——即在安装过程中——我同时做两件事(导入和导出),但我不确定。也就是说,我需要将数据导入到 C# 代码中,在 C# 代码中做一些事情,然后 从 C# 代码中导出数据。 但是怎么做?!?对着天空戏剧性地挥手

总结一下:如何在WiX中将数据导入导出到C# Custom Action(使用相同的C#代码)?

【问题讨论】:

  • 我在我的答案中添加了一个替代选项,以防您已经阅读它并且没有看到编辑。答案有点乱对不起=]

标签: c# wix custom-action


【解决方案1】:

AFAIK 您不能在执行序列中更改一次属性值。如果我错了,有人可以纠正我,这将是您问题的替代答案。

您应该能够在安装的 UI 阶段加密属性。在您的immediate 自定义操作中,您可以使用session["PROPERTYNAME"] 而不是session.CustomActionData["PROPERTYNAME"] 访问msi 属性。您还可以设置属性:session["PROPERTYNAME"] = "new value string";

然后在添加信息的页面上的 Next/Install 控件上,您可以放置​​

<Control Id="Install" ...>
    <Publish Event="DoAction" Value="EncodeAndSetValuesAction">1</Publish>
    ....
</Control>

如果它们被标记为 Secure='yes' 和 public(全部大写名称),那么它们应该可以在安装的执行阶段使用编码值。

请注意,如果您使用 DoAction 控件事件(在用户输入值的页面上单击下一步)启动自定义操作,您将无法在 msi 日志中获取日志记录信息。请参阅here 了解更多信息。

小编辑:当您编辑问题时,我正在写这个答案,这表明您已经知道如何获取属性并立即进行设置。

或者,您可以只安排一个即时自定义操作来加密并在 InstallInitialize 之前(或在 WriteRegistryValues 之前或任何地方?)设置 InstallExecuteSequence 中的值,它会在安装的提升服务器部分开始。我认为 InstallExecuteSequence 发生在两个部分。它通过计算值和要安装的文件为安装的提升服务器部分制作安装脚本,它实际上复制文件并写入注册表项等。这部分仍然是客户端上下文,您可以在其中运行即时自定义操作和读取/设置属性。其次,它将使用设置的石头属性启动安装的服务器部分,并遵循刚刚创建的执行脚本。


我决定在这里也对立即和延迟自定义操作之间的区别进行简短的简化说明。

延迟自定义操作和立即自定义操作之间基本上有两个主要区别。即时自定义操作可以直接访问 msi DB 以读取和/或修改属性,但不能执行任何需要提升的操作,除非安装程序以“管理员身份”运行,因为它在用户的上下文中运行。

延迟操作只能在执行序列中运行,并且只能读取通过与操作同名的 CustomActionData 显式设置的属性值,但它们始终具有提升的权限。

【讨论】:

  • 这个问题其实源于this问题。我最初计划做的是从 UI 中获取属性并在 C# 代码本身中设置注册表。但是,我无法删除在卸载期间在 C# 代码中创建的注册表(而且我不想成为在用户注册表中留下随机垃圾的开发人员)。所以我想也许我会在 WiX 中重新设置注册表,然后在自定义操作中加密属性。
  • 话虽如此,事实是我不明白安装过程的顺序:如何让一些东西先于其他东西发生,等等。坦率地说,这种无知让你的“替代”建议很难供我解析,您对立即和延迟自定义操作之间差异的简短解释非常有用(谢谢!)。所以我要做的就是向我学习一些东西,重新阅读你的“替代”建议,然后试一试。
  • @Bob 微软的 Orca.exe 是一个很好的工具,可以用来进一步了解排序。您可以查看 InstallExecuteSequence 表并按“序列”对其进行排序,并查看所有操作(自定义和标准)将运行的顺序。执行序列中的立即与延迟有点奇怪,因为我认为所有直接的都首先运行,然后在第二遍中延迟的运行。这就是为什么我把“任何地方?”作为一个有效的排序,因为它应该在任何延迟操作之前运行。
  • 此外,您应该能够在延迟自定义操作中删除您创建的注册表项,该操作在“RemoveRegistryValues”之后排序,并确保条件为NOT UPGRADINGPRODUCTCODE AND Remove~="ALL"
  • 让我问你最初的建议。您的意思是我可能能够在 InstallUISequence 中执行加密自定义操作,对吗?然后去掉InstallExecuteSequence中的key?如果是这种情况,Publish 元素中的值 EncodeAndSetValues 是否是执行编码的自定义操作的 ID?另外,Publish 元素中的“1”有什么作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 2015-11-27
相关资源
最近更新 更多