Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Visual Studio.NET / Setup / April 2004

Tip: Looking for answers? Try searching our database.

Possible design flaw in windows installer during an uninstall/install.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Dave - 09 Apr 2004 10:27 GMT
I've run into what appears to be a bug/design flaw in windows installer.
This occurs when an MSI file is configured so that it will automatically
uninstall a previously installed older version before running the install of
the new version, and the MSI file contains a custom action that is to be run
in managed code in one of the assemblies that is to be updated to a newer
version.

I added diagnostics to the custom action so that it printed out to a trace
listener the version number of the executing assembly. I then built two
versions of the MSI file, each time changing the version number of the
assembly and the MSI file.

I installed the older version and then ran the install of the newer version.
When running the install of the newer version it correctly detected the
older version and 1st uninstalled it - when it ran the custom action during
the uninstall the version number of the old assembly was printed out. It
then ran the install of the newer version. When it ran the custom action in
what was supposed to be the new assembly it printed out the version number
of the old assembly (that was supposedly uninstalled).

The bits on disk were correct but the wrong assembly was executing code!

It appears that windows installer creates a single appdomain and executes
all custom actions from within the default appdomain. It appears that it
never recycles the appdomain between the time the uninstall completes and
before the install begins - if so, then this is a major problem.

The problem is that once an assembly is loaded into an appdomain it stays
loaded and cannot be unloaded from that appdomain. Once the original
assembly is loaded, even if a newer version of it is on disk the fusion
layer will ignore it and continue to run the version that has been loaded.
The assembly was not signed with a strong name, but I would expect this
behavior even if it was signed. The result is that code in the original
assembly is executing when that assembly should have been deleted.

It may  be that windows installer expects shadow copying to permit this (I'm
guessing that's what it uses) but if so, this is a faulty assumption.

If the installer wants to execute only once the code that hosts the CLR,
then it should run all custom actions in managed code from a second
appdomain, and then unload that appdomain after the uninstall and reload it
for the install. That is the only way to unload all the assemblies that have
been loaded without unloading the entire CLR.

So...I'm wondering if my analysis is correct, and if anyone else has run
into this. And I'm also wondering if there's a workaround other then forcing
users to manually uninstall the old version before installing the new
version.

Thanks
David Levine
Phil Wilson - 09 Apr 2004 18:11 GMT
You're right, I think this is a bug that the Windows Installer team is aware of.
It's not quite as exotic as you describe. Once MSI has loaded a DLL (any kind of
DLL) to call a custom action, it doesn't load another copy with the same name,
even though it's a different version. It's most common in the major upgrade
scenario you describe. See the thread "Windows Installer bug when same custom
action called twice" in platformsdk.msi, starting 3/16/2004.
Signature

Phil Wilson [MVP Windows Installer]
----

> I've run into what appears to be a bug/design flaw in windows installer.
> This occurs when an MSI file is configured so that it will automatically
[quoted text clipped - 47 lines]
> Thanks
> David Levine
Dave - 10 Apr 2004 12:58 GMT
Thanks for the link to that thread. After reading that thread I am not sure
if this is the same problem.

From what I could gather from that thread the windows installer will not
load the same DLL twice (as determined by its simple name), but it also
sounds as if it uses a different algorithm for loading native .net
assemblies.  The thread mentions that it invokes actions in .net assemblies
by going through the InstallUtilLib.dll layer instead of loading it
directly.  In this other thread's  case an assembly of the same name was in
two different locations at install time. This could have been a problem
because MSI does not invoke the same named assembly twice, and it could also
be because of the way the CLR runtime loads assemblies and resolves
references - the fusion layer in .net could be the source of the problem. If
the assembly is identical in both merge modules (same name, strong name,
etc) then fusion will not load the 2nd copy since the 1st assembly satisfies
all the binding requirements.

The part I am unclear on in my situation is how the installer can invoke the
method in the old assembly when that assembly has been deleted as part of
the uninstall process.

The situation I have is:

1. Old assembly exists. Invoke uninstall custom action, then remove assembly
(all files and directories are blown away).
2. New assembly gets installed at same location as old one (new directories
are created exactly as old directory layout and new files copied in).
3. Invoke install custom action.

