Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Update Component Condition at Runtime


9 replies to this topic

DenMori

DenMori
  • Full Members
  • 38 posts

Posted 22 November 2005 - 21:47

I have been tasked with bringing an old IS7 InstallScript project up to IS11 Basic MSI. All is well except for one monkey wrench thrown my way:

To speed the execution of the old project, a SQL DB table was maintained of all SQL scripts in project and their date/time stamps, each script was evaluated to see if it was newer than the stored date, and only those scripts whose date > db table (or were not in the table at all) are run.

I have been asked to replicate this functionality (primarily because some of the scripts can take upwards of 10 minutes or longer to run). Here's what I've done so far:

1. In the Files view of each SQL Component, I have added the corresponding SQL script.

2. I have written a deferred custom action to cycle through the list of SQL files installed to a SCRIPTS directory and have created a property SKIP_NN (where NN is a number) to correspond to each, and I use MsiSetProperty to initialize it to being unset.

3. I am calling functions in an external DLL to query the SQL db and determine whether the script needs to be run. If FALSE, I use MsiSetProperty to set the value of SKIP_NN to a non-blank value. If TRUE, I do nothing.

4. I opened up a database view to get the Component Name corresponding to a SQL file from the File Table using MsiViewFetch, then close the view.

5. I then open another view to grab the corresponding row of the Component table using MsiViewFetch.

6. I want to set the Condition column of the row to be "Not SKIP_NN". So I did a call to MsiRecordSetString(hRec,5,"Not SKIP_NN").

7. I want to commit this change, so I call MsiViewModify. However, I get a ERROR_FUNCTION_FAILED coming from the call. I tried using MSIMODIFY_UPDATE, MSIMODIFY_REPLACE, and MSIMODIFY_ASSIGN as arguments without any luck.

Can anyone give me a clue as to where I'm going wrong here?? I really need to get past this so I can complete this project.

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 22 November 2005 - 22:00

You can only make temporary changes to the running database. But why do you need to set those component conditions? If you only need to condition the *execution* of those SQL script (and not the copying of the .sql file) you could evaluate the SKIP_NN properties in your custom action that executes the script.
Otherwise you can simply reference the property in your condition, such like:
[SKIP_NN] = 0
Note however that those SKIP_NN must be set before ConstFinalize, and you should set those components to transitive (reevaluate condition).

DenMori

DenMori
  • Full Members
  • 38 posts

Posted 22 November 2005 - 22:29

The custom action I have written does not actually run the SQL script (I let IS11 do that), it is there solely to dump the SQL scripts down to the target machine so I can evaluate the date/time stamp against the db's internal table to set the corresponding property value that the script's condition will test. So in a sense I am evaluating and setting the property value in the custom action.

The primary reason I was doing this was to automate the process (some of our packages have over 100 scripts, and I have been instructed (to put it mildly) that the installer should see if the script has been updated since the last time it was run in order to decide whether or not to run it), and part of me really didn't want to manually set up 100+ properties and conditions (this project has 60+)

I don't know how I can set this to run before CostFinalize if I won't know until the files are installed to do the test.

DenMori

DenMori
  • Full Members
  • 38 posts

Posted 23 November 2005 - 17:38

Based on what you described, here's what I did:

1. In the IDE, I set conditions on 5 of my 60+ scripts.
2. During my custom action, instead of trying to update the condition of the component, I read it in to get the property name I test against.
3. I set the property to a non-blank value using MsiSetProperty.

My question becomes: Is there any other action I need to take to ensure that the scripts I had to set the property value for do not get run?



DenMori

DenMori
  • Full Members
  • 38 posts

Posted 28 November 2005 - 16:46

Here's my status--If anyone can give me any help, it would be very much appreciated (the IS boards are having severe difficulty today with posts getting dropped)

As indicated earlier, I have a custom InstallScript deferred action scheduled after InstallFiles in the Execute sequence that reads my list of .sql files that have been copied down. It then cycles through the list to query the File table to find its associated Component ( call this Qry1). I then query the Component table using the Component name returned by Qry1 to get the Condition of the component (call this Qry2). I'm finding a couple of problems that I don't know if its just me or there's a bug somewhere

1. Many of my files are long file names, but I am only having a problem querying the file table with one of them. My query is SELECT * FROM `File` where `File`.`Filename` = 'myfilename.sql' or `File`.`FileName` = 'shortName|myfilename.sql'

This query returns no records, even though there is a record in the file table. What further complicates matters is that the shortfilename in the table is xxxx~1.sql, but when the sql files are broken out, the file name is xxxx~4.SQL

The file name in the File column matches my filename, so I tried adding "or `File`.`File` = 'myfilename.sql' in the query, but it still returns no records.

What am I screwing up???

2. I find that sometimes I cannot list out my column names in the sql statement without an Error being generated, even though I enclose the column names in ` marks to avoid reserved word hangups. If I use Select *, it works fine.



Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 30 November 2005 - 08:10

What happens if you only use
`File`.`FileName` = 'shortName|myfilename.sql'
without the
`File`.`Filename` = 'myfilename.sql' or
part?

Note that in the docs all SQL keywords are in upper case. I don't know if they are case sensitive but you may want to use WHERE and OR instead.

Not sure about your second problem. Can you post the failing string, and the error message?

DenMori

DenMori
  • Full Members
  • 38 posts

Posted 01 December 2005 - 22:58

OK, I got past the errors (I must have done something bizarre, I just don't know what!) and am now consistently retreiving my sql filenames and their associated components, pulling the name of the property used in the component condition, and using MsiSetProperty to set the property so that the condition will be satisfied.

I also made sure the Reevaluate Condition flag in the component view for the SQL scripts is set to Yes.

However, IS11 is ignoring this and running the SQL scripts anyway!!

Am I facing a Chicken and Egg situation here (the SQL Script won't extract out where I can examine it to see if the property value in its condition evaluates to FALSE unless I set the condition initially to TRUE)? It's almost as if the condition can only be evaluated prior to file examination


Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 02 December 2005 - 17:55

I mentioned before that component conditions are evaluated during CostFinalize. So I guess you will need to extract those files in a custom action to inspect their date. Or not use InstallShield's mechanism of using component condition for SQL scripts but instead create your own custom action to execute the scripts. This custom action could evaluate the conditions based on the file dates.

DenMori

DenMori
  • Full Members
  • 38 posts

Posted 02 December 2005 - 18:08

Well, I already have a custom action inspecting the script dates and setting the property, so it looks like I'll port the code over from the old project to actually run the scripts.

Since conditions are evaluated during costing, and costing happens before InstallFiles, this is the proverbial chicken and egg situation. What's aggravating is that IS help says that the Script condition is used in conjunction with the component state. Even if I set the component state to INSTALLSTATE_ABSENT, it doesn't have any effect because the ISSQL actions seem to not be re-evaulating the condition prior to firing the script.

I guess I'll have to write 60+ function calls to correctly dictate the order of execution of the scripts mad.gif

DenMori

DenMori
  • Full Members
  • 38 posts

Posted 05 December 2005 - 18:04

Well, its official..According to a couple of IS posters who responded to this question on the IS bulletin boards, the ISSQLServerInstall process is a deferred CA that can't access the MSI where I've got my properties. Instead it accesses some text file created by the ISSQLServerCosting CA, which invokes itself before I can perform the necessary tests.

So a word to the wise..IS11 SQL Script conditioning only works if the condition can be fully resolved as part of the normal costing process.