/build/static/layout/Breadcrumb_cap_w.png

Blog Posts tagged with Windows Installer (MSI)

Ask a question

Active Setup Concept

One has to repackage applications that have no advertised entry points (like shortcuts) but they need to install files in user profile locations or some specific user configuration. Here's how I do it.
When deploying such applications, everything is installed in System Context and all the user specific files and configuration info are missing. Because the application has no advertised entry points, there is nothing that might trigger the installation for any user. So, what do we do in this case? How can we make sure that those user-specific files & configuration info will be installed?
This issue can be solved using Active Setup Concept which is as follows:

Using Active Setup registry keys.
These keys are used by Windows during the "just-in-time" setup process for user profiles. Windows creates a user profile for each new user and then runs the "just-in-time" setup process to finish configuring it.
The registry key "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components" drives this "just-in-time" setup process.

The "(Default)" entry stores the Application (or Component) Name, the "Version" entry stores the version of the application while the "StubPath" entry stores the command that needs to be executed by the "just-in-time" setup process.
During the "just-in-time" setup process, Windows reads all the entries in the "...Active Setup\Installed Components" tree and runs the commands stored in each "StubPath" key. If the "StubPath" entry is empty or missing, nothing is executed.


Each time a user logs in, Windows compares the
"HKLM\Software\Microsoft\Active Setup\Installed Components\[PRODUCTCODE]"
and
"HKCU\Software\Microsoft\Active Setup\Installed Components\[PRODUCTCODE]"
registry keys.
If the registry entries from HKCU do not exist or they have an inferior version number than those from HKLM, then the command stored in the "StubPath" entry is executed and the appropriate entries are created in HKCU.
One of the most elegant and simple solutions for repackaging and deploying applications that have no advertised entry points but require the installation of user files and registry keys is to include Active Setup registry keys in your package.
The only thing you need to do is add the appropriate entries in "HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\[ProductCode]"

Like you can see in the above screenshot you need to create just a few entries. The "StubPath" entry is extremely important and, if missing, nothing will be executed.
"StubPath" should have a string value such as "msiexec /fauvs {ProductCode} /qb".
After the package is deployed, when a user logs in, Windows will check the Active Setup registry entries and will notice that the application is not installed for the current user. In this case it will run the command line that will force the installation of the application for the user and all user files and registry keys will be installed in the appropriate locations. After that, Windows will generate the appropriate Active Setup registry entries for the installed application so the installation process won't be repeated at the next log in of the same user.

View comments (3)

Right-Click and Install Your MSI/MST with Verbose Log Without Using BAT or CMD

I have come to realize after reading from another blog, http://www.itninja.com/blog/view/easy-way-to-refer-to-an-msi-and-its-mst-via-bat-or-cmd-file and share this little REG file of mine which I have been using for quiet sometime.

Worth trying if you dont want to type everytime you need to install or uninstall with your MSI and MST. It can also create a verbose log on the same folder. Enjoy!

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Msi.Package\shell]
@="Open,Repair,Uninstall,Install_With_Verbose_Log,Uninstall_With_Verbose_Log,Install_With_Transforms"

[HKEY_CLASSES_ROOT\Msi.Package\shell\Install_With_Transforms]
@="Install with &TRANSFORMS (MSIName.MST)"

[HKEY_CLASSES_ROOT\Msi.Package\shell\Install_With_Transforms\command]
@="\"C:\\WINDOWS\\System32\\msiexec.exe\" /i \"%1\" TRANSFORMS=\"%1.MST\" /l*v \"%1Install.log\" /qb+"

[HKEY_CLASSES_ROOT\Msi.Package\shell\Install_With_Verbose_Log]
@="Install with &Verbose Log"

[HKEY_CLASSES_ROOT\Msi.Package\shell\Install_With_Verbose_Log\command]
@="\"C:\\WINDOWS\\System32\\msiexec.exe\" /i \"%1\" /l*v \"%1Install.log\" /qb+"

[HKEY_CLASSES_ROOT\Msi.Package\shell\Uninstall_With_Verbose_Log]
@="Uninstall with Verbose Log"

[HKEY_CLASSES_ROOT\Msi.Package\shell\Uninstall_With_Verbose_Log\command]
@="\"C:\\WINDOWS\\System32\\msiexec.exe\" /x \"%1\" /l*v \"%1Uninstall.log\" /qb+"

