Wrox Programmer Forums
Go Back   Wrox Programmer Forums > .NET > Other .NET > General .NET
|
General .NET For general discussion of MICROSOFT .NET topics that don't fall within any of the other .NET forum subcategories or .NET language forums.  If your question is specific to a language (C# or Visual Basic) or type of application (Windows Forms or ASP.Net) try an applicable forum category. ** PLEASE BE SPECIFIC WITH YOUR QUESTION ** When posting here, provide details regarding the Microsoft .NET language you are using and/or what type of application (Windows/Web Forms, etc) you are working in, if applicable to the question. This will help others answer the question without having to ask.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the General .NET section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old June 19th, 2006, 04:41 AM
Authorized User
 
Join Date: Aug 2004
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default Custom Install Actions and the GAC

[This is all with .Net 1.1/VS 2003]

I am trying to create an installer which installs a shared assembly (MyLibrary.dll) in Common Files, which also is registered in the GAC. The installer also installs a service application (MyService.exe) in Program Files. Within the service application there is an Installer class to register the service, which relies on the shared assembly.

To do this I have a setup project which places the service assembly in the Application Folder, and two copies of the shared code in the Common Files Folder and the Global Assembly Cache folder.

When I try to run the installer the installation fails because the framework cannot create the installer class. The reason for this appears to be that the shared code has not been registered in the GAC at the time the custom install action is executed. If I remove the cutom action the shared assembly definitely gets registered in the GAC.

If I look inside the installer database with Orca I see that in the InstallExecuteSequence the custom actions are performed before the MsiPublishAssemblies action, which is supposed to be the action which registers assemblies in the GAC. I have tried changing the sequence so that the custom action is the last action except for InstallFinalize, and it still does not work. As far as I can tell the custom action is a deferred action, since its type is 1025.

What is more I have tried creating an installer without the custom action. If I remove the MsiPublishAssemblies action from the InstallExecuteSequence table the shared assembly still gets registered in the GAC, which leads me to believe the MsiPublishAssemblies action is not the place where assemblies are registered, despite Microsoft's documentation.

What am I missing, and is there a way to make this kind of thing work without having to hack around inside the installer database?

The closest I've come on the internet to a solution is at http://www.dotnet247.com/247referenc...28/140998.aspx, but what they have suggested has failed.

 
Old June 21st, 2006, 05:39 AM
Registered User
 
Join Date: Jun 2006
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi eadred, I'm having the exact same problem. Only difference is I'm running VS2005/.NET 2.0. I have had the same experience with the MsiPublishAssembly Action, but I have noticed that if you remove the entry for the assemblies going into the GAC in the MsiPublishAssembly table, they are not put into GAC. So it must be related to this action or some action that references the MsiPublishAssembly table.

