【问题标题】:wix 3.7 set property based on script/logic/codewix 3.7 基于脚本/逻辑/代码设置属性
【发布时间】:2013-02-12 18:18:20
【问题描述】:

我们开发了一个非常全面的 wix 安装程序 msi 包,其中包括一些 10 多个 c# 自定义操作。

我的问题是我还没有弄清楚如何以编程方式“设置”属性。

基本上我想做的是将现有属性解析为新属性。

这种解析可以在 c# 中完成,但也可以在 RegEx、JavaScript 或 w/e 中完成。

但是,我无法通过我的 c# 自定义操作(“无法从非即时自定义操作访问会话详细信息”)执行此操作,并且据我所知,我只能更改类型 51 自定义操作的属性。但是类型 51 不能使用我的 c# 自定义操作。所以它的捕获 22。

谁能给我一个关于如何在 wix 中执行以下操作的示例: 使用一个属性的值执行正则表达式/字符串操作,并使用结果设置另一个。

在我看来,这应该是可能的,但经过大量搜索后,我仍然一无所知。

任何帮助将不胜感激。


编辑#1: 使用 wix 工作 3 年后,我仍然觉得自己像个业余爱好者,但这里是: 我认为发送属性并在自定义操作中使用它们的唯一方法是这种模式:

 <CustomAction Id="CA.SetCreateMessageQueueProperty"
                  Property="CA.CreateMessageQueue"
                  Value="MsmqData=.\Private$\[MYAPPLICATIONNAME]/ObservationReportingService.svc,Observation delivery queue"
                  Return="check"/>
    <CustomAction Id="CA.CreateMessageQueue" 
                  BinaryKey="BI.CA" 
                  DllEntry="CreateMessageQueue" 
                  Execute="deferred" 
                  Return="check"
                  Impersonate="no"/>
    <InstallExecuteSequence>
      <Custom Action="CA.SetCreateMessageQueueProperty"
              After="InstallFiles"/>
      <Custom Action="CA.CreateMessageQueue" After="CA.SetCreateMessageQueueProperty">
        <![CDATA[((&FE.Afs=3) AND NOT (!FE.Afs=3))]]>
      </Custom>
    </InstallExecuteSequence>

在自定义动作c#程序集中:

[CustomAction]
        public static ActionResult CreateMessageQueue(Session session)
        {
            return session.DoCustomAction("CreateMessageQueue",
                () =>
                    {
                        string msmqData = session.ExtractString("MsmqData");

                        //create actual message queue
                            }
                        }
                    });
        }

internal static ActionResult DoCustomAction(this Session session, string name, Action action)
        {
            session.Log("Begin " + name);
            session.Log("session.CustomActionData.Count:" + session.CustomActionData.Count);
            try
            {
                action.Invoke();
            }
            catch (Exception ex)
            {
                session.Log(string.Format("Exception: {0}\nInner Exception: {1}", ex, ex.InnerException));
                return ActionResult.Failure;
            }
            return ActionResult.Success;
        }

【问题讨论】:

  • 为什么真的需要延迟自定义操作?它们旨在执行环境更新,而不是属性的某些计算。如果我理解正确,应该在延迟脚本执行之前设置所有属性。

标签: regex string properties wix


【解决方案1】:

我认为您正在尝试在延迟自定义操作期间检索现有属性并将其分配给新属性。

<CustomAction Id="SetProperty" Return="check" Property="NameOfCustomActionYouAreUsingToRetrieveProperty" Value="[PROPERTY]"></CustomAction>

由于InstallExecuteSequence 中的延迟自定义操作无法访问安装程序属性,我们必须将该属性添加到CustomActionData

我用 C++ 编写了我的自定义操作,但我会发布代码,你会想到将其更改为 C# 代码。

extern "C" UINT __stdcall NameOfCustomActionYouAreUsingToRetrieveProperty(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
LPWSTR szValueBuf = NULL;

hr = WcaInitialize(hInstall, "NameOfCustomActionYouAreUsingToRetrieveProperty");
ExitOnFailure(hr, "Failed to initialize");

WcaLog(LOGMSG_STANDARD, "Initialized.");

hr = WcaGetProperty(L"CustomActionData",&szValueBuf);
ExitOnFailure(hr, "failed to get CustomActionData");

hr = MsiSetProperty(hInstall, "NEWPROPERTY",  szValueBuf);
ExitOnFailure(hr, "failed to set the new property");

LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);     
}

【讨论】:

    【解决方案2】:

    在 C# 中,您的代码如下所示:

    [CustomAction]
    public static ActionResult MyCustomAction(Session session)
    {
      string property = session["PROPERTYNAME"];
      session["PROPERTYNAME"] = "Look at me!";
      return ActionResult.Success;
    }
    

    session 对象可以访问安装数据库及其所有表。并且使用它的索引器,您可以获取和设置属性表中的任何属性。

    您还需要一个描述 .NET 运行时的小 .config 文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup>
        <supportedRuntime version="v2.0.50727"/>
      </startup>
    </configuration>
    

    比使用MsiGetPropertyMsiSetPropertyC++ alternative 干净得多。

    希望这会有所帮助。您可以在this WiX tutorial 中找到我刚刚写的所有内容,尤其是this page

    【讨论】:

    • 感谢您的帮助,先生,我已经尝试过了,结果出现“无法通过非即时自定义操作访问会话详细信息”错误。我想这与我如何从 wix xml 调用 CA 有关。不幸的是,由于恶意软件,您的网页在我公司的禁止列表中,所以当我到达那里时,我将不得不在家检查。 (我们公司的filter很过分,还封杀了Rob Menchings的博客一年)
    • @CasperLeonNielsen 您的自定义操作的 Execute 属性的值是多少?
    • 尊敬的先生。很抱歉一直悬而未决,我很难做出回应。我已经编辑了我的初始问题(Edit#1),显示了我如何调用我的所有自定义操作(例如创建消息队列)。有没有机会我可以让您编辑您的答案以向我展示 Wix xml 呼叫站点?
    • 并非所有这些都在 InstallExecute 序列中,但其余部分是我的代码的样板。
    • @CasperLeonNielsen 在这种情况下,您需要deferred custom action,正如 Natalie Carr 指出的那样。但是,我不明白为什么您需要推出延迟操作来设置属性。到那时,安装几乎完成;您不再有权访问安装数据库。最重要的是,您将无法访问 session 对象。延迟操作的目的是直接更改系统或调用另一个系统服务。我建议您立即采取行动。
    猜你喜欢
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    相关资源
    最近更新 更多