View comments (10)

Application Isolation for Windws Installer MSI

Application isolation keeps the applications protected from inadvertent overwrites by other applications if they are using only local resources and DLLs. Isolating an application with its support files ensures that your application always uses the version of shared files with which it was installed.  
 
Why isolate an application?
  1. Application isolation is one solution to component versioning conflicts, or DLL hell.
  2. Isolation reduces versioning conflicts by modifying an application so it always loads the versions of components – such as DLLs – with which it was originally developed and tested.
  3. Application isolation provides increased stability and reliability for applications because they are unaffected by changes caused by installation and ongoing maintenance of other applications on the system.
  4. Resolve incompatibilities between different versions of shared components.
  5. Reduce the complexity of the installation by storing COM activation data in a manifest instead of the registry.
  6. Insulate the application from changes to shared components.
How to isolate an application.

Application isolation can be performed using one of these two methods.
  • Assemblies and manifests
  • MSI isolated components

Assemblies and Manifests:

Application isolation using assemblies and manifests is the recommended isolation method for Windows XP. Assemblies are DLLs or other portable executable files that applications require to function, and manifests are XML files that describe either an isolated application or an application's assemblies. These assemblies and manifests provide the same end result as Windows Installer isolated components, but keep all information outside of the registry and do not require the components to be installed in the same folder as the application. This reduces the chance of errors after isolation resulting from how the application was written.

MSI Isolated Components:

Application isolation using Windows Installer isolated components is best applicable for Windows 98 SE, Me, and 2000. It can also be used on Windows XP, but using assemblies and manifests is the better solution. The isolated component method copies shared files (typically DLLs) into an application's folder instead of a shared location. The application then uses these files instead of global ones, preventing modifications made by other applications from affecting the shared files. As a result, the application always uses the versions of these files with which it was deployed.
When an application is isolated, any shared files are moved to an area specified during the package building. That area is normally the application directory. An Isolated Component table is populated with the information that the OS needs to find the redirection. The Isolated Component table is part of the Windows Installer database created during repackage creation. When the application is setup, a .local file is created from the Isolated Component table and directs the OS to search for the needed DLL files in the application directory.Disadvantages of .local(Isolated Component Method)
  • Only DLLs present in the same feature as the executable can be isolated using this method. If DLL is present in different feature then it needs to be moved to the main exe feature.
    • No self-repair functionality exists for isolated.DLL files in the application directory.
    • 16-bit applications cannot be isolated using .LOCAL isolation method.
    • Only DLLs present in the same feature as the executable can be isolated using this method. If DLL is present in different feature then it needs to be moved to the main exe feature.
Be the first to comment

A General Approach to Software Packaging – Starting from consistent installer analysis

The goal of this blog post is to provide people who need to provide silent installers for softwares with a general framework on how to approach this process. I often run into posts on IT-ninja, and Appdeploy before that, along the lines of ‘how to silently install this or that software’, that could easily be answered if the poster had a general approach to creating silent installations.. While I realise seasoned packagers will find alot (if not all) of this stuff to be trivial and self-evident, I still believe it has its value in teaching people a good packaging methodology.

I myself am what you might call a software packaging veteran, having been active in the field pretty much continuously for the past 9 years. During this time, like many of my colleagues, I’ve developed a standard approach in analysing installers. While posting this might cost me some much-coveted Ninja-points, I still think it might be appreciated :-)

This post will be mainly geared towards MSI packaging. While I am well aware of the advent of software virtualisation technologies like app-V, I still believe it worthwhile to focus on MSI in this post for a number of reasons:

  1. While some might deny this, MSI will be around for a while yet. There are still a number of inherent limitations to software virtualisation, specifically App-V,  that will make the use of (complementary) MSI packages necessary. Most notably I’m thinking about drivers, context menu’s  and yes, Office applications
  2. I absolutely believe in the future of App-V, but would like to stress that many of the principles of MSI packaging can and should be adhered to in App-V sequencing, even if a case could be made that App-V is more forgiving to ‘quick and dirty’ packaging, but that does not have to mean I like it…
  3. Continuing on the last point, MSI packaging will remain a more labor-intensive job when trying to build silent, customised installers.
  4. Even when building a virtualised package, a well built or customised MSI can be an easy starting point.

