Thursday, March 22, 2007

Global Assembly Cache (GAC) and the .Net Assembly

1. How should we add an assembly reference?

If a DLL project is referenced in an application, using Add Reference--> Projects, the referenced DLL has the source path as one of the following:

DLL in the release folder.

Note: DotNet does not considers whether the .dll is available in the release folder or not.

Incase release folder is not available then the .dll will refer the debug folder.

If the reference file is selected explicitly to point debug or release the selected folder is referenced.

2. How should an assembly be uninstalled

Uninstalling an assembly should be done with care.

The following command removes the assembly hello from the global assembly cache(GAC) as long as no reference counts exist for the assembly.

gacutil /u hello

Note : If there is only one version of hello assembly the above command is fine and you are in safer side. Incase if there are more than one version of the assembly or different assembly with same name exists then the above command might remove more than one assembly from the assembly cache because the assembly name is not fully specified. For example, if both version 1.0.0.0 and 3.2.2.1 of hello are installed in the cache, the command gacutil /u hello removes both of the assemblies.

Then how to remove the assembly safely: Use the following example to avoid removing more than one assembly. This command removes only the hello assembly that matches the fully specified version number, culture, and public key.
gacutil /u hello, Version=1.0.0.1, Culture="de", PublicKeyToken=45e343aae32233ca

3. Can I delete the source file which I have used to register in GAC

Yes, the assembly makes a copy in the GAC folder. So the source file can be deleted.

4. Can I specify the space used by GAC?

Yes, Navigate to the GAC directory, C:\winnt\Assembly in explore. In the tools menu select the cache properties; in the windows displayed you can set the memory limit in MB used by the GAC.

5. Why I should use Assemblies.

The .NET Framework uses assemblies as the fundamental unit for several purposes:

· Security
· Type Identity
· Reference Scope
· Versioning
· Deployment

6. What is Versioning?

Each assembly has a 128-bit version number that is presented as a set of four decimal pieces: Major.Minor.Build.Revision

For example, an assembly might have the version number 3.5.0.126.

By default, an assembly will only use types from the exact same assembly (name and version number) that it was built and tested with. That is, if you have an assembly that uses a type from version 1.0.0.2 of another assembly, it will (by default) not use the same type from version 1.0.0.4 of the other assembly. This use of both name and version to identify referenced assemblies helps avoid the "DLL Hell" problem of upgrades to one application breaking other applications.

Tip An administrator or developer can use configuration files to relax this strict version checking. Look for information on publisher policy in the .NET Framework Developer's Guide.

7. Can my assembly span more that one file?

Yes, assembly can have more that one file. Each file can be developed from different language too. Using the al.exe utility all the required files are grouped and made into single file.

8. How do I decide whether my assembly should contain only one DLL or a collection of dlls?

A typical assembly is a single DLL described by an assembly manifest. An assembly may contain multiple files. In cases where components have tight interdependencies such that if you make changes to one component the other would also change, it makes sense to include the group of files in the same assembly.

When deciding what to include in your assembly, keep in mind how you intend to manage these in the future, and how you want applications to use them. For example, if you include two files in an assembly, each time you ship a new version of the assembly, you would include both files, whether or not both have changed. If you have two files with a strong interdependency, and you decide to ship as separate assemblies, you need to be aware that customers have a choice of mixing versions. If you update both assemblies, a customer may choose to use the new version of one and the older version of the other, which may or may not be compatible

9. Which type of reference is advantageous during development and why? Referencing the exact dll path or the project itself in a solution with more than one project, with one or more class lib project?

Referring, project itself is right and advantages, for the following reasons:

They automatically track project configuration changes. For example, when you build using a debug configuration, any project references refer to debug assemblies generated by the referenced projects, while they refer to release assemblies in a release configuration. This means that you can automatically switch from debug to release builds across projects without having to reset references.

10. What are the types of caches available in .Net ?

1) GAC, or Global Assembly Cache - all shared assemblies live here
2) Download Cache - when you execute an assembly from a URL, this is where the downloaded assemblies end up
3) 'ZAP' Cache - this cache seems to serve as the home for pre-compiled native assembly images that are produced by NGEN

11. What is called probing?

Private assemblies are deployed within the directory structure of the application in which they are used. Private assemblies can be placed directly in the application directory, or in a subdirectory thereof. The CLR finds these assemblies through a process called probing. Probing is simply a mapping of the assembly name to the name of the file that contains the manifest.

12. If the same assembly is used by two app, what will be store in GAC and how it is stored.

In GAC, only one master copy of the dll is stored. But if another application is installing the same assembly (with the same version) a reference with a native image is created.

So if we have a dll, which is used by three applications, there will be one master and two images in the GAC.

You can see this when you check the GAC folder. In COM you can't have same dlls with different versions.

13. What do you call as DLL Hell in COM and how was that fixed in .Net.

Let’s consider a shared dll used by msn messenger and your own application. When you upgrade MSN Messenger, a new version of shared dll will be installed which may not be compatible with your application, which leads in failure of your application. This scenario is described as DLL Hell.

