Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
709 views
in Technique[技术] by (71.8m points)

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

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:PathToMyMsiMyMsi.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="....InstallerCustomActionsin$(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="....InstallerCustomActionsCustomActionsin$(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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...