Generally speaking, when analysing an installer, 3 phases can be distinguished in the process:

  1. Analysing required customisations: What exactly is it that the customer wants the install to look like? Is it a pretty much standard install, or are heavy modifications required? One should always remember packaging is a customer-oriented activity, and the whole process should start with a detailed description of exactly how the customer wants the software to be installed.
  2. Analysing installation executables, keeping in mind the requirements from step 1: Now that we know what to change, what is the best way to implement this change? What is the core install source (MSI, Executable) and to what extent can the customisations easily be passed to these installers?
  3. Customising the installers with either install parameters or transforms

The focus of this blog post will be on step 2, and to a lesser extent on step 1. While I will give a couple pointers on how to customise efficiently, this is very case-by-case, and it is my belief that a consistent method of installer analysis will make this more streamlined as well.

 

ANALYSING INSTALLERS – IS THERE AN MSI TO BE FOUND?

As stated, we will always go looking for MSI’s, whether they ARE the actual source installer, or are CONTAINED within the installer executable. To this end it is always advisable, if the installer is not natively a (vendor) MSI, to run the installer exe, and keep an eye on the system during this installation. First step I take is to try and open the exe in WinRAR, it might just be a self-extracting archive, and the MSIs might be just that easy to find.. If that does not work run the installer with /? and pray for an extraction parameter that gives you an MSI, final action is to monitor the installing user’s %TEMP% and %APPDATA% folders while running the exe.  In about 95% of cases, if not more, any msi contained in the installer will be extracted here. If so, grab it!! If not, we move on…

 

REQUIRED CHANGES vs AVAILABLE PARAMETERS vs TIME CONSTRAINTS

We haven’t found an MSI… damn… now what? This is when we go looking for command line parameters to the installer. Keeping in mind the customisations we want I’d suggest doing the following:

-          Look at the package KB on IT-Ninja for a list of parameters. There might even be one to extract an MSI after all, although, if you got past the previous paragraph, this is usually not the case. Second stop is the vendor website. If neither provide parameters, we might be stuck repackaging the installer.

-          Now the choice becomes whether or not to snapshot the install and build an msi ourselves. This can be avoided if ALL the required changes can be leveraged through command-line parameters or simple enough script statements (copying settings files for example). To me snapshotting is still an option in this case, since you will get increased control of what the installation does to the target machine, but this is where TIME constraints come into play, since tailoring a snapshot MSI generally takes longer than collecting the required command-line parameters.

-          If all the above does not pan out, we’re basically stuck snapshotting the installation and creating our own MSI

So now we either have a simple enough set of command line parameters for the setup executable, or we will be working with an MSI, either of our own making or provided by the vendor. Let’s quickly run through some basic priciples for the latter case

 PLAYING NICE WITH MSI – BASIC PRINCIPLES

-          When changing vendor MSIs, ALWAYS use transforms!! Why, do you ask? Well, in order to be able to maintain the ability to call on the vendor for assistance when building the installer, you’ll always want to hold on to their core installer. Otherwise it will become too easy for them to say you ‘messed up’ their installer, and they won’t help you. I know it sounds silly, but it happens, trust me. Also a transform is the most easily revertible means of modifying the installer.

-          NEVER REPACKAGE AN MSI. For basically the same reason as above, and the added reason of being able to implement possible future patches. Repackaging an MSI is actually far worse than changing it without a transform, so beware!!

-          Change AS LITTLE AS POSSIBLE  in transforms. While tools like Adminstudio’s InstallTailor will show you what changes are made to the properties of an MSI during an install, I tend to consider this a starting point only. Often during install a number of properties in the MSI are changed that are not strictly needed. Try to filter these out and leave them alone.

-          Analyse the installer’s DIALOGS: in order to identify exactly which properties you want to change, it is often useful to look through the MSI’s Dialog and Control tables, trying to link textboxes, radiogroups etc to the specific properties they change. Good thing here is it can actually be done without access to a complete packaging IDE, using just Orca or InstedIt.

-          When snapshotting, CLEAN UP!!  Only include changes relevant to the application in question, take out everything else. This is also where good exclusion lists are paramount, as well as, I hate to say, experience. Learn to distinguish the gold from the rubble. When not sure, take a stepwise approach. Try to exclude something and see if the application still works, but make a backup just in case..

