如何使用在命令行安装期间作为参数传递的值从 wix 自定义操作更新 appsettings.json?

How to update appsettings.json from wix custom actions with the values passed as parameter during command line installation?

我目前正在开发一个项目,其中我使用 Wix 作为安装程序。我的应用程序是使用 .net core 开发的,并将 appsettings.json 作为配置文件。

我想用 command-line installation

期间作为参数传递的值更新 appsettings.json 上的值

例如,我通过参数 BUFFER.SIZE

传递值 500
msiexec.exe /i c:\PathToMyMsi\MyMsi.msi BUFFER.SIZE="500" /L*vx c:\PathToMyLog.txt

为了实现这一点,我在Product.wxs中定义了propertycustom action如下

 <Property Id="BUFFER.SIZE" />

 <Binary Id="GetParameters.CA" SourceFile="..\..\Installer\CustomActions\bin$(var.Configuration)\CustomActions.CA.dll" />
 <CustomAction Id="GetParValues" 
   BinaryKey="GetParameters.CA" 
   DllEntry="ConfigureBufferSize" 
   Execute="deferred" 
   Return="asyncWait" 
   Impersonate="no" />
 <InstallExecuteSequence>
    <Custom Action="GetParValues" After="InstallFiles"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>

这是我的自定义操作

    [CustomAction]
    public static ActionResult ConfigureBufferSize(Session session)
    {
        try
        {
            session.Log("Begin ConfigureBufferSize");

            string size = "size = "+ session["BUFFER.SIZE"];
            session.Log(size); // I do not see any log like "size = 50"

            session.Log("End ConfigureBufferSize");
            return ActionResult.Success;
        }
        catch (Exception e)
        {
            return ActionResult.Failure;
        }           
    }

但是,我被困在这里,因为我无法读取自定义函数中的值。日志不包含以下字符串

  "size = 500"

但是,我在日志中看到如下值。

   MSI (c) (D0:54) [10:47:06:515]: Command Line: BUFFER.SIZE=500 
   CURRENTDIRECTORY=50 CLIENTUILEVEL=0 CLIENTPROCESSID=17360 
   MSI (s) (84:DC) [10:47:19:361]: PROPERTY CHANGE: Adding BUFFER.SIZE property. Its value is '500'.
   Property(C): BUFFER.SIZE = 500

如何在自定义操作中读取这些值并更新 appsettings.json

我尝试按如下方式使用Component,但它没有执行post安装

  <Component Id="config" Guid="*">
    <File Id="appconfig" Source="$(var.BasePath)\appsettings.json" KeyPath="yes" Vital="yes"/>
    <util:XmlFile
      Id="_pathFormat_" File="$(var.BasePath)\appsettings.json"
      Action="setValue"
      Name="pathFormat" Value="[BUFFER.SIZE]"
      ElementPath="/ApplicationLog/BufferSize"
      Sequence='1' />
  </Component>

困惑!!

更新

这就是我在自定义操作中获取传递值的方法

声明一个属性

  <Property Id="BUFFER.SIZE"  Secure="yes"/>

定义二进制文件

   <Binary Id="CustomActionDLL" SourceFile="..\..\Installer\CustomActions\CustomActions\bin$(var.Configuration)\CustomActions.CA.dll" />

定义自定义操作

 <CustomAction Id="SetGetParsValues"
              Property="GetParsValues"
              Value="BUFFER.SIZE=[BUFFER.SIZE]"/>
<CustomAction Id="GetParsValues"
              BinaryKey="CustomActionDLL"
              DllEntry="ConfigureBufferSize"
              Execute="deferred"
              Return="check"
              Impersonate="no" /> 

设置安装顺序

  <InstallExecuteSequence>
    <Custom Action="GetParsValues" After="InstallFiles"><![CDATA[NOT Installed]]></Custom>
    <Custom Action="SetGetParsValues" Before="GetParsValues"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>

现在,我可以在日志中看到传递的参数。

但是,当我尝试传递 json 文件路径时,它失败了

     <Property Id="APPLICATION.PATH"  Secure="yes" Value="$(var.BasePath)\appsettings.json;"/>


 <CustomAction Id="SetFilePathID"
              Property="SetFilePath"
              Value="APPLICATION.PATH=[APPLICATION.PATH]"
              Return="check"/>

这失败了。

您不能在延迟的自定义操作中使用 session["BUFFER.SIZE"]

要将 属性 从 MSI 传递到延迟的自定义操作中,您需要使用另一个操作来设置值,然后使用稍微不同的机制在您的自定义操作中读取该值。

custom action you'll see it has a special mention in the Property description pointing to this microsoft article 的 wixtoolset 页面上讨论了如何在延迟的自定义操作中获取上下文。

关于第二个操作需要注意的重要一点是它的 属性 值必须与延迟的自定义操作的 ID 值完全匹配。

<CustomAction Id="SetGetParsValues" Property="GetParsValues" Value="BUFFER.SIZE=[BUFFER.SIZE]" />

<InstallExecuteSequence>
    <Custom Action="SetGetParsValues" Before="GetParsValues"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>

然后在您的自定义操作中,您可以通过将 session["BUFFER.SIZE"] 更改为 session.CustomActionData["BUFFER.SIZE"]

来访问该值

了解 [#FileId] 也可能对您有用,它使用文件的 Id 值评估为组件文件的安装位置。然后,您可以通过将 SetGetParsValues 自定义操作中的值更新为 Value="BUFFER.SIZE=[BUFFER.SIZE];JsonFilePath=[#JsonFileId]",将两个值传递给您的自定义操作。我不是 100% 确定 [#JsonFileId] 会在那里工作,所以你也可以在此之前设置一个 属性 值并在自定义操作的值中使用 属性 值。