MSI Install-On-Demand


According to MSDN documentation How the Runtime Locates Assemblies, if fusion can’t find the assembly through probing, fusion will ask Windows Installer to provide the assembly if Windows Installer has information about the assembly.


<quote>


Probes for the assembly using the heuristics described in the probing section. If the assembly is not found after probing, the runtime requests the Windows Installer to provide the assembly. This acts as an install-on-demand feature.


</quote>


Alan talked about the Install-On-Demand in his blog back in Nov 2003.
http://blogs.gotdotnet.com/alanshi/PermaLink.aspx/a37d41c6-fc0a-4704-a024-42ecbc5db807


I don’t want to repeat what has been said. Here I want to talk about the details of MSI Install-On-Demand.


Install-On-Demand is per assembly. This means Install-On-Demand will be invoked for every assembly probing failure.


For Install-On-Demand there are two contexts. One is global context, which responds to all the assemblies installed to GAC. Another is application qualified context. Each assembly either belongs to the global context, or to an application context.


At runtime when fusion looks for Install-On-Demand information, fusion will look at the global context, as well as the context of the currently running application.


The context is really an MSI concept.


Over the years I have received several questions about this feature. Apparently it is used by people.


And John Lyon-Smith even opened a bug on MSDN feedback center!
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=6ca1cd8c-4cc4-4456-8c50-7705b5157548


John’s scenario does not work. It is not because fusion does not invoke Install-On-Demand, but because the assembly in question is in the wrong context.


Specifically, John is using VS to develop an MSI package. The package has two assemblies, Binding.exe and ClassLibrary1.dll, both built by VS. After the package is installed, if ClassLibrary1.dll is removed, it will not bring back by MSI Install-On-Demand.


The reason is when VS builds the package, VS puts Binding.exe and ClassLibrary1.dll into different contexts. In other words, Binding.exe is in Binding.exe context, and ClassLibrary1.dll is in ClassLibrary1.dll context.


At runtime when fusion is asked to find ClassLibrary1.dll, since Binding.exe is the currently running application, fusion will look for ClassLibrary1.dll in the Binding.exe context, and won’t find it there.


The reason VS puts them into separate contexts is that VS has no idea about the relationship between these two assemblies. For VS, all assemblies are equal. If VS had a feature to (manually) assign assemblies to different context, then this bug could be fixed.


According to the comment on the bug, the assigning assemblies to different context feature is resolved by won’t fix by VS team. If you want to build a MSI package with Install-On-Demand feature, you will have to find alternatives.


(I am very sure that context is not the right terminology here. But I am not familiar with MSI so I hijacked the term context.)

Comments (14)

  1. I believe you’re talking about "components" when you say "contexts" – maybe :)

  2. Eric Hybner says:

    I’m not sure that the PM responded to the issue appropriately. This bug is not technically requesting install-on-demand, it is requesting that a missing assembly trigger an MSI repair as the documentation indicates.

    In the example case, the DLL and EXE are in the same Feature (that’s the MSI context to which I believe you are referring), so if MSI’s Component validation was triggered then a repair would replace the missing file.

    One way to demonstrate this is to add a shortcut to Binding’s output binary in the setup package included with the sample solution. When the shortcut is launched, MSI component validation is triggered, which validates that all of the Components in the Feature are present and replaces any missing Components. This is also a viable workaround for the particular case documented in the bug.

    The demonstrated behavior (no repair when launching the binary directly) is consistent with MSI behavior for native binaries, which require that an "Advertised" (Feature-associated) shortcut (or similar Feature-associated data such as COM registration information) be accessed in order to trigger a repair.

    I agree with John’s original bug report; this is a bug. The .NET runtime does not invoke the Windows Installer to provide missing assemblies as is promised in http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhowruntimelocatesassemblies.asp. The documentation states that that the runtime "Probes for the assembly using the heuristics described in the probing section. If the assembly is not found after probing, the runtime requests the Windows Installer to provide the assembly. This acts as an install-on-demand feature."

    The runtime does not appear to be requesting that Windows Installer provide the assembly. If Fusion were invoking MsiProvideAssembly (as John’s sample CheckInstalled program does), then MSI would replace the missing binary.

    Either John and I are both terribly confused, the documentation is incorrect, or this is indeed a bug.

  3. junfeng says:

    Eric,

    We don’t invoke MSI install every time we see a binding failure. There are many by-design binding failure for resource probing. If we do that the perf will go to hell.

    Instead, we query MSI before we invoke MSI install. If MSI says it has the component we then will invoke MSI install. In John’s case, the query returns nothing because ClassLibrary1.dll is in the wrong context/component.

  4. Ovidiu says:

    Sometimes I wonder how Microsoft can act so stupidly as a whole with so many good people working there:

    Why build ClickOnce when many useful features were already available in Windows Installer? (If the answer is "for self-updating smart clients", then I’ll ask: Why not build a product similar to Windows Update and sell it?! Not to mention the fact that System Management Server does a very similar job already… or that you can advertise MSI packages from Active Directory with Group Policy. These two components work very well in intranets. A "Microsoft Update Server" product would work very well on the internet.)

    Even having built ClickOnce, I can all but wonder: For instance, when you choose "Background updates" for an app, you might expect it to use the Background Intelligent Transfer Service (BITS) available in Windows (it’s used by Automatic Updates, after all), but no, ClickOnce reinvents the wheel.

    Besides the Install-on-demand feature, very useful for large projects, Windows Installer has plenty other things to offer and it’s very extensible. The fact that Windows Installer provides extensibility points for custom actions but they’re still unavailable from .NET in a clean (_flexible_) manner amazes me (I don’t like the Installer class thingie and I think it’s a half baked solution).

    It’s a pity that Microsoft is unable to coordinate itself on these fronts. It seems to me that ClickOnce will join the ranks of marginal technologies of no use that will have to be supported for decades, when a wise investment into Windows Installer would have solved many problems with lower costs.

    Sorry for being off-topic, but this was a good place for a rant somewhat related to the matter :)

  5. junfeng says:

    Ovidiu,

    You can post your complain in Saurabh’s blog now:

    http://blogs.msdn.com/saurabh/default.aspx

  6. Phil Wilson says:

    I’d really like to know precisely what this means in the response to Erik:

    "Instead, we query MSI before we invoke MSI install. If MSI says it has the component we then will invoke MSI install. In John’s case, the query returns nothing because ClassLibrary1.dll is in the wrong context/component. "

    The implication is that there is some arrangement where you could invoke MSI to do the install, but there’s not enough detail in that response. The "in the wrong context/component" comment begs the question of what the right context/component would be. Note also that the VS people didn’t say that install-on-demand doesn’t work, just that you couldn’t make it work with Visual Studio setup projects. There are plenty of MSI build tools that could be used to build an MSI file that really would do the install-on-demand, so it would actually help if someone could explain what the right context/component etc would be to make install-on-demand work.