You are on page 1of 20

Windows Installer (MSI) Tips and Notes

Just to add to the good (and bad, and terrible) MSI writing already out there, here are some tiny notes and tips that might be useful or interesting or amusing to somebody, somewhere.

Expanding properties at run time A oiding !ustom a!tions by using the "#ile tables #ixing up a failed uninstall #ile ersions s. $rodu!t%ersion Some property names (silly) Add or &emo e $rograms properties 'ogging swit!hes Merge modules and properties AppSear!hing 'aun!hing a bat!h file in a !ustom a!tion (Sorry, but)* +a,ing in entory of installed produ!ts, features, and !omponents S!ript !ustom a!tion notes -ommon property problems In estigating self"repair (.ow do I !reate a nested installation/* 0sing Spawn1ait2ialog 3bfus!ated MSI 4i!e to .a e

Expanding properties at run time


MSI database fields that use the Formatted data type !an ta,e expressions of the form [PropertyName], and the alue will be expanded at run time. +he 5expression6 doesn7t need to be the whole field8 for example, you !an put the following in a registry alue and the appropriate parts of the oddly phrased senten!e will be expanded at run time9

Installed to [INSTALLDIR] by [USERNAME] from account [LogonUser] at [Time] on [Date]

As with all things property"related, !apitali:ation (and spelling) matter. ;ou !an tell the data type of a field by loo,ing at the 1indows Installer help library topi! for the gi en table. +he topi! (&egistry +able* indi!ates that the 4ame and %alue fields use the #ormatted data type, whi!h means that property alues !ontained in those fields will be expanded. 3n the other hand, the 4ame and 2es!ription fields of the Short!ut table use other data types (#ilename and +ext), and therefore don7t expand properties. (See the topi! (#ormatted* for other expressions that will get expanded, su!h as 5<E4%=%A&6 for en ironment ariables and 5>56 and 5>66 for literal s?uare"bra!,et !hara!ters.) 1hile we7re on the sub@e!t, a field that uses the Identifier data type doesn7t need s?uare bra!,ets around it. #or example, the 2ir$roperty field of the &emo e#ile table a!!epts a dire!tory property su!h as App2ata#older, and does not ta,e bra!,ets.

A oiding !ustom a!tions "y using t#e $%ile ta"les


It has often been remar,ed that one should a oid using !ustom a!tions if a built"in table and a!tion will do. I7ll repeat the remar, in the hope that it will help9 2on7t use a !ustom a!tion if a built"in table and a!tion will do. #or example, my heart sin,s e ery time I see someone using %AS!ript !ustom a!tions and the #ileSystem3b@e!t to manipulate files, when three tables will handle many !ommon !ases9 the &emo e%ile table, the 'upli!ate%ile table, and the Mo e%ile table. +a,ing ea!h one in turn9 +he &emo e%ile table is where you spe!ify files that you want to remo e during uninstallation (most !ommon !ase), installation, or both. (In ea!h of these tables, and in fa!t most tables related to data transfer, the a!tion is tied to a !omponent. In this !ase, &emo e#ile re!ords are asso!iated with a !omponent, and the file is remo ed when the asso!iated !omponent is installed or uninstalled.) +he remo al o!!urs when the &emo e#iles a!tion runs, whi!h must be before Install#iles runs. #or example, suppose you ,now that on first laun!h, your produ!t will !reate a file !alled file=to=remo e.ext in the main program dire!tory, represented by the dire!tory property I4S+A''2I&. (+he main dire!tory property name might be different depending on the de elopment en ironment or help file you7re using.) 1indows Installer will normally err on the side of !aution during uninstallation and lea e behind any files it didn7t install, but to remo e the file at uninstallation time, you !an add a re!ord similar to the following to the &emo e#ile table. %ield name Sample alue #ileBey &emo eMy#ile -omponent= main=exe &emar(s arbitrary identifier for this re!ord pi!, a !omponent

#ile4ame

file=to=remo e.ext !an use wild!ards8 lea e blan, to remo e empty dire!tory8 won7t delete subdire!tories must be property with no bra!,ets8 !an7t be raw path that is, when !omponent (main=exe* is remo ed

2ir$roperty I4S+A''2I& InstallMode C

.a ing set this up, when you uninstall your produ!t, file=to=remo e.ext will be remo ed instead of being left behind. #or some reason, the &emo e&egistry table remo es extra registry information during installation but not uninstallation. +o remo e extra registry information during uninstallation, loo, into the hyphen (!* flag for the &egistry table. +he 'upli!ate%ile table is where you spe!ify files that you want to !opy, assuming you also installed the files with the #ile table. +he following example !opies file=to=!opy.ext to I4S+A''2I& with the new name newname.ext, assuming the main=exe !omponent has been sele!ted to be installed lo!ally. %ield name Sample alue #ileBey #ile= 2est4ame 2est#older -omponent= main=exe newname.ext I4S+A''2I& &emar(s pi!, one new name if you want one, blan, if you don7t property with no bra!,ets

2upli!ateMy#ile arbitrary identifier file=to=!opy.ext identifier from #ile table

+hese files are pro!essed by the 2upli!ate#iles a!tion, whi!h must o!!ur after Install#iles. +he Mo e%ile table is similar to the 2upli!ate#ile table, but the files that you want to mo e or !opy need not ha e been installed with the #ile table. +he files are mo ed when the Mo e#iles a!tion runs (before Install#iles), and will not be remo ed when the produ!t is remo ed.

%ixing up a )ailed uninstall


1indows Installer !a!hes a produ!t7s MSI database in the hidden dire!tory <1I42I& <>Installer, whi!h is how users !an uninstall without ha ing to put the -2 ba!, in. (In MSI Automation, Installer.$rodu!tInfo with !onstant 'o!al$a!,age will tell you where the !a!hed pa!,age is8 ditto MsiDet$rodu!tInfo with I4S+A''$&3$E&+;='3-A'$A-BADE.) Ay default, maintenan!e operations su!h as repairs use this !a!hed database, whi!h is why testing is easier if you uninstall an old ersion before installing a new one9 your !hanges in a new build will ordinarily not be a ailable be!ause they7re not in the !a!hed database.

+rouble arises if you ha e a !ustom a!tion that !rashes during uninstallation9 you !an7t @ust ma,e a new build without the error and run it, sin!e maintenan!e mode will !ontinue to use the !a!hed MSI database. (A !ommon beginner mista,e is not reali:ing that the same se?uen!es are used for both installation and uninstallation, and therefore a !ustom a!tion with no !ondition will run for installation, repairs, modifi!ations, and uninstallation. 4ot that you as,ed, but the !ondition Not Installed su!!eeds for a first"time installation, and &EM*+E,-A..- will wor, in the Exe!ute se?uen!e after Install%alidate to dete!t a !omplete uninstallation. Mind the !apitali:ation and ?uotation mar,s.) +o re"!a!he the MSI database so a subse?uent uninstallation will wor,, deploy the new build (with the error remo ed), setting the &EI4S+A''M32E property to in!lude the letter v, as in9
msie"ec #i $roduct msi REINSTALLM%DE&voums REINSTALL&ALL

+his is how minor upgrades are deployed, too, of !ourse. 3!!asionally you7ll hear suggestions to use the 1indows Installer -leanup 0tility or msi:ap, whi!h is o erdoing things, or to find and edit the !a!hed MSI database in the hidden Installer dire!tory, whi!h is @ust !ra:y.

%ile ersions s/ Produ!t+ersion


Ma@or upgrades in 1indows Installer use only the first three fields of the $rodu!t%ersion property9 the #ind&elated$rodu!ts a!tion won7t distinguish ersion E.C.F.G of a produ!t from ersion E.C.F.H. Some ta,e this to mean that file ersions in the #ile table are limited to three fields, whi!h isn7t the !ase. +he %ersion field of the #ile table uses the %ersion data type, des!ribed as xxx.xxx.xxx.xxx, where ea!h field is an integer from I through JHHFJ. +o demonstrate this, !reate a file !alled ersions.exe with ersion E.I.I.I and pla!e it in (say) -9>$rogram #iles>%ersions, and !reate another !opy with ersion E.I.I.E, adding it to an installer that installs it to that same dire!tory. If you !reate a log file with msie"ec #i 'ersion(test msi #L)' e'eryt*ing log, you !an sear!h for (file9* and find this (edited)9
MSI +s,- E"ecuting o$- .ile/o$y +SourceName&'ersions e"e0 DestName&'ersions e"e0 1ersion&1.0.0.10 , MSI +s,- .ile- /-23rogram .iles21ersions2'ersions e"e4 Overwrite4 5on6t $atc*4 Existing file is a lower version

3r I guess you !ould @ust ha e !he!,ed to see if the new file was installed. If MSI !onsidered the ersions identi!al, the log message would be (strange !apitali:ation and all)9

MSI +s,- .ile- /-23rogram .iles21ersions2'ersions e"e4 Won't Overwrite4 5on6t $atc*4 Existing file is of an equal version

Some property names


Shortest pri ate property names (G letters)

2ate +ime

Shortest publi! property name (H)

$A+-.

'ongest publi! property name (FC)

MSI04I4S+A''S0$E&SE2E2-3M$34E4+S

'ongest pri ate property name (FF)

Msi4+SuiteSmallAusiness&estri!ted

$roperties with triple letters


A'''E#A0'+ #I'EA'''E#A0'+ A&$I4S+A...3-A+I34 I4S+A...E%E' MSI2ISAA'EEE0I

Add or &emo e Programs properties


A 1indows Installer installation usually !reates a produ!t entry in the Add or &emo e $rograms list, similar to the following9

If you want to hide the &emo e button, set A&$43&EM3%E to E in the $roperty table or from the !ommand line. If you want to hide the -hange button, set A&$43M32I#; to E. (If you want to annoy users, set both properties to E.) ;ou !an suppress the whole entry by setting A&$S;S+EM-3M$34E4+ to E. Setting A&$S;S+EM-3M$34E4+ only hides the Add or &emo e $rograms entry8 it doesn7t suppress !reation of the information used to uninstall the produ!t. 'aun!hing the MSI a se!ond time still runs maintenan!e mode, and so forth. +o suppress !reation of the uninstall information, you !an remo e or (!ondition out* the a!tions &egister$rodu!t, &egister0ser, $ublish$rodu!t, and $ublish#eatures. +he following figure shows the properties that !ontrol display text in the Support Info panel. (3f !ourse, the %ersion field uses $rodu!t%ersion, and $rodu!t4ame shows up a !ouple of times.) +he hyperlin,ed manufa!turer name is ba!,ed by the 0&' in the A&$0&'I4#3AA30+ property.

If you lea e any of these properties undefined, the !orresponding line won7t be displayed in the Support Info panel. #or example, lea ing A&$.E'$+E'E$.34E unset !auses the Support

+elephone entry to be omitted. Moreo er, setting A&$43&E$AI& to E hides the (If this program is not wor,ing)* paragraph and the &epair button. 4ote that these A&$" properties ha e no effe!t on the maintenan!e"type dialog box usually displayed when a user laun!hes an installer a se!ond time or !li!,s -hange on the Add or &emo e $rograms panel.

+o modify this dialog box, modify the 2ialog"-ontrol"&adioAutton"whate er tables of your MSI database or use your en ironment7s graphi!al dialog editor.

.ogging swit!#es
+o be o erwhelmed by information about what an MSI installer is doing, run the following from a !ommand prompt9
msie"ec #i 3roductName msi #L)' e'eryt*ing log

In parti!ular, the 0 following the 1. swit!h spe!ifies to do erbose logging of e erything the installer does. +rouble isKwhi!h you ,now be!ause I telegraphed the pun!hlineKit7s often way more than you wanted. +he MSI help topi! (-ommand"'ine 3ptions* (or running msiexe! 12) lists other, more spe!ifi! swit!hes that !an follow 1.. In parti!ular, you !an log @ust the properties li,e this9
msie"ec #i $roduct msi /Lp $ro$erties log

+he output has @ust entries li,e this9

&&& Logging started- 7#7#7777 77-77-77 &&& 3ro$erty+S,- Dis83rom$t & [9] 3ro$erty+S,- U$grade/ode & :;;;;;;;;!;;;;!;;;;!;;;;!;;;;;;;;;;;;< 3ro$erty+S,- 3roductTo=eRegistered & 9 3ro$erty+S,- Sourcedir3roduct & :;;;;;;;;!;;;;!;;;;!;;;;!;;;;;;;;;;;;< many more 3ro$erty+/,- Dis83rom$t & [9] 3ro$erty+/,- U$grade/ode & :;;;;;;;;!;;;;!;;;;!;;;;!;;;;;;;;;;;;< 3ro$erty+/,- ALLUSERS & 9 3ro$erty+/,- 3rimary1olumeS$aceRemaining & 7 3ro$erty+/,- 3rimary1olumeS$aceRe>uired & 7 etc &&& Logging sto$$ed- 7#7#7777 77-77-77 &&&

$op ?ui:9 why do the !lient (-) properties appear after the ser er (S) properties/ And a tip9 to see what properties !hanged or appeared between the (-) and (S) sides, run a !ommand li,e this9
sort #?9@ $ro$erties log

+he output loo,s something li,e this9


3ro$erty+/,3ro$erty+S,3ro$erty+S,3ro$erty+S,Menu2 A/TI%N & INSTALL A/TI%N & INSTALL ADDL%/AL & .eatureName AdminTools.older & /-2Documents and Settings2All Users2Start

3rograms2Administrati'e Tools2 3ro$erty+/,- AdminTools.older & /-2Documents and Settings2username2Start Menu2 3rograms2Administrati'e Tools2 3ro$erty+S,- AdminUser & 9 3ro$erty+/,- AdminUser & 9

)and so on. Similarly, to display @ust information about a!tion starts, stops, and return alues, use 1.i. +he log starts something li,e this9
&&& Logging started- 7#7#7777 77-77-77 &&& Action start 77-77-77- INSTALL Action start 77-77-77- A$$Searc* Action ended 77-77-77- A$$Searc* Return 'alue 7 Action start 77-77-77- Launc*/onditions Action ended 77-77-77- Launc*/onditions Return 'alue 7 Action start 77-77-77- .indRelated3roducts Action ended 77-77-77- .indRelated3roducts Return 'alue 7 Action start 77-77-77- 1alidate3roductID Action ended 77-77-77- 1alidate3roductID Return 'alue 9 Action start 77-77-77- /ostInitialiAe Action ended 77-77-77- /ostInitialiAe Return 'alue 9 etc

+he MSI help topi! ('ogging of A!tion &eturn %alues* des!ribes what these return alues mean. I ha e no idea what the ! and u swit!hes do.

Merge modules and properties


As you ,now, you !an expand the alues of your MSI pa!,age7s propertiesKfor example, in registry or I4I dataKat run time using 5$rop4ame6 expressions. Something that7s a bit tri!,ier is to use the alues of properties that you7 e defined in a merge module. +he idea is that e ery merge module has a uni?ue identifier, whi!h is stored in the ModuleSignature table. (;ou !an stop reading if you !reate merge modules by hand8 this is useful only if your de elopment en ironment hides these details.) An identifier loo,s li,e ModuleName.HHHHHHHH_HHHH_HHHH_HHHH_HHHHHHHHHHHH, where the HHHH_etc. number is a D0I2 with the !urly bra!,ets remo ed and the hyphens repla!ed with unders!ores. Many primary ,eys in your merge module database (your MSM file) are de!orated with that .HHHH_etc. suffix, whi!h means that !omponent names, &egistry"table ,eys, and (the reason we7re tal,ing about this) $roperty"table and 2ire!tory"table ,eys ha e that ?uasi"D0I2 appended. #or example, suppose you ha e a property !alled ME&DE=M320'E=$&3$E&+; defined in your merge module pro@e!t. If you merge your merge module into a full MSI pa!,age and !reate a log file while deploying the MSI pa!,age, mixed in with the main MSI7s properties you7ll see entries that loo, li,e this9
3ro$erty+/,- 5indoBs.older & /-25IND%5S2 3ro$erty+/,- 5indoBs1olume & /-2 3ro$erty+/,- MERGE_MO !LE_"RO"ER#$.EEEEEEEE_EEEE_EEEE_EEEE_EEEEEEEEEEEE & msm $ro$erty 'alue 3ro$erty+/,- 1ersionNT & C79

+herefore, if you want to expand the alue of your merge module property at run time, you7ll need to use the 5$&3$.........=....=....=....=............6 format. Moreo er, if you see other log entries with that ,ind of suffix, the atta!hed item probably !omes from a merge module. 4ote that the de!orations go only one way9 if your merge module uses unde!orated 5$&3$4AME6 somewhere, the property (if there is one) from the !onsuming MSI pa!,age will be expanded normally.

AppSear!#ing
+he AppSear!h a!tion is typi!ally used to sear!h for a file on the target system, and populates the alue of a publi! property with the full path to the file if it exists. (AppSear!h !an also be used to read data from the registry or an I4I file in 51indows#older6, but it7s not really (sear!hing*.) A

re!ord in the AppSear!h table !ontains the name of the publi! property to be populated with the results, and the primary ,ey of a re!ord in the Signature table8 whi!h in turn !ontains the file name, along with an optional range of a!!eptable ersions, range of si:es, range of dates, and a language for the file. In addition, the 2r'o!ator tableKnot sure why it7s not the (2ir'o!ator* tableKspe!ifies the dire!tory and number of le els of its subdire!tories in whi!h to sear!h. +he AppSear!h table is pro!essed by the AppSear!h a!tion, whi!h o!!urs early in the 0I se?uen!e. (Also early in the Exe!ute se?uen!e, in !ase of a silent or other nonLfull 0I installation, but ne er mind that for now.) 4aturally, AppSear!h !an ta,e a while to exe!ute, so it7s a !ourtesy to display information about what7s ta,ing so long. +o handle this, s!hedule a modeless dialog in the 0ser Interfa!e se?uen!e before AppSear!h (in the 0I sample from the $latform S2B, the !orresponding dialog box is !alled ($repare2lg*). 3n this dialog box, you !an pla!e +ext !ontrols that subs!ribe to the A!tion+ext and A!tion2ata !ontrol e ents. #inally, in the A!tion+ext table, spe!ify appropriate alues for the AppSear!h a!tion. In the following figure, the AppSear!h re!ord in the A!tion+ext table has the text beginning (A!tion+ext says9* in the 2es!ription field, and the text beginning (A!tion2ata says9* in the +emplate field.

+he A!tion2ataM+emplate alue doesn7t add mu!h to itK@ust diplaying the property and signature namesKso nobody would blame you for lea ing it out.

.aun!#ing a "at!# )ile in a !ustom a!tion


+o laun!h a bat!h file from a !ustom a!tion, you !an7t @ust spe!ify the .bat file as the exe!utable to run8 instead, you !an laun!h !md.exe or !ommand.!om, depending on the platform, with the path to the bat!h file as an argument. Instead of hard"!oding the path to the !ommand pro!essor

Kwhi!h plenty of people seem to thin, is @ust fineKyou !an expand the -3MS$Een ironment ariable and laun!h the result. +here7s probably a better way, but a two"step pro!ess for laun!hing a bat!h file that you7re installing is9

-reate a +ype"HE (set a property) !ustom a!tion, with sour!e 3*MSPE3 and target [43*MSPE3]. It should be an immediate"mode !ustom a!tion that goes somewhere in the Exe!ute se?uen!e. 4ext, !reate a +ype"HI (laun!h an exe!utable whose path is in a property) a!tion with sour!e 3*MSPE3 and target 1! -[INSTA..'I&].aun!#Me/"at- (or whate er the path to the file is). +his should be a deferred a!tion (add EICG to the type), possibly without impersonation (add another CIGN, for a grand total of a!tion type FECC), s!heduled after Install#iles (sin!e it7s a file you7re installing).

$op ?ui:9 why !an7t we @ust get rid of the first a!tion and use 5<-3MS$E-6 in the sour!e of the se!ond a!tion/ As usual, to run the a!tions only during the initial installation, gi e the a!tions the !ondition Not Installed, or, better yet, use the 5ComponentName,6 type of !ondition. (At this point, I might as well admit that I don7t ,now an automati! way to hide the !ommand prompt window.) Beep in mind that you don7t need to laun!h a bat!h file to laun!h something that7s already in the form of an exe!utable. #or example, I7 e seen installers that laun!h a bat!h file @ust to run net.exe or attrib.exe. I7 e seen things you wouldn7t belie e.

7Sorry8 "ut9:
#irst in a series of notes about things that seem to be impossible (or ery diffi!ult, or really bad ideas) to do with MSI.

-an7t !hange the system i!on in the upper"left !orner of e ery dialog box9 . 'i,ewise (but less surprising), you !an7t !hange the i!on of an MSI file. Similarly, !an7t modify text in system messages displayed by msi.dll9 (Are you sure you want to uninstall this produ!t/*, (+he upgrade pat!h !annot be installed by the 1indows Installer ser i!e be!ause the program to be upgraded may be missing)*, and so on. If the message is in a window whose !aption reads (1indows Installer*, you7re probably stu!, with it. -an7t !hange the !ommand line that7s exe!uted when the user !li!,s -hange or &emo e in the Add or &emo e $rograms panel. (At least not without setting A&$S;S+EM-3M$34E4+ and !reating a dummy se!ond entry whose sole purpose in life is to !hange the !ommand line.)

-an7t spe!ify a $rodu!t%ersion alue that !ontains letters. See I-ECG. -an7t spe!ify an order for 'aun!h-onditions or AppSear!hes. (It7s not at all the same thing, but !an7t spe!ify the order in whi!h short!uts are displayed in the All $rograms menu8 but sear!h the world for (Menu3rder* for information about how to sort Start menu items alphabeti!ally.) -an7t spe!ify the order in whi!h features are installed8 or install one feature, perform a !ustom a!tion, then install another feature. +he #ile table does ha e a Se?uen!e field, but sin!e file transfer is handled by a single run of the Install#iles a!tion, you !an7t really get in the middle of it.

Ta(ing in entory o) installed produ!ts8 )eatures8 and !omponents


(Short ersion.) +hey7re not at all diffi!ult to find, but some often o erloo,ed MSI A$I fun!tions to enumerate what7s installed on a system9

1hat produ!ts are installed9 MsiEnumProducts or MsiEnumProductsEx (in %AS!ript, Installer.Products or Installer.ProductsEx) 1hat features are installed for a produ!t9 MsiEnumFeatures (Installer.Features) 1hat !omponents are installed9 MsiEnumComponents (Installer.Components)

$rodu!t and !omponent information9


Installed produ!t information (install lo!ation, date, ersion, that sort of thing)9 MsiGetProductInfo or MsiGetProductInfoEx (%AS!ript Installer.ProductInfo) Installed !omponent information9 MsiGetComponentPath (Installer.ComponentPath) Di en a !omponent, whi!h produ!ts use it9 MsiEnumClients (Installer.ComponentClients)

$rodu!t, feature, !omponent states (installed/ ad ertised/ et!.)9

MsiQueryProduct tate, MsiQueryFeature tate, MsiQueryComponent tate (Installer.Product tate!Feature tate!Component tate)

S!ript !ustom a!tion notes


0nsorted notes related to %AS!ript and JS!ript !ustom a!tions (assuming the world !an7t tal, you out of it)9

0se -reate3b@e!t, not 1S!ript.-reate3b@e!t.

0se Session.$roperty (or @ust plain $roperty) to get and set properties from a !ustom a!tion9
6 VBScript: Session 3ro$erty+DUSERNAMED, & D1alued /ustomerD 6 value must be a string Msg=o" D;ello0 D E Session 3ro$erty+DUSERNAMED,

#or 2ire!tory"table properties, use


Session Target3at*+D/aseSensiti'e3ro$ertyNameD,

Session.$roperty in a deferred !ustom a!tion re?uires use of -ustomA!tion2ata. If you want to !at!h the return alue from a s!ript fun!tion, the s!ript !ode must be stored in a file, and not in the -ustomA!tion table. S!ript !ustom a!tions !annot be run asyn!hronously. (I found this out only re!ently when I was experimenting with Spawn1ait2ialog, about whi!h more later.)

3ommon property pro"lems


#or MSI new!omers, a !ommon hurdle appears to be figuring out that property names are !ase" sensiti e, followed by figuring out what !apitali:ation to use. Most !ommon mista,es9

Installed, not I4S+A''E2 ;et INSTA..'I&, not Installdir or Install2ir &EM*+E (usu. in &EM3%EOPA''P to dete!t uninstallation), not &emo e TA&;ET'I&, not +arget2ir or +argetdir or et!.

If you !hoose the wrong !apitali:ation, MSI thin,s you7re ma,ing up a new property with an empty alue, meaning !onditions that use the erroneous names probably won7t e aluate the way you want them to. I-EGJ will help. And the most !ommon resolutions to (.ow !ome my property alue disappearedMwent ba!, to its default alue/*Ltype problems9

3nly the alues of publi! propertiesKthose with all"upper!ase names9 M;$&3$, not My$ropKare passed from the 0I se?uen!e to the Exe!ute se?uen!e, so use a publi! property in your 0I"se?uen!e a!tion or dialog box !ontrol if you want to use the alue to ma,e system !hanges using the &egistry table, Ini#ile table, and so on. 1hile you7re refle!ting on things, loo, into Se!ure-ustom$roperties. If you7re !alling MsiDet$roperty, ma,e sure the last argument (the alue"buffer"si:e ariable) is initiali:ed to a alue large enough to hold the property alue. If you7re !alling MsiDet$roperty multiple times, reset the buffer si:e before ea!h !all. As before, reading a property alue during deferred exe!ution (with Session.$roperty or MsiDet$roperty) re?uires use of -ustomA!tion2ata.

In estigating sel)$repair
Another !ommon ?uestion is, (1hy does 1indows Installer run e ery time I restart my systemMstart my appli!ation/* +his beha ior is part of the resiliency or self"repair feature of 1indows Installer. (+his ?uestion has been answered many times in many pla!es, but not with pi!tures.) 1hen MSI fails to find a resour!e it needs, it displays a !onfiguration dialog box similar to the following9

+o see details about the missing resour!e, open the E ent %iewer (-ontrol $anel Q Administrati e +ools)8 the details are in the Appli!ation se!tion.

+he details of the repair are the MsiInstaller entries in the Appli!ation se!tion of the e ent iewer.

2ouble"!li!,ing the warning e ent re eals the e ent properties8 the details of the e ent list the produ!t !ode, feature name, and !omponent !ode in ol ed, as well as the missing resour!e.

(A pre ious tip hinted at how to get more information about a produ!t or !omponent, gi en its D0I2.) I7m not aware of a way to disable self"repair, short of disabling ad ertised short!uts, extra!ted -3M information, Extension"table file asso!iations, et!. A follow"up ?uestion is how to log self"repair operations, sin!e there7s not an expli!it msiexe! !ommand to whi!h you !an add the M' swit!h. 3ne unin iting method is to set the system"wide 'ogging poli!y, whi!h !reates a debug log in the +emp folder for ea!h MSI operation. A somewhat less unin iting option is to set the system"wide 2ebug poli!y (to R), and then use 2ebug%iew from Sysinternals to iew the (li e* debug log.

7<ow do I !reate a nested installation2:


2on7t.

=sing SpawnWait'ialog
A !ommon re?uest for installation programs is to display a small modal dialog box while a lengthy a!tion is ta,ing pla!e (similar to SdShowMsg, for those familiar with InstallS!ript programming). +he nearest built"in e?ui alent in MSI is a dialog box triggered with the Spawn1ait2ialog !ontrol e ent, whi!h displays a modal dialog box until a spe!ified !ondition is true. #or example, suppose you ha e a button reading ($erform lengthy a!tion)* on one of your dialog boxes, and you want a dialog box similar to the following to be displayed while the a!tion is ta,ing pla!e9

;ou !an !reate this dialog using the 2ialog and -ontrol tables, the main point being to ma,e sure the dialog (!alled SpawnMe in the 2ialog table) has the modal attribute ( alue C) set.

#or this example, I7 e defined the lengthy a!tion to be an asyn!hronous 2'' a!tion, with the following implementation.
F$ragma comment+lib0 Dmsi libD, Finclude GBindoBs *H Finclude Gmsi *H Finclude Gmsi>uery *H UINT ((stdcall Lengt*yAction+MSI;ANDLE *Install, : Slee$+C777,4 ## G!! $ut long!running code *ere ## set $ro$erty t*at indicates t*e action is finis*ed MsiSet3ro$erty+*Install0 TEIT+DDone5it*Lengt*yActionD,0 TEIT+DID,,4 return ERR%R(SU//ESS4

<

4aturally, the !ode that ta,es a long time will ta,e the pla!e of the Sleep fun!tion abo e. (Someone on!e as,ed me for a way to slow down an installation program, whi!h is about the fifth"funniest installation"related ?uestion I7 e been as,ed.) As with all !ustom a!tion 2''s, you7ll probably want to use a .def file or the li,e to suppress name de!oration9
LI=RARJ 5aitT*enSet3ro$erty EI3%RTS Lengt*yAction

A good pla!e for this ,ind of helper 2'' is in the Ainary table. +he a!tion that !alls the 'engthyA!tion fun!tion from 1ait+henSet$roperty.dll has type ESF, asyn!hronous 2''. $redi!tably, in the -ustomA!tion table I7 e named the a!tion -all'engthyA!tion. +o tie e erything together, your ($erform lengthy a!tion)* button will ha e two !ontrol e ents9 one to laun!h the a!tion, one to spawn the wait dialog box while the a!tion is running. +he first one should be familiar9 a 2oA!tion !ontrol e ent with target -all'engthyA!tion and !ondition E. +he se!ond !ontrol e ent is a Spawn1ait2ialog !ontrol e ent, with argument SpawnMe (the name of the dialog to spawn) and !ondition 2one1ith'engthyA!tion (a !ondition indi!ating when the dialog is no longer needed, using the property defined in the 2'' a!tion !ode). 1hen running the pro@e!t, the initial dialog box might loo, as follows9

1hen the user !li!,s the big button, and 1hile the a!tion is running (that is, while 2one1ith'engthyA!tion is unset), the spawned dialog box appears o er the normal dialog box as follows9

3n!e the a!tion has finished (that is, on!e the !ondition 2one1ith'engthyA!tion is true8 that is, on!e the a!tion sets the 2one1ith'engthyA!tion property to any alue), the spawned dialog anishes, and the dialog box appears as it did in the first figure. -losing remar,s9

An ob ious refinement is to disable the big button after the a!tion has !ompleted8 otherwise, the button remains a!ti e, but the spawned dialog box will not appear again. (Easy pop ?ui:9 1hy not/) As you ,now, a!tions in the 0I se?uen!e should not ma,e system !hanges, but instead @ust ?uery the target system. #or a!tions in the Exe!ute se?uen!e, setting up A!tion+ext and A!tion2ata so that a des!ription and ti!,s appear on the progress dialog is the re!ommended approa!h.

*")us!ated MSI
+hough it !ould be argued MSI is obfus!ated enough.

A feature !alled (A''*/ A deferred a!tion !alled (-ustomA!tion2ata*/ A property !alled (4ot*/ $roperties !alled * and l, with alues E and PP/

Ni!e to <a e
A handful of gi:mos that are good to ha e around when you7re learning your way around9

A family of exe!utables with the same name and different ersions9 sample.exe ersion E.I.I.I, E.I.I.E, and E.I.I.E.E, for example, for experimenting with updates and o erwrite rules. An exe!utable that displays the !ommand line it was laun!hed with (using the Det-ommand'ine A$I fun!tion or pretty mu!h anything else), for experimenting with !ustom a!tions. An exe!utable that returns :ero and one that returns non:ero, to test those !ustom a!tion !he!,"return" alue options. #or bonus points, an exe!utable that tells you what a!!ount it7s running in, for testing deferred and immediate a!tions. (#ailing that, use $ro!ess Explorer or the li,e to see the a!!ount information, en ironment ariables, and so on.) A fa,e -3M ser er 2'' that displays a message box during 2ll&egisterSer er and 2ll0nregisterSer er, to show when self"registration is used during de elopment and deployment.

You might also like