【问题标题】:Accessing a wix property value inside a deferred .net custom action在延迟的 .net 自定义操作中访问 wix 属性值
【发布时间】:2015-08-24 20:52:13
【问题描述】:

我有一个用 c# 编写的自定义操作,可以管理计划任务。 CA 使用 ScheduledTasks 表并基于this article。目前一切都很好,除了一件关键的事情:-)

我在使用此表的 ExeAction 列时遇到问题,该列应该代表计划任务要运行的 EXE 的完整路径和名称。安装程序运行时,会将 EXE 文件放到正确的目录中,并创建计划任务;但是,任务的 exe 操作始终包含在我的 .wix 文件中指定的文件的原始 ID(例如,[#fil489D713AB5785D45D8F9A2BC3ACD7847]),而不是我们正在安装的 EXE 的实际文件名。已创建任务的导出如下所示:

<Actions Context="Author">
    <Exec>
        <Command>[#fil489D713AB5785D45D8F9A2BC3ACD7847]</Command>
    </Exec>
</Actions>

这是我的 CA 的概要...

ScheduledTasks 表定义中的列定义:

<!-- Actions -->
<columnDefinition
  name="ExeAction"
  length="255"
  type="string"
  category="formatted"
  modularize="property"
  nullable="no"
  description="The path of the executable to run." />

在立即自定义操作方法中,安排在 InstallFiles 之后,我从行中提取 ExeAction 列,最终将值存储在会话中的 CustomActionData 实例中:

CustomActionData data = new CustomActionData();
CustomActionData details = new CustomActionData();

details["ExeAction"] = row["ExeAction"].ToString();
...
session["CreateScheduledTaskDeferred"] = data.ToString();

在延迟自定义操作方法中,在相应的即时自定义操作方法之后安排,我从会话中提取 ExeAction 值并将值传递给将创建计划任务的 ScheduledTasks 库:

string exeAction = details["ExeAction"];
task.Actions.Add(new ExecAction(exeAction));

计划任务自定义操作的用法如下在我的主 .wix 文件中:

<st:ScheduledTask
  Id="stask1F47C88A6951460CBE8973F741521206"
  ExeAction="[#fil489D713AB5785D45D8F9A2BC3ACD7847]"
  ... />

我尝试了以下方法:

  1. 在延迟的自定义操作中,跟踪提取的 ExeAction 的值。当我这样做时,该值正确显示为完整路径和 exe 名称!
  2. 在延迟的自定义操作中,提取 ExeAction 值,然后将其转换为 byte[],然后返回到存储在 convertExeAction 变量中的字符串的新实例。我跟踪了这​​个新的 convertExeAction 变量,发现它包含正确的完整路径和 exe 名称;但是,当我将此变量传递给我的计划任务库时,创建的任务仍然包含 [#fil489D713AB5785D45D8F9A2BC3ACD7847]!
  3. 为了排除计划任务库的问题,我改为将 ExeAction 值的内容写入延迟自定义操作方法内的随机文件中。输出包含 [#fil489D713AB5785D45D8F9A2BC3ACD7847]。

目前我不确定问题出在哪里。我试图浏览一些现有的 wix 扩展;但是,我找不到任何用 .Net 编写 CA 的地方。在指定可以包含属性的列时,这些扩展的 XML 表定义似乎使用了相同的 modulesize="property" 属性,这与我在这里所做的相匹配。

任何建议将不胜感激。

【问题讨论】:

    标签: wix


    【解决方案1】:

    事实证明,this SO answer 包含我需要的确切 sn-p。

    简而言之,我需要更改从表中提取 ExeAction 数据并将其传递给 session.Format 的即时 CA 方法,而不是直接将其传递给会话数据:

    details["ExeAction"] = session.Format(row["ExeAction"].ToString());
    

    Session.Format documentation

    请注意,我尝试在延迟 CA 方法中使用相同的方法,但收到“句柄无效”错误。我想有一种方法可以从此方法解析属性,因为对 session.Log 的调用能够做到这一点;但是,上述解决方案可以很好地满足我的需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      相关资源
      最近更新 更多