In .Net the problem is fixed using GAC - shared assembly, where you can have more than one version of the same dll. If new version of msn is installed, the new version of the dll in installed in GAC with the new version number. The important thing in GAC is that, more than one version of same dll can co-exist, so older version of dll, which is referenced by your application, will not get affected.

14. How to override the assembly name and version combination key while selecting and using the assembly in the GAC?

By default the assembly for the application is binded during installation.

The assembly is selected by name and the version from the GAC, sometimes we require our application to use another version of the same assembly. For example

An administrator may deploy a critical bug fix to a shared assembly and want all applications to use this new version regardless of which version they were built with. Also, the vendor of a shared assembly may have shipped a service release to an existing assembly and would like all applications to begin using the service release instead of the original version. These scenarios and others are supported in the .NET Framework through version policies.

Version policies are stated in XML files and are simply a request to load one version of assembly instead of another. For example, the following version policy directs the CLR to load version 5.0.0.1 instead of version 5.0.0.0 of an assembly called MarineCtrl:






In addition to redirecting from a specific version number to another, you can also redirect from a range of versions to another version. For example, the following policy redirects all versions from 0.0.0.0 through 5.0.0.0 of MarineCtrl to version 5.0.0.1:






15. What are the types of version policy levels

Application-specific Policy. Each application has an optional configuration file that can specify the application’s desire to bind to a different version of a dependent assembly. The name of the configuration file varies based on the application type. For executable files, the name of the configuration file is the name of the executable plus a ".config" extension. For example, the configuration file for "myapp.exe" would be "myapp.exe.config". Configuration files for ASP.NET applications are always "web.config".

Publisher Policy. While application-specific policy is set either by the application developer or administrator, publisher policy is set by the vendor of the shared assembly. Publisher policy is the vendor’s statement of compatibility regarding different versions of her assembly. For example, say the vendor of a shared Windows Forms control ships a service release that contains a number of bug fixes to the control. The original control was version 2.0.0.0 and the version of the service release is 2.0.0.1. Because the new release just contains bug fixes (no breaking API changes) the control vendor would likely issue publisher policy with the new release that causes existing applications that used 2.0.0.0 to now start using 2.0.0.1. Publisher policy is expressed in XML just as application and machine-wide policy are, but unlike those other policy levels, publisher policy is distributed as an assembly itself. The primary reason for this is to ensure that the organization releasing the policy for a particular assembly is the same organization that released the assembly itself. This is accomplished by requiring that both the original assembly and the policy assembly are given a strong name with the same key-pair.

Machine-wide Policy. The final policy level is machine-wide policy (sometimes referred to as Administrator policy). Machine-wide policy is stored in machine.config which is located in the "config" subdirectory under the .NET Framework install directory. The install directory is %windir%\microsoft.net\framework\%runtimeversion%. Policy statements made in machine.config affect all applications running on the machine. Machine-wide policy is used by Administrators to force all applications on a given machine to use a particular version of an assembly. The most common scenario in which this is used is when a security or other critical bug fix has been deployed to the global assembly cache. After deploying the fixed assembly, the Administrator would use machine-wide version policy to ensure that applications don’t use the old, broken version of the assembly.

16. What is Native image file for an assembly?

A native image is a file containing compiled processor-specific machine code. Note that the native image that Ngen.exe generates cannot be shared across Application Domains. Therefore, you cannot use Ngen.exe in application scenarios, such as ASP.NET, that require assemblies to be shared across application domains.

Pre-compiling assemblies with Ngen.exe can improve the startup time for applications, because much of the work required to execute code has been done in advance. Therefore, it is more appropriate to use Ngen.exe for client-side applications where you have determined that the CPU cycles consumed by JIT compilation cause slower performance.

17. Can I limit the space used by GAC?

Yes, the size of the GAC can be modified as per the requirements. To set the size, browse through the gac folder %windir%\Assembly\ in windows explorer.

Select ToolsàCache Options from the menu to set the maximum size of the disk space to be allotted for GAC.

18. How do I see the physical file structure of cache in explorer?

It is possible to see physical file structure of GAC folder.

As such Winnt\assembly\gac cannot be browsed using windows explorer.

To view the physical file structure add a binary value named 'DisableCacheViewer' to the registry key HKLM\Software\Microsoft\Fusion and set it to a non-zero value.

Thursday, March 15, 2007

Could not load file or assembly 'stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.

Could not load file or assembly 'stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

We developed windows application using FrameWork2.0. It was working fine in the development system. When we installed in the production system which does not have VS2005. We got the above mentioned error. We access com component for getting the image file from the webcamera. It was suprising the framework 2.0 was perfectly installed.

The issue was The stdole.dll is installed in GAC and is not bundled through application setup. When we access image through our application, the interop dll (stdole.dll) is required. Interesting thing is the stdole.dll is not installed along with the framework 2.0 and is not available in GAC of production system.

To resolve, we updated the setup project to have stdole.dll as private assembly. The file was referenced in the file section of setup project from

C:\Program Files\Microsoft.NET\Primary Interop Assemblies

To make sure that that stdole.dll has to be accessed from the current folder instead of GAC. Right click on the stdole.dll in the reference section of project and select local copy true. By default it will be false.