BEWARE THE SNEAKY SETUP

Another point  I’d like to make is you always want to be aware of the possibility that the setup that contained an MSI, might actually be doing more during the installation than just installing these MSI’s. If you ever run into problems just running the MSI(s) contained in a setup, be prepared to do a so-called GAP CAPTURE. The principle behind this is as follows:

1)      Install the vendor msi, with any transforms you made

2)      Start your snapshotting tool of choice

3)      Run the setup.exe over your MSI

4)      (Run the application for the first time, there might be some settings done here)

5)      Stop the capture and look at the result

This might allow you to detect a number of extra actions that sneaky setup did, that you were never aware of. Or some settings that are done by that pesky application at first startup, that you just did not capture in your snapshot. Generally speaking, including a first startup of the application while snapshotting is a good idea, though not always necessary.

DRIVERS

Many seem to fear these packages. Me, I like em…

My general advise would be to ask yourself 2 questions

1)      Do I need more than just the driver for a piece of software?? While often a load of extra stuff gets installed, you might just need a driver. If this is the case, just look through the sources of the installer for the INF and CAT files, and make a package (using DifxAPP) to install them. An excellent blog post on this can be found here: http://www.itninja.com/blog/view/driver-installation-from-an-msi-using-microsoft-difx

 

2)      Are the drivers signed?? If they are not, try to get a signed version off the vendor, or if that does not work, SIGN THEM YOURSELVES. In today’s desktop world it is just no longer viable to work with unsigned drivers. There is an excellent guide on ITNinja on how to selfsign drivers here:  http://www.itninja.com/question/guide-to-signing-unsigned-drivers

 

So, that’s about it. While there is undoubtedly a lot more to cover, I think this a good start. Further topics can afterall be covered in later posts

 

Kr,

PJ

View comments (4)

A General Approach to Software Packaging - Propagating user settings

The goal of this blog post is to provide an overview of the most common means of getting user settings in place for each user that starts an application. While it is in no way my intention to reiterate materials that are already available, I want to give an overview of choices.

I will stick to what might be called the Windows-Inherent options, so I will not go deeper into things like AppSense or Citrix User Profile Management.

 

USER SETTINGS – WHAT ARE WE TALKING ABOUT?

While I could spend a lot of time expanding on this topic, I like to remember that basically every windows application (and package) is made up of 2 things: files and/or registry keys. That’s it, nothing more, nothing less.

So when talking User Settings what we basically mean are

  • FILES in the locations on a machine that make up the user’s personal workspace, his profile to be exact. Specifically for packaging we’re talking about a user’s UserProfile and the ApplicationData that is contained within.
  • REGISTRY KEYS that go into the user-specific  registry hive, HKEY_CURRENT_USER or HKCU

 

SO WHAT’S THE PROBLEM WHEN GETTING THESE SETTINGS IN PLACE?

Usually when installing an application through MSI in a corporate environment, these installation are done ‘per-machine’ as opposed to the other option ‘per-user’

What this means is that all the application data is written in a way to allow every user on the target machine to use the application. MSI-technically this is linked to the ALLUSERS property, the value of which will determine the location where this data ends up.

However at time of installation (often done in LOCALSYSTEM context) it is not always possible to put all user-specific data in place, simply because not all users can be known at time of installation. While one could conceivably run through the file and registry locations for each user known on the machine at time of installation, and put the files and registry keys in place, what about new users that log in?

So a mechanism is needed to put this data in place for each specific user, either when they log on, or at the latest when they start up the application. In this post I will distinguish between 4 options:

  1. MSI advertisement: the most ‘core’ of the options in that it makes best use of the Windows Installer options available, this will propagate settings when the user starts the application
  2. Active Setup: A Windows mechanism (not Windows Installer) that allows execution of commands when a user logs on
  3. MSI repair: often used in combination with Active Setup as a trigger, I will treat this separately from option one since there are some key differences.
  4. RUN and RUNONCE registry keys: while these are generally considered to be inferior options, I will mention them for the sake of completeness

The table below gives an overview of these mechanisms with some key properties

Name

Technology

Execution Timing

Repetition

Advertisement