I also have been searching for a few days and found the same link. But it has not helped me at all either. I am beginning to think that the type 1025 is not a deferred action.
(http://bonemanblog.blogspot.com/2005...-i-custom.html) This blog, as well as a few other article mentions that only types 0x400 and 0x4000 (1024 and 16384) are the only deferred action types. However, if I change the type to either of these values I get an error 2717 which is an error with the custom action.

In any case, I will also be plugging along at this until I get it right. So if I find anything I will let you know. If you could do the same, that would be great. And if by some chance you've already figured this out, please save me the pain and clue me in.

Thanks.

Pete
 
Old June 21st, 2006, 05:56 AM
Authorized User
 
Join Date: Aug 2004
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi

Thanks for the link - I'll have a look at that.

As far as my limited understanding goes, deferred custom actions are specified by adding a value (in this case 1024) to the value for the type of the non-deferred action (in this case 1, which indicates a call to a dll).

See http://msdn.microsoft.com/library/de...on_options.asp and http://msdn.microsoft.com/library/de...ion_type_1.asp

 
Old June 21st, 2006, 10:41 AM
Registered User
 
Join Date: Jun 2006
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Check out this link.

http://www.c-sharpcorner.com/UploadF...b-496261d81367

Download the code. Add the FusionInstaller.cs class to your project. Make the appropriate calls and it works. You add the assemblies programmatically to the GAC. I haven't found any other way to do it. Let me know if you have any problems and I'll walk you through it.

Pete
 
Old June 21st, 2006, 11:24 AM
Authorized User
 
Join Date: Aug 2004
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi,

Thanks for the link.

If this is doing what I think it is doing then it is installing the shared assembly to whatever location it gets installed to, then calls a helper function to register the assembly found at that location into the GAC. This was originally what I was trying to do before using the Global Assembly Cache special folder. You can do the same kind of thing with the System.EnterpriseServices.Internal.Publish class with its GacInstall method.

The problem coimes when you are trying to install an older version of the shared dll over the top of a newer version (for example the shared dll is used by two applications, both of which try to install the shared assembly in Common Files, and the application which was installed first used a newer version of the shared assembly). In this case the installer won't copy an older version over the top of a newer version, in which case the custom install action code doesn't find the version of the assembly it wants at the installation location, and the older version never gets installed in the GAC.

 
Old June 28th, 2006, 09:19 AM
Authorized User
 
Join Date: Aug 2004
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I've got it!

What you need to do is place your custom actions after the MsiPublishAssemblies action in the InstallExecuteSequence table, but you need to add an InstallExecute standard action between MsiPublishAssemblies and your custom actions.

There is a rather confusing comment in the installer documentation on MSDN which reads "The assemblies are not committed until successful execution of the InstallFinalize Action. This means that if you author a custom action or resource that relies on the assembly, it must be sequenced after the InstallFinalize Action. For example, if you need to start a service that depends on an assembly in the Global Assembly Cache (GAC), you must schedule the starting of that service after the InstallFinalize Action." Trying this however leads to an Error Code 2762, but it did put me on the scent of InstallExecute.

 
Old June 29th, 2006, 06:24 AM
Registered User
 
Join Date: Jun 2006
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Excellent work!!! I found the same passage in the documentation and took it mean the situation was a catch 22. That's why I went on the programmatic path. I just tried your solution out and it works beautifully. Thanks a million. I'll buy you a pint if you're ever in Dublin.

I have a question for you. In your file system editor in the setup and deployment project, is the contents of the "Application Folder" the same as the contents of the "Global Assembly Cache Folder"? The reason I ask is, when I run the validator on the msi from Orca I get an error stating:

"The target file '<mycomponent>.dll' is installed in '[TARGETDIR]\' by two different components on an LFN system: (the two component id's). This breaks component reference counting."

Any thoughts? Once again, nice work and thanks.

Pete
 
Old June 29th, 2006, 07:15 AM
Authorized User
 
Join Date: Aug 2004
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Pete!

I put the 'Primary Output from MyProject' in both the Commom Files folder and the Global Assembly Cache folder. The automatic dependency detection also drags in the project dependencies into the Global Assembly Cache folder (and I probably ought to also put them in Common files as well).

I've never seen the problem you are having, but the mention of reference counting smacks of COM - you aren't trying to register your assemblies as COM assemblies or something like that? Also the error indicates that two things are being registered in the same place, not that the same thing is being installed in two different places.

Actually thinking about it, if you have a solution with two projects, one of which relies on the other, if you add the Primary Outputs from both into the application folder the automatic dependency detection isn't intelligent enough to realise that it doesn't need to automatically add the referee assembly as a dependency of the referrer.

In other words in your application folder you end up with 'Primary Output from Referrer', 'Primary Output from Referee' (both of which you have added manually), and Referee.dll (added by the automatic dependency detection because it is used by Referrer.dll).

When you try and build a project like this you get warnings from VS about multiple copies of the same assembly being installed in the same place, and you have to manually exclude the automatically added dependencies. Is this the problem?

PS mine's a Guinness

 
Old August 22nd, 2006, 08:02 AM
Registered User
 
Join Date: Aug 2006
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Well.. in VS.NET 2005, you can't even build the deployment project.. moans about building a custom action that is in the GAC.

Who designed this rubbish! Why so many hoops to go through to run an installer on an assembly in the GAC?





Similar Threads
Thread Thread Starter Forum Replies Last Post
Focus on Actions Panel Stela Flash (all versions) 1 September 29th, 2007 11:45 PM
trigger actions b00gieman Beginning VB 6 1 September 25th, 2007 07:23 AM
e-mail actions... ruhin Beginning PHP 4 May 4th, 2005 10:52 AM
User Actions ppenn Access VBA 1 May 18th, 2004 02:37 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.