Handling GAC Assemblies Using Wise Package Studio 7.0
In .NET, when an application is compiled, the output of the compilation produces what is known as an Assembly. Two types of assemblies can be produced by the compilation procedure. One is the executable file (*.exe) and the other is a dynamic link library file (*.dll).
Basically the assembly is the unit of deployment in Microsoft .NET and it can be thought of as a collection of types and resources that form a logical unit of functionality. An assembly is a self-describing entity. It contains all information about the types (classes) contained in the assembly, all external references needed for executing the assembly and so on. This is possible with an assembly manifest. The manifest contains assembly's identity and version information, a file table containing all files that make up the assembly and the assembly reference list for all external dependencies. Thus assemblies do not need to depend on the registry values for compilation or execution.
An assembly contains manifest data and one or more modules. Manifest data contains information about the assembly and other list of assemblies that it depends on. It also contains all the publicly exposed types and resources. An assembly contains various modules. Each module contains metadata and IL.
Why Global Assembly Cache (GAC)
The GAC was originally called the Fusion cache and is currently implemented within Fusion.dll. This Global Assembly Cache stores .NET assemblies specifically designated to be shared by several applications on that computer.
Since the GAC is the machine-wide repository for shared assemblies, it is very easy to run into the problem of name collisions if these assemblies only had simple identities because they are developed independently by different vendors and even developers within an organization. Hence, when an assembly has to be put into the Global Assembly Cache it needs to be signed with a strong name.
A strong name contains the assembly's identity i.e. it's text name, version number, and culture information strengthened by a public key and a digital signature generated over the assembly. This is because the CLR verifies the strong name signature when the assembly is placed in the Global Assembly Cache.
Within each folder for a shared assembly, there is a sub folder named using the version and public key token components of the assembly e.g. 1.0.3300.0__b77a5c561934e089. Within this sub folder resides the actual assembly that is installed into the GAC. Note the __AssemblyInfo__.ini file that resides alongside each and every assembly file. This stores assembly properties like URL, MVID, DisplayName etc. For assemblies that have a native image installed, a CustomString property is also included.
Different Methods of adding Assemblies to the Application Setup
Gacutil.exe to Add an Assembly to GAC
Usually, We should avoid using GACUtil to install assemblies to the GAC for the following reasons:
- Unless the /r option is used, there is no way to track installation references in the GAC.
- GACUtil.exe is part of the .NET Framework SDK and hence is not guaranteed to be on all target machines. Additionally, it is not marked as redistributable and hence you need to check the licensing to make sure you can package it up with your application's installation image.
- Installing using GACUtil.exe does not enable Auto-Repair if the assembly in the GAC is missing (Auto-Repair is possible only with Windows Installer).
Windows Installer to add an Assembly to GAC
These are the following advantages of using Windows Installer to install an assembly:
- It supports accurate reference counting based on installation, repair and removal of assemblies in the GAC.
- It supports Install-on-Demand of assemblies in the GAC. If an assembly was missing from the GAC and a user launches an application that requires that assembly, MSI will automatically install / re-install that assembly to the GAC.
- Rollback of unsuccessful installations, repairs and removals of assemblies in the GAC. Assemblies are added and removed from the GAC as a unit; that is, the files that constitute an assembly are always installed or removed together. This is due to the transactional model of the installation, which doesn't actually commit to the GAC until the end of the script so that rollback can remove the GAC assemblies.
Re-Packaging MSI with Assemblies
Step 1:
Change the GAC from the catalogue Format to Folder.
Procedure 1:
Create the following registry DWORD key to view the GAC in a folder format. Usually, it will be displayed in a catalog format.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion] "DisableCacheViewer"=dword:00000001
Procedure 2:
Map a temporary drive say W to C:\ using subst w: C:\
now, just type W:\Winnt\Assembly in run prompt to view in folder format.
Now, we can copy the assembly dlls.
Step 2:
Capture the application on a clean Vista/XP or a 2000 Machine.
After capturing the application WSI will be displayed as below in the "Installation Expert
Step 3:
Goto Installation expert-> Product Details and change the Application Type to
.NET Application If only GAC assemblies are present.
Mixed If you have both GAC and WinSxS in your captured MSI
Step 4:
Delete all the assemblies and its folders from Windows->assembly->GAC
Step 5:
Copy all the assemblies under GAC to the folder Global Assembly Cache and place it right next to the WSI.
Step 6:
Goto Installation expert->Files section, we see a new folder called Global Assembly Cache being created. Add GAC assemblies one by one to this folder.
On adding each file double click on the assembly, Change the Assembly Type to .NET
On changing the Type, it would automatically generate a manifest file.
Now click on the Add button to enter the details for this assembly.
Add the other parameters like Name, PublicKeyToken and Version. (These details can be found in C:\Windows\Assembly or in the captured folder names)
In the above example folder name, 2.5.0.3 is the version name and b518cb987517199b is the PublicKeytoken
Once when all the details are added the window will look as below.
Step 7:
Go to Setup Editor-> MSIAssembly Table and check whether an entry is being made for the assembly you just entered.
If there are multiple versions of a single assembly then confirm that the File_Manifest is marked correctly for the same.
In this below example, there is a single assembly of 2 different versions existing in GAC.
Important step is to check whether their manifests are mapped correctly, else change it manually. When this is not done, we get the error 1935(An error occurred during the installation of assembly).
Also check with MsiAssemblyName table for more details,
Step 8:
Compile the WSI and test for the assembly Installation and package functionality.
General guidelines for assemblies which are Captured in a WSI While Snapshot:
- Anything captured in GAC - one can create them by going to component and going to assembly table, Wise automatically creates an entry for them in assembly table.
- Anything in registry in HKCR\Clsid...with inprocserver as mscoree.dll - they are.net interoperable assemblies (.net assemblies that can be used with non dotnet languages like vbscript others) that are registered with regasm.exe. Although keeping registries for them would be a good option too., but should be aware that they are also .net assemblies.
- Anything captured in GAC Native images folder- they are dot assemblies registered with ngen.exe - native imgaes are created for faster execution of assemblies. One needs to delete these files from captured wsi and use ngen in custom action to create native images for these assemblies.
- Mshelp2 files captured- they are new type of help files (we will see extension like .hxn, hss) help file that can be used as url as well. we can see them when u install visual studio .net. One needs to delete all the references of these files in appdatafolder. Further, we will need to use custom actions and h2reg.ini and h2reg.exe to register these help files.
Advantages of Using an Assembly
Assemblies are designed to simplify application deployment and to solve versioning problems that can occur with component-based applications. Many deployment problems have been solved by the use of assemblies in the .NET Framework. Because they are self-describing components that have no dependencies on registry entries, assemblies enable zero-impact application installation. They also simplify uninstalling and replicating applications.
To solve versioning problems, as well as the remaining problems that lead to DLL conflicts, the runtime uses assemblies to do the following:
- Enable developers to specify version rules between different software components.
- Provide the infrastructure to enforce versioning rules.
- Provide the infrastructure to allow multiple versions of a component to be run simultaneously (called side-by-side execution).














Great Post
This is really a good and in depth analysis of GAC assemblies. Really appreciate this...
Just wanted to clarify somethings from you since you have so much knowledge on this..
I have created a few package for .Net but never used this method as described above, maybe i never placed them in GAC. But what I wanted to ask is that is it ok that if we just have .NET files to add then we perform the following steps:
1) register the .Net file with Gacutil or regasm
2) drag drop the file into file table.
3) it automatically takes the entries of .Net assemblies in the MSIAssembly and MSIAssembly name table.
We use to follow the above procedure.
Piyush Nasa
Altiris Certified Professional (ACP)
Path?
Can we know the path of the dll registered in the GAC as to where is it present in the system?
The Path
The Path where GAC dlls are stored after registration is: C:\WINDOWS\assembly or you can say: %Windows%\assembly, just in case your root drive is not C:\
Piyush Nasa
Altiris Certified Professional (ACP)
Would you like to reply?
Login or Register to post your comment.