Windows Installer

At application launch

At every launch

Active Setup

Windows Native

At user login

Once for each user

MSI repair

Windows Installer

When desired, usually user login

Depends on trigger

RUN/RUNONCE

Windows Native

At machine startup or user login

Once or every time

Let’s now run through the options, in descending order of desirability

 

MSI ADVERTISEMENTS

This will always be your best option, and hence your first choice. The idea is to use the tables in your MSI to create what is called an Advertised Entry Point into your package.  The best known method for creating such an entry point is the Shortcuts table, but this is NOT THE ONLY OPTION!!

Generally, when an advertised entry point into an MSI is triggered, this triggers the Windows Installer Self-Healing mechanism. This mechanism works as follows:

  1. Windows Installer detects the feature that the entry point is part of
  2. For all components in this feature, Windows installer checks for the presence of the component key-paths
  3. If a key-path, whether it be a file or registry key, is missing, a repair of  the all the components in this feature is triggered (feature level repair)
  4. If no missing keypaths are detected in the initial feature, a check will be done on the parent feature, and if any missing keypaths are found, Windows Installer will initialise a check on ALL features in the MSI. Any repairs done at this point though are done per component, not for the entire feature (component level repair)

 The fact that a check on missing keypaths is made, and a repair is only triggered if said keypath is not in place implies that you should give each component that contains user settings a keypath that is a HKCU registry key. Since this will never be in place before the self-healing has completed the installation for that user, you can be sure that the self-healing will be triggered. A simple value like HKCU\SOFTWARE\<Your Application>\UserSettings = 1 will suffice here.

 Now let’s run through the MSI tables that may contain such advertisement data. Before doing so however a small sidestep into COM Objects is necessary

 

COM or Component Object Model is a language-neutral way of implementing objects that can be used in environments different from the one in which they were created, even across machine boundaries. So to put it simply, it allows programmers to write code that can be re-used on a system by other programs (using DLLs or EXEs or OCXs).

This means that these components need to implement well-known interfaces to provide a standard way of approaching them, and they need to be uniquely registered by the operating system. This is where the CLSID comes into play.

A CLSID is a 128 bit key or GUID that uniquely identifies one of these COM objects. In the Windows registry such CLSIDs can be found at

 [HKEY_CLASSES_ROOT\CLSID\{<clsid>}]

 This key contains the info that links this class to a dll, exe or ocx file that contains the specific code implementation.

 Since these GUIDs can be troublesome to work with, it is allowed to link a CLSID to a simpler ProgID (PROGrammatic IDentifier), which is a more readable, non-unique name linked to a CLSID that has the form <Program>.<Component>.<Version>. These ProgIDs are stored in the registry under

 [HKEY_CLASSES_ROOT\{<ProgID>}]

 When a dll is shared by multiple CLSIDs some settings for this dll, like security, can be handled centrally across these CLSIDs. For this purpose one can identify an AppID. This is also a 128bit GUID. An individual class can be linked to such an AppID by adding a named value, "AppID" under their CLSID key in the registry.

[HKEY_CLASSES_ROOT\AppID\{<AppID>}]

[HKEY_CLASSES_ROOT\CLSID\{<clsid>}]

"AppID" = "{<appid>}"

 

Now let’s finally run through the MSI tables that allow for advertisement

Shortcuts table

As stated, the best known option. You create an advertised shortcut in your package that points to any file inside the msi, and each time a user clicks the shortcut, it will trigger the self-healing check, with the entry-point being the component that contains the advertised shortcut.

 Class table

This table is used to register a COM object to the Operating System, as discussed above. When this registration is advertised, Windows Installer will add a so-called darwin descriptor to the data in the registry. This darwin descriptor, which looks like a string of gibberish, is actually a hashed pointer to a product-feature-component combination which makes up the entry point for Windows Installer Self-healing. As soon as any application (most notably the one in your package) tries to use this COM object, a self-heal will be triggered.

 ProgID table

As discussed above ProgIDs allow for higher level naming of (sets of) CLSIDs. The ProgID table contains an optional foreign key (Class_) that links it to the Class table and hence a certain CLSID. The triggering mechanism for self-healing is essentially identical to the one for the Class table.

 Extension table

