The beginning of this is a primer, there are tips and tricks at the end of this document. MSI Basics: =========== From the Wise Solutions Whitepaper. * Advertising - where an application appears to be installed but files are not actually on the system. It's not installed until activated by the user. * Publishing - refers to COM The whole thing is a big ass table. Here are the main ones to populate: Feature Feature Components Component Directory File Media Property Represent logical grouping of resources in an install. Features are what users typically turn on / off during a custom install. Examples are sample files, multiple language support etc. Features can be nested - Feature_Parent column specifies this relationship. Child features only get installed if parent is selected. Display column determines how feature is displayed, zero means it's not displayed. Odd values mean it's expanded, even mean it's not expanded in tree view. Level column assigns an integer - compres it to Install level, if it's less then Level Install then it's installed. InstallLevel is usually set by a complete, custom, or typical selection in a dialog. Components are smallest piece of an install - they include files, registry keys, shortcuts, and other resources. They can only be installed or uninstalled as a single unit Directory_ column is a foreign key that optionally specifies a directory to be configured at runtime KeyPath column represents critical file, reg key, or ODBC data source assigned to the component. If it is missing it will require Windows Installer to repair the entire component. Advertised shortcuts are assigned to component whose key path specifies target file for shortcut. Only Reference counts are kept on components rather than files. Each component is given a GUID in the ComponentID Column. Features are made up of several components. FeaturesComponents table is used to assign components to features. Components can be in multiple features but will of course be only installed once. Directory table contains a key column -> Directory_Parent and DefaultDir column. DefaultDir column holds name of a single subdirectory and Directory_Parent column specifies key to parent directory and directory structure is build from this recursive relationship. Directory names can be fucked up: source/destination directory names can contain short/long filename separated by | DefaultDir column can contain a colon separating target directory from source directory if they differ -> used to separate OS specific files such as: .:Win95 or .:WinNT [SourceDir]\MyApplication\Win95 [SourceDir]\MyApplication\WinNT File table contains information on version,size, and language for files to be installed. The sequence number is a critical column. This represents the order of the files in the cabinet files; for merge modules - these numbers must be sequential starting from one. File sequence numbers are related to LastSequence column in Media table. Media table specifies where source files are located during an install. To support advertising - there are serveral tables that represent classes, extensions, typelibs, Prog ids, App ids, vergs, and MIME types. These tables populate the registry during an advertised install so an advertised app that has a specific extension can be installed on demand. Properties and Conditions ========================= Properties ---------- Property table keeps information that allows conditional installs - things only happen if a property is set or something. Property values though are hard coded for a limit of 128 characters which isn't enough for a filepath. There are three types of properties: Private (not modifiable by user at runtime), Public (modifiable by commandline), and Restricted (like public but cannot be changed by user in a managed installation). Property types are differentiated through different capitalization. In order for a property to be passed to the server side it must be in all caps. Private properties which have lower case, are never passed through to the actual install execution. Therefore conditions that occur in Execute sequence can be based on private properties. On locked down machines, only restricted public prperties are seen in execute sequences. ProductCode - is the GUID for an entire product. Rerunning an install whose product code is already tracked will set the Installed property - this shows the maintenance or repair dialogs. [PropertyName] : To get at properties you can use this construct [PropertyName]. [#FileKey] : Another useful construct this expression is replaced at runtime by full path to the file whose key is referenced. Filekey expression is often used to set a registry key to point to a file whose location is not determined until installation. [!FileKey] : resolves to the short path name to a file - useful for registry references that require short filenames. Conditions ---------- Conditions evaluate to TRUE or FALSE. Properties based on Windows9X and Windows NT are set to TRUE depending on the OS. Condition syntax is SQL/BASIC like that handles operators, text strings, and integers. BEWARE: Properties are case sensitive. If property is not defined it will resolve to an empty string without warning. A ~ before an operator denotes a case insensitive compare. During an install a DLL can get the value of a condition using the API MsiEvaluateCondition. This function is useful for performing different actions based on the system state or user choices. User Interface ============== ------------------------------------------------------------------------------------ TIPS AND TRICKS ------------------------------------------------------------------------------------ How do I create a log file of my installation? For a specific setup Launch your setup with a command line like this: msixec.exe /i C:\Path\Your.msi /L*v C:\Your.log If you're using InstallShield's Setup.exe launcher, you can enter /L*v C:\Your.log in the CmdLine= entry of Setup.ini to force a log file to be created; starting with IPWI 2.03 environment variables are expanded, so you can use expressions like /L*v %TEMP%\Your.log. Other setup launchers support similar methods to specify command line arguments. If you launch the setup from the InstallShield IDE you can specify the logging options in the Project Settings dialog. Globally for all setups on a machine You can also globally turn on Windows Installer logging for a machine. To do this create the following registry entry: [HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer] "Logging"="voicewarmup" "Debug"=dword:00000007 This will generate log files named Msi*.log where * is a random number in the TEMP directory for each MSI based setup. The meaning of the flags in the value are documented in Microsoft knowledge base article Q223300. Note that you should use this only during the trouble shooting phase because it will have adverse effects on system performance and disk space. From: http://www.installsite.org/pages/en/msifaq/a/1022.htm ------------------------------------------------------------------------------------ (courtesy of Bill Blanke) if you have any custom actions at all you'll probably want to move RemoveExistingProducts as high up as Wise will let you (before it this will do the uninstall first then the otherwise MSI tries to do both at the same more efficient but if you custom action isn't savvy if you don't do anything screwy you can that took a bit of finding :-) but is endorsed by MS ------------------------------------------------------------------------------------ Registry Stuff: HKLM/Software/Microsoft/Windows/CurrentVersion/ShareDLLs HKLM/Software/Microsoft/Windows/CurrentVersion/Uninstall ------------------------------------------------------------------------------------ In MSI Script, MSI first runs User Interface, Execute Immediate prior to install. It then runs Execute Deferred after the installation is done. Well that's the theory. ------------------------------------------------------------------------------------ Starting a service after install (no reboot) Execute Program From Destination net.exe start servicename Default Directory Windows\System32 (StartServiceAfter) Set to Synchronus, Ignore exit. StartServiceAfter is just the name of the custom action ------------------------------------------------------------------------------------ This is for the sub sub minor numbor (1.1.1.100) -> 100 This is a modulo 256 issue. It shouldn't happen again until build 512 :-) Upgrading builds reports current installation is newer that the version you are attempting to install --------------------------------------------------------------------------------- WISE 5.2 SPECIFIC STUFF * Setting a version to a file. Setup Editor | File | Version (combo box) * INSTALLDIR1 resolves to the parent of INSTALLDIR * To not uninstall a specific component/registry Setup Editor | Components Right click the component at the top level. Select Details, and click on the "Leave installed on uninstall" checkbox. --------------------------------------------------------------------------------- Deleting a service: sc delete servicename http://www.tweakxp.com/tweak1976.aspx --------------------------------------------------------------------------------- Validating an install you can use: MsiVal2.exe --------------------------------------------------------------------------------- WinAPI MSI Stuff: MsiOpenDatabase MsiDatabaseOpenView MsiViewExecute and ...