In step 3, the custom action invoked is running code in the old assembly
even though that assembly has been removed.  To verify this I printed out
the assembly version number from within the install routine and its the old
version number. It sounds like it's keeping a copy of the assembly loaded in
memory (or in another location) even though the bits have been deleted.

Is this the same problem as the one in the thread you mentioned?

Any insight into this is appreciate. Thanks.

Dave

> You're right, I think this is a bug that the Windows Installer team is aware of.
> It's not quite as exotic as you describe. Once MSI has loaded a DLL (any kind of
> DLL) to call a custom action, it doesn't load another copy with the same name,
> even though it's a different version. It's most common in the major upgrade
> scenario you describe. See the thread "Windows Installer bug when same custom
> action called twice" in platformsdk.msi, starting 3/16/2004.
Phil Wilson - 10 Apr 2004 21:43 GMT
A couple of thoughts:
I think the issue isn't so much MSI or InstallUtilLib.Dll, it's just that
the LoadLibrary API ends up not loading the "same" DLL into the process no
matter which piece of code calls it, most likely because each is not loaded
using a unique full path. If you LoadLibrary("x.dll") twice, the second call
won't load another copy. That's my guess at why this might be happening.
Regarding the fusion stuff, I don't think it's heavily involved. You can see
the parameters passed to the ManagedInstall call, and none of them specify a
strong name or version of the custom action assembly, so I'm guessing that
locating the assembly isn't using strong names or assemblyversions.

You're probably right that the assembly stays loaded in the process even
though the file has been removed, so the custom action called from the new
install doesn't load the new assembly DLL that has the same name.
Signature

Phil Wilson
[MVP Windows Installer]

> Thanks for the link to that thread. After reading that thread I am not sure
> if this is the same problem.
[quoted text clipped - 48 lines]
> custom
> > action called twice" in platformsdk.msi, starting 3/16/2004.
Dave - 11 Apr 2004 16:14 GMT
> A couple of thoughts:
> I think the issue isn't so much MSI or InstallUtilLib.Dll, it's just that
> the LoadLibrary API ends up not loading the "same" DLL into the process no
> matter which piece of code calls it, most likely because each is not loaded
> using a unique full path. If you LoadLibrary("x.dll") twice, the second call
> won't load another copy. That's my guess at why this might be happening.

Could be. The loading rules for .net are very different then for win32. I'm
reserving the right to disagree later on :-)

> Regarding the fusion stuff, I don't think it's heavily involved. You can see
> the parameters passed to the ManagedInstall call, and none of them specify a
> strong name or version of the custom action assembly, so I'm guessing that
> locating the assembly isn't using strong names or assemblyversions.

If the assembly wasn't signed then all that is needed is the simple name. If
the assembly was signed with a strong name but the parameters used to invoke
the custom action did not specify a full name (simple name, strong name,
culture, and version) then this would be a major flaw. It should be possible
to install two assemblies, each with the same simple name, but both signed
with a strong name and of a different version, and invoke custom actions in
each (they would need to be in different folders to avoid naming conflicts
with the file system). I say "should" because I haven't tried this with MSI,
but this loading two assemblies of the same simple name but with different
full names is definitely supported in .net itself.

I would think that if the target of the custom action then MSI would defer
all assembly loading to the InstallUtilLib.Dll, which should have been smart
enough to handle this. But there I go assuming again...

> You're probably right that the assembly stays loaded in the process even
> though the file has been removed, so the custom action called from the new
> install doesn't load the new assembly DLL that has the same name.

Yah, that's pretty scary :-) I wonder how they pulled that one off...

Thanks for the feedback. If I learn anything further from MSFT I'll post
what I find out up here.
Phil Wilson - 11 Apr 2004 18:56 GMT
I think MSI *does* defer assembly loading to InstallUtilLib, but
InstallUtilLib doesn't know anything about the sn or version of the assembly
it should load. I think it's basically a shim to host the runtime and use
the AssemblyInstaller class, passing the command line.
Signature

Phil Wilson
[MVP Windows Installer]

>
> > A couple of thoughts:
[quoted text clipped - 39 lines]
> Thanks for the feedback. If I learn anything further from MSFT I'll post
> what I find out up here.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.