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

1

4

I’m currently working on a project where I am using Wix for the installer. My application is developed using .net core and having appsettings.json as a configuration file.

I would like to update the values on the appsettings.json with the values which passed as a parameter during command-line installation

For example, I am passing value 500 through parameter BUFFER.SIZE

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

To achieve this, I have defined property and custom action in Product.wxs as follow

 <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>

Here is my custom action

    [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;
        }           
    }

But, I am stuck here because I am not able to read the values inside the custom function. the log does not contain below string

  "size = 500"

But, I see values in log as follow.

   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

How do I read these values in custom action and update the appsettings.json

I tried to useComponent as follow but it's not executing post installation

  <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>

Confused!!

Update

This is how I am able to get the passed values in custom actions

Declare a property

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

Define the Binary

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

Define custom actions

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

Set up the installation sequence

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

Now, I am able to see the passed parameters in the log.

But, when I try to pass json file path, it fails

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


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

This fails.

Calloway answered 31/7, 2019 at 15:21 Comment(6)
Make sure to set Secure="yes" attribute for properties that should be used as command-line parameters. https://mcmap.net/q/104807/-wix-condition-properties-passed-from-command-line-don-39-t-workDilettantism
Also I would be surprised, if util:XmlFile works with JSON files.Dilettantism
@Dilettantism i better prefer updating app settings from custom actions. you can ignore util:XmlFileCalloway
@Dilettantism tried Secure="yes" but no luck. any sample can be provided for above requirement?Calloway
$(var.BasePath)\appsettings.json; Firstly has a ; at the end of it and I don't know what that will do. Secondly it looks like it might be pointing to the local path at build time and not the install path at runtime since you're using a $(var.BasePath) instead of [INSTALLDIR] or something like that. You can try running your install (installing or uninstalling) from the command line with /l*v log.txt to get a log file of your install or uninstall to see where it is crashing.Ruffo
great catch, let me check those. also, is it possible to help me with this? #57374335Calloway
R
3

You can't use session["BUFFER.SIZE"] in a deferred custom action.

To pass a property from the MSI into a deferred custom action you need to use another action to set the value and then read that value in your custom action using a slightly different mechanism.

On the wixtoolset page for custom action you'll see it has a special mention in the Property description pointing to this microsoft article which talks about how getting context in a deferred custom action works.

An important thing to note about the second action is that its property value must be an exact match to the deferred custom action's Id value.

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

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

then in your custom action you can access the value by changing your session["BUFFER.SIZE"] to be session.CustomActionData["BUFFER.SIZE"]

It might also be useful for you to know about [#FileId] which gets evaluated as the install location of a component's File using the File's Id value. Then you can pass in two values to your custom action by updating the Value in the SetGetParsValues custom action to be Value="BUFFER.SIZE=[BUFFER.SIZE];JsonFilePath=[#JsonFileId]". I'm not 100% sure doing [#JsonFileId] will work there so you can also just set a property value before that and use the property value in the Custom action's Value.

Ruffo answered 2/8, 2019 at 16:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.