About Windows Installer, the .NET Framework, and Visual Studio.
A recent project I worked on was to replace functionality for part of our patching process that runs commands after reboot, a task not too uncommon for installers - most notably because files were in use when the installers ran. Typically when files are in use installers such as Windows Installer and many proprietary installers will schedule a pending file rename, or PFR (also called a pending file rename operation, or PFRO). In Windows 9x/Me this is done by adding a DestinationFileName=SourceFileName pair to the [rename] section of the %WINDIR%\wininit.ini file. In Windows NT a similar key/value pair is added to the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations registry key, which is a protected key requiring, by default, administrative permission to write to it. The MoveFileEx function works with the link tracker in Windows NT and will schedule a PFR if necessary.
When commands must be run, for example, to NGEN assemblies such commands must be scheduled to run after reboot or performed on the temporary source files when possible. Under certain scenarios and to keep the assemblies in the %WINDIR%\Microsoft.NET\Framework\<Version> directory, the Global Assembly Cache (GAC), and the native image cache in parity, such commands must be handled after a reboot after the PFR is performed. Previously this was done by adding the commands (indirectly) to the RunOnce and Run registry keys.
The problem with this approach is that those registry keys require an interactive login before they are processed and - in Windows NT - the processes inherit the permissions and privileges (or lack thereof) of the interactive user. If the target of the operation is a protected store - like the GAC - administrative permissions are required. Under Windows 9x/Me this is not nearly as big a problem since everyone basically has full control on the system; but, for networked machines or Windows 9x/Me machines that have profiles enabled, an interactive login is still required when commands are scheduled in the RunOnce and Run registry keys.
To solve this problem, the RunServicesOnce and RunServices registry keys should be used under Windows 9x/Me. These are similar to the RunOnce and Run keys except that they are processed before a login is required. Under Windows NT a service that reads commands from a protected store - such as a registry key requiring administrative permissions for write access - could be used. Such a service should run with the least amount of privileges necessary. Service user accounts already exist which should meet your requirements; but, you can also install a service to run as a user who has the SE_SERVICE_LOGON_NAME account right, but then must securely prompt for their credentials which are passed as parameters to CreateService(). In the latter scenario silent installations may be difficult depending on the installation technology you use, and great care should be taken to not divulge or store any credentials which are obtained such as in an installation log file, event log, or install state data.
When its necessary to create a service to process commands independently of an interactive user, you are highly encouraged to create a threat model and to make sure that your solution is secure.
Using the ARPSYSTEMCOMPONENT Windows Installer property can leave your Add/Remove Program entries behind.
I am now facing an issue which i believe is very commonly encountered.
I need to launch an EXE at the end of the installation. I can use a custom action of type 19 to do it.
However, i just realized that the EXE depends upon the PATH environmental variable which is updated by the installer. Since the environment variable was not available when the msiexec process started, this environment variable is not available for use to the EXE.
To overcome this, we have the following options:
i)Run the exe after a reboot by making use of RunOnce keys
The user has to reboot the sytem after an install.
By creating an entry for this EXE in RunOnce, this exe will run upon a user logon sucessfully as the environment variables would be available to it.
Question: Is using RunOnce a recommended procedure to accomplish this?
ii)Make use of a vbscript custom action to launch the EXE.
iii)Broadcast a message to windows when the environment variable is updated
What is the recommended solution here?
Is RunOnce used by msi installers frequently?
@Kiran, if you really need to run an EXE at the end - and really think about whether you need to since setup is about copying bits and anything more complicates repairs, servicing, and other scenarios - you might consider writing a type 1 CA that will CreateProcess() after reading in the current environment block (there various APIs and other ways of getting it).