In this table you link file extensions to their associated executables. When advertised, clicking a file with the registered extension will call Windows Installer Self-healing.

 Verb table

The Verb table is used for associating context-menu entries when clicking files with a certain extension, and identifying the command that should be run when clicking this menu entry. Again using this functionality will trigger Self-healing.

 Typelib table

This table is used for registering Type Libraries, however, since there is a strong advisory from Microsoft against using this table, I will not go into detail on it here. The advisory states that the needed entries should be entered directly in the registry instead of using this table.

 MIME table

The MIME table associates a MIME content type with a file name extension or a CLSID to generate the extension or COM server information required for advertisement of the MIME (Multipurpose Internet Mail Extensions) content.

 

ACTIVE SETUP

I sometimes like to consider Active Setup as a ‘poor man’s alternative to advertisement’, in the sense that, if possible, I would always prefer the use of advertisement in an MSI over Active Setup. There are however plenty of circumstances where you just cannot use advertisements in the MSI, so then Active Setup really becomes the next choice.

The principle behind Active Setup is simple. It sets up a way to run a command once for each user that logs into the machine. Core of the system is the list of registry keys found under

[HKLM\Software\Microsoft\Active Setup\Installed Components]

Every subkey here is the reference of one Active Setup. Once the Active Setup command has run for a certain user, an equivalent key is written to that user’s HKCU registry hive. Three important values can be distinguished under each of these keys:

  • @(Default): the friendly name for the action. This is the text which will appear in Microsoft’s “Applying Personal Settings for…” window that shows up when a user logs on
  • StubPath: this is the command that will execute once for each user that logs into the machine. It can be any command, considering that it gets executed in User Context, so the user should have sufficient privileges to execute this.
  • Version: versioning allows for rerunning the StubPath command. When the version is increased in the HKLM key, the Active Setup will run again for each user. This can bypass the problem of having to delete Active Setup keys for all users when we want to rerun the command.

Often the StubPath command used is actually an msiexec command that will trigger a repair of the installer MSI (msiexec /f …). We will go into this in the next section.

 

MSI REPAIR

By running msiexec.exe with a /f parameter and pointing it to an MSI file or a ProductCode, we can trigger a repair of this MSI. A full list of msiexec parameters can be found at http://support.microsoft.com/kb/227091, but the most commonly used combinations for User Setting repair are:

Msiexec /fu {ProductCode} : repairs all user-specific registry settings

Msiexec /fup {ProductCode}: repairs all user-specific registry settings and reinstalls missing files

 

The reason why I want to mention this mechanism separately from MSI self-healing, is that self-healing and repair are not the same thing. Where self-healing is a process that gets triggered from data within the MSI itself (advertised entry points), and get initiated from a specific component and feature, MSI repair is triggered by an external command, and does not initiate as fine-grained a process. There is no feature cascade done during the reinstall of missing files and registry keys.

Since the repair gets triggered by a msiexec.exe command line, more often than not, the aforementioned Active Setup is used to trigger the process.

 

RUN/RUNONCE registry keys

To me (note that this is subjective, but hey) this is really not as viable an option as the previous ones. I mention it for the sake of completeness, but will only give it a cursory treatment.

The RUN and RUNONCE keys can be found in the registry under

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

Values under these keys may contain commandlines that will be run either every time (RUN) or once (RUNONCE), either starting the next time the machine starts up (HKEY_LOCAL_MACHINE) or the next time the specific user logs on (HKEY_CURRENT_USER)

Personally I tend to think the combination of available options with Self-Healing, Repair and Active Setup should be enough to cover any scenario of User Settings propagation, so I almost never use this last option. The RunOnce key is too limited in my view for User Settings, and the Run key, since it triggers every time, runs unnecessarily often in my view.

 

This concludes this post giving an overview of User Setting propagation techniques. The key point that I wanted to get across is that there is, in my opinion, a cascading list of techniques to do this. Cascading in the sense that some should be preferred over others because they are more tightly linked to Windows Installer. I know there is more to be said on the subject, but that will be for future blog posts. That does not mean that I do not appreciate feedback, or am unwilling to change/extend/adapt this post based on that feedback :-)

 

Kr,

PJ

 

View comments (6)
Showing 11 - 15 of 92 results

Top Contributors

Talk About Windows Installer (MSI) Error Messages