Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run SqlScript on custom condition #1668

Open
veselinoWiktor opened this issue Nov 2, 2024 · 6 comments
Open

Run SqlScript on custom condition #1668

veselinoWiktor opened this issue Nov 2, 2024 · 6 comments

Comments

@veselinoWiktor
Copy link

Hello,

I'm trying to run SqlScript, but only if my property SQLSCRIPT is set to True.
new SqlScript("db", "script_binary_id", ExecuteSql.OnInstall) { ComponentCondition = "SQLSCRIPT='True'" },
I've tried doing it with ComponentCondition, but it didn't solved the problem. Is there a way I can set custom condition like mine, and if the condition matches then the script gets executed?

@oleg-shilo
Copy link
Owner

I checked your code (see .\wix folder) and it generates the correct WiX
image

Your condition may not be set at the time of the execution.
You can test it but building the msi with hardcoded condition: new Property("SQLSCRIPT", "True"),

@veselinoWiktor
Copy link
Author

It's set for sure because when I click the checkbox and then click back I test it with pop up window that shows if the properties are set correctly
image

But in the .\wix folder the condition is set as a separate tag:

<Component Id="CreateUsers" Guid="615de02f-62d7-478a-b5c1-2b388f972b61" KeyPath="yes">
    <SqlScript Id="CreateUsers" BinaryKey="CreateUsers" ExecuteOnInstall="yes" SqlDb="db" xmlns="http://schemas.microsoft.com/wix/SqlExtension" />

    <Condition>SQLSCRIPT01=True</Condition>

    <CreateFolder />
</Component>

This is what the code that I added in the previous message generates me

@veselinoWiktor
Copy link
Author

I also tried adding FeatureCondition:
Feature featureA = new Feature("RunSqlScript01") { Condition = new FeatureCondition("SQLSCRIPT01='True'", 1) };
and then adding it to the SqlScript:
new SqlScript("db", featureA, "CreateUsers", ExecuteSql.OnInstall),

But then I get the following error:
ICE03: Bad conditional string; Table: Condition, Column: Condition, Key(s): RunSqlScript01_

And I have the current feature generated:

<Feature Id="RunSqlScript01_" Title="RunSqlScript01" Absent="allow" Level="1">
    <Condition Level="1"><![CDATA[SQLSCRIPT01='True']]></Condition>

    <ComponentRef Id="CreateUsers" />
    <ComponentRef Id="INETPUB" />
    <ComponentRef Id="MyWindowsVolume" />
    <ComponentRef Id="TARGETDIR" />
    <ComponentRef Id="some_component_id" />
    <ComponentRef Id="some_component_id" />
    <ComponentRef Id="some_component_id" />
</Feature>

@oleg-shilo
Copy link
Owner

But in the .\wix folder the condition is set as a separate tag...

That's odd. The wxs with the correct placement of the condition attribute I shared before, was generated from the SqlDatabase sample. I only added your condition to the code.

image

I suggest you check the example by yourself as the wrong placement of the condition can be the cause you are looking for. Though, the WiX compiler did not complain. Strange...

Note the current version of WiX v4-5 requires the condition to be an attribute and in v3 it is an element.

@veselinoWiktor
Copy link
Author

I'm using WiX v3. I've actually just find a way in which it works. I left the SqlScript element without ComponentCondition:
new SqlScript("db", "script_binary_id", ExecuteSql.OnInstall)

And when the .wxs file is generated I use the used the WixSourceGenerated event to replace the ComponentRef in the Feature Id="Complete" with subfeature:

project.WixSourceGenerated += document =>
{
    
    var el = document.Select("Wix/Product/Feature")
        .Elements().Where(el => el.GetAttribute("Id") == "<sql_script_binary_key>").First();
   
    el.ReplaceWith(XElement.Parse($@"<Feature` Id=""feature_script"" Title=""fscript" Description=""fscript"" Display=""hidden"" Level=""1"" >	                                                           
                                       <Condition Level=""0"">SQLSCRIPT=""False""</Condition>                          		                                                        
                                       <Condition Level=""1"">SQLSCRIPT=""True""</Condition>
                                       <ComponentRef Id=""{el.GetAttribute("Id")}"" />                                                  
                                     </Feature>"));
};

As a result from this .wxs:

<Feature Id="Complete" Title="Complete" Absent="allow" Level="1">
      <ComponentRef Id="<db_id>" /> // Db component ref
      <ComponentRef Id="<sql_script_binary_key>" /> // sql script binary key

      <ComponentRef Id="some_component_ref_id" />
      ........................................
</Feature>

Now I have this .wxs file and everyting is working:

<Feature Id="Complete" Title="Complete" Absent="allow" Level="1">
      <ComponentRef Id="db" /> // Db component ref

      <Feature Id="feature_script" Title="fscript" Description="fscript" Display="hidden" Level="1">
        <Condition Level="0"> SQLSCRIPT="False"</Condition>
        <Condition Level="1">SQLSCRIPT="True" </Condition>

        <ComponentRef Id="<sql_script_binary_key>" /> // sql script binary key

      </Feature>
      <ComponentRef Id="some_component_ref_id" />
      ........................................
</Feature>

This is working for me as I test it. Do you think there is a better way I can do this

@oleg-shilo
Copy link
Owner

No, the way you do it is quite OK. You need to apply a condition but since the direct entity (SQL script) does not support conditions then you have to apply it to its parent. Which parent? It's your call. Feature or Component both are OK.

I only suggest you do the subfeatures directly with WixSharp entities instead of XML injection. The same outcome but the code looks cleaner.

var binaries = new Feature("MyApp Binaries", "Application binaries", "FEATURE_INSTALL_PATH2");
var docs = new Feature("MyApp Documentation");
var docsLight = new Feature("MyApp Light Documentation");
var tuts = new Feature("MyApp Tutorial") { Condition = new FeatureCondition("SQLSCRIPT=\"False\"", level: 1) };
var test = new Feature("TEST");

docs.Add(tuts);
binaries.Add(docs);
binaries.Add(docsLight);

Have a look at the corresponding FeatureCondition sample

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants