The "SelfRegister" Command |
This command is used to perform self registration and unregistration similar to that performed by the "REGSVR32.EXE" program (which is used by default by this command).
The processing of the native "SelfReg" table is undocumented and since it also doesn't support per-user installations it is not used by this MAKEMSI command.
The "File" and "Files" commands both have a "SelfReg" parameter which will invoke this command without the need to know the file's key.
Both per-user and per-machine installation and uninstallation custom actions (so 4 in total for each command) are created in the "CustomAction" and "InstallExecuteSequence" tables. An executable may not support per user installation, not much can be done about that, the default uses "regsvr32.exe" with the "/n" and "/i:user" parameters, if your msi can't be installed per-user I suggest a launch condition check for this to abort the install if required.
This command takes these parameters:
Like all MSI identifiers it is case sensitive and if an unknown value is used the "MSI validation" step should generate an "ICE03" error with text similar to "Not a valid foreign key; Table: SelfReg, Column: File_, Key(s): SomeKey.DLL".
All unordered registrations occur before ordered ones and unregistrations occur after all ordered unregistrations.
You can also pass "next" to be ordered after any previously seen value.
If one of your registrations requires another registration to have already occurred then you must use the "order" parameter to ensure this ordering. You could use "Dependency Walker" to check for this as it shows dependent DLLs etc.
Error Handling |
Windows Installer detects errors (registration only) for unordered self registrations however by default this command uses "msiexec.exe" for ordered registrations and this does not allow errors to be detected (another one to thank Bill for...).
It is possible to configure this command to use other registration executables such as "REGSVR32.EXE" which does appear to return meaningful return codes allowing you to alter the custom action type to check for errors, this also has issues as even in "silent" mode it can display error dialogs!
Main Options |
Please see the "options for commands" section of the manual.
#define? SELFREG_REGISTER_BY_SEQ RegisterComPlus ;;All Ordered Registrations must be complete before this action #define? SELFREG_UNREGISTER_FROM_SEQ UnregisterComPlus ;;No ordered unregistration at or before here #define? SELFREG_ORDERED_CA_TYPE &H0C22 ;;Regsvr32.exe does return meaningful RC #define? SELFREG_ORDERED_CA_TYPE_PU &H0C22 ;;Regsvr32.exe does return meaningful RC #define? SELFREG_ORDERED_REXXEXP_REGISTRATION '"[SystemFolder]regsvr32.exe" /s "[#' || {$FileKeyVar} || ']"' #define? SELFREG_ORDERED_REXXEXP_UNREGISTRATION '"[SystemFolder]regsvr32.exe" /s /u "[#' || {$FileKeyVar} || ']"' #define? SELFREG_ORDERED_REXXEXP_REGISTRATION_PU '"[SystemFolder]regsvr32.exe" /s /n /i:user "[#' || {$FileKeyVar} || ']"' ;;Only "regsvr32.exe" will allow per-user installation... #define? SELFREG_ORDERED_REXXEXP_UNREGISTRATION_PU '"[SystemFolder]regsvr32.exe" /s /u /n /i:user "[#' || {$FileKeyVar} || ']"' ;;Only "regsvr32.exe" will allow per-user uninstallation... #define? SELFREG_ORDERED_KEY_PREFIX_REGISTRATION SelfReg.I.PM ;;Start of Custom Action Name (per-machine install) #define? SELFREG_ORDERED_KEY_PREFIX_UNREGISTRATION SelfReg.U.PM ;;Start of Custom Action Name (per-machine un-install) #define? SELFREG_ORDERED_KEY_PREFIX_REGISTRATION_PU SelfReg.I.PU ;;Start of Custom Action Name (per-user install) #define? SELFREG_ORDERED_KEY_PREFIX_UNREGISTRATION_PU SelfReg.U.PU ;;Start of Custom Action Name (per-user un-install)
EXAMPLE |
<$Component "SomeFiles" Create="Y" Directory_="INSTALLDIR"> ;--- Unordered ----------------------------------------------------------- <$File SOURCE="SomeDll.DLL" RowKey="SomeDLL.DLL" KeyPath="Y" EXLIST="MY_DDLS"> <$SelfRegister "SomeDLL.DLL"> ;;Not component specific - just keeping related items together ;--- We need these to occur in order ------------------------------------- <$File SOURCE="SomeDLLOther1.DLL" RowKey="SomeDLLOther1.DLL" EXLIST="MY_DDLS"> <$File SOURCE="SomeDLLOther2.DLL" RowKey="SomeDLLOther2.DLL" EXLIST="MY_DDLS"> <$SelfRegister "SomeDLLOther1.DLL" Order="next"> <$SelfRegister "SomeDLLOther2.DLL" Order="next"> ;--- We have some other DLLS we wish to pick up... ----------------------- <$Files "*.dll" EXLIST="MY_DDLS"> ;;All DLLS except those already handled. <$/Component>