Вы находитесь на странице: 1из 81

Q: What is the difference between managed and unmanaged code?

A: Managed Code Managed code is code that is written to target the services of the managed runtime execution environment (like Common Language Runtime in .NET Framework). The managed code is always executed by a managed runtime execution environment rather than the operating system directly. Managed refers to a method of exchanging information between the program and the runtime environment. Because the execution of code is governed by the runtime environment, the environment can guarantee what the code is going to do and provide the necessary security checks before executing any piece of code. Because of the same reason the managed code also gets different services from the runtime environment like Garbage Collection, type checking, exception handling, bounds checking, etc. This way managed code does not have to worry about memory allocations, type safety, etc. Applications written in Java, C#, VB.NET, etc target a runtime environment which manages the execution and the code written using these types of languages is known as Managed Code. Managed code is always compiled into an Intermediate Language (MSIL in case of .NET Framework). The compiler used by .NET framework to compile managed code compiles it into Intermediate Language and generates the necessary metadata, symbolic information that describes all of the entry points and the constructs exposed in the Intermediate Language (e.g., methods, properties) and their characteristics. The Common Language Infrastructure (CLI) Standard describes how the information is to be encoded, and programming languages that target the runtime emit the correct encoding. In .NET Framework Managed Code runs within the .Net Frameworks CLR and benefits from the services provided by the CLR. When we compile the managed code, the code gets compiled to an intermediate language (MSIL) and an executable is created. When a user runs the executable the Just In Time Compiler of CLR compiles the intermediate language into native code specific to the underlying architecture. Since this translation happens by the managed execution environment (CLR), the managed execution environment can make guarantees about what the code is going to do, because it can actually reason about it. It can insert traps and sort of protection around, if it's running in a sandboxed environment, it can insert all the appropriate garbage collection hooks, exception handling, type safety, array bounce, index checking and so forth. Managed code also provides platform independence. As the managed code is first compiled to intermediate language, the CLRs JIT Compiler takes care of compiling this intermediate language into the architecture specific instructions.

Unmanaged Code Code that is directly executed by the Operating System is known as un-managed code. Typically applications written in VB 6.0, C++, C, etc are all examples of unmanaged code. Unmanaged code typically targets the processor architecture and is always dependent on the computer architecture. Unmanaged code is always compiled to target a specific architecture and will only run on the intended platform. This means that if you want to run the same code on different architecture then you

will have to recompile the code using that particular architecture. Unmanaged code is always compiled to the native code which is architecture specific. When we compile unmanaged code it gets compiled into a binary X86 image. And this image always depends on the platform on which the code was compiled and cannot be executed on the other platforms that are different that the one on which the code was compiled. Unmanaged code does not get any services from the managed execution environment. In unmanaged code the memory allocation, type safety, security, etc needs to be taken care of by the developer. This makes unmanaged code prone to memory leaks like buffer overruns and pointer overrides and so forth. Unmanaged executable files are basically a binary image, x86 code, loaded into memory. The program counter gets put there and thats the last the Operating System knows. There are protections in place around memory management and port I/O and so forth, but the system doesnt actually know what the application is doing. Runtime Technical Questions Terminology What What What What What is is is is is the Common Language Runtime (CLR)? the common type system (CTS)? the Common Language Specification (CLS)? the Microsoft Intermediate Language (MSIL)? managed code and managed data?

Assemblies What is an assembly? What are private assemblies and shared assemblies? If I want to build a shared assembly, does that require the overhead of signing and managing key pairs? What is the difference between a namespace and an assembly name?

Application Deployment and Isolation What options are available to deploy my .NET applications? I've written an assembly that I want to use in more than one application. Where do I deploy it? How can I see what assemblies are installed in the global assembly cache? What is an application domain?

Garbage Collection What is garbage collection? How does non-deterministic garbage collection affect my code? Can I avoid using the garbage collected heap?

Remoting

How do in-process and cross-process communication work in the Common Language Runtime?

Interoperability Can I use COM objects from a .NET Framework program? Can .NET Framework components be used from a COM program? Can I use the Win32 API from a .NET Framework program?

Security What do I have to do to make my code work with the security system? Why does my code get a security exception when I run it from a network shared drive? How do I make it so that code runs when the security system is stopping it? How do I administer security for my machine? For an enterprise? How does evidence-based security work with Windows 2000 security?

Conceptual Questions What is the .NET Framework? The Microsoft .NET Framework is a platform for building, deploying, and running Web Services and applications. It provides a highly productive, standards-based, multi-language environment for integrating existing investments with next-generation applications and services as well as the agility to solve the challenges of deployment and operation of Internet-scale applications. The .NET Framework consists of three main parts: the common language runtime, a hierarchical set of unified class libraries, and a componentized version of Active Server Pages called ASP.NET. Runtime Technical Questions Terminology What is the common language runtime (CLR)? The common language runtime is the execution engine for .NET Framework applications. It provides a number of services, including the following: Code management (loading and execution) Application memory isolation Verification of type safety Conversion of IL to native code Access to metadata (enhanced type information) Managing memory for managed objects Enforcement of code access security Exception handling, including cross-language exceptions Interoperation between managed code, COM objects, and pre-existing DLLs (unmanaged code and data)

Automation of object layout Support for developer services (profiling, debugging, and so on)

What is the common type system (CTS)? The common type system is a rich type system, built into the common language runtime, that supports the types and operations found in most programming languages. The common type system supports the complete implementation of a wide range of programming languages. What is the Common Language Specification (CLS)? The Common Language Specification is a set of constructs and constraints that serves as a guide for library writers and compiler writers. It allows libraries to be fully usable from any language supporting the CLS, and for those languages to integrate with each other. The Common Language Specification is a subset of the common type system. The Common Language Specification is also important to application developers who are writing code that will be used by other developers. When developers design publicly accessible APIs following the rules of the CLS, those APIs are easily used from all other programming languages that target the common language runtime. What is the Microsoft Intermediate Language (MSIL)? MSIL is the CPU-independent instruction set into which .NET Framework programs are compiled. It contains instructions for loading, storing, initializing, and calling methods on objects. Combined with metadata and the common type system, MSIL allows for true cross-language integration. Prior to execution, MSIL is converted to machine code. It is not interpreted. What is managed code and managed data? Managed code is code that is written to target the services of the common language runtime (see What is the Common Language Runtime?). In order to target these services, the code must provide a minimum level of information (metadata) to the runtime. All C#, Visual Basic .NET, and JScript .NET code is managed by default. Visual Studio .NET C++ code is not managed by default, but the compiler can produce managed code by specifying a command-line switch (/CLR). Closely related to managed code is managed datadata that is allocated and de-allocated by the common language runtime's garbage collector. C#, Visual Basic, and JScript .NET data is managed by default. C# data can, however, be marked as unmanaged through the use of special keywords. Visual Studio .NET C++ data is unmanaged by default (even when using the /CLR switch), but when using Managed Extensions for C++, a class can be marked as managed by using the __gc keyword. As the name suggests, this means that the memory for instances of the class is managed by the garbage collector. In addition, the class becomes a full participating member of the .NET Framework community, with the benefits and restrictions that brings. An example of a benefit is proper interoperability with classes written in other languages (for example, a managed C++ class can inherit from a

Visual Basic class). An example of a restriction is that a managed class can only inherit from one base class. Assemblies What is an assembly? An assembly is the primary building block of a .NET Framework application. It is a collection of functionality that is built, versioned, and deployed as a single implementation unit (as one or more files). All managed types and resources are marked either as accessible only within their implementation unit, or as accessible by code outside that unit. Assemblies are self-describing by means of their manifest, which is an integral part of every assembly. The manifest: Establishes the assembly identity (in the form of a text name), version, culture, and digital signature (if the assembly is to be shared across applications). Defines what files (by name and file hash) make up the assembly implementation. Specifies the types and resources that make up the assembly, including which are exported from the assembly. Itemizes the compile-time dependencies on other assemblies. Specifies the set of permissions required for the assembly to run properly.

This information is used at run time to resolve references, enforce version binding policy, and validate the integrity of loaded assemblies. The runtime can determine and locate the assembly for any running object, since every type is loaded in the context of an assembly. Assemblies are also the unit at which code access security permissions are applied. The identity evidence for each assembly is considered separately when determining what permissions to grant the code it contains. The self-describing nature of assemblies also helps makes zero-impact install and XCOPY deployment feasible. What are private assemblies and shared assemblies? A private assembly is used only by a single application, and is stored in that application's install directory (or a subdirectory therein). A shared assembly is one that can be referenced by more than one application. In order to share an assembly, the assembly must be explicitly built for this purpose by giving it a cryptographically strong name (referred to as a strong name). By contrast, a private assembly name need only be unique within the application that uses it. By making a distinction between private and shared assemblies, we introduce the notion of sharing as an explicit decision. Simply by deploying private assemblies to an application directory, you can guarantee that that application will run only with the bits it was built and deployed with. References to private assemblies will only be resolved locally to the private application directory. There are several reasons you may elect to build and use shared assemblies, such as the ability to express version policy. The fact that shared assemblies have a cryptographically strong name means that only the author of the assembly has the key to produce a new

version of that assembly. Thus, if you make a policy statement that says you want to accept a new version of an assembly, you can have some confidence that version updates will be controlled and verified by the author. Otherwise, you don't have to accept them. For locally installed applications, a shared assembly is typically explicitly installed into the global assembly cache (a local cache of assemblies maintained by the .NET Framework). Key to the version management features of the .NET Framework is that downloaded code does not affect the execution of locally installed applications. Downloaded code is put in a special download cache and is not globally available on the machine even if some of the downloaded components are built as shared assemblies. The classes that ship with the .NET Framework are all built as shared assemblies. If I want to build a shared assembly, does that require the overhead of signing and managing key pairs? Building a shared assembly does involve working with cryptographic keys. Only the public key is strictly needed when the assembly is being built. Compilers targeting the .NET Framework provide command line options (or use custom attributes) for supplying the public key when building the assembly. It is common to keep a copy of a common public key in a source database and point build scripts to this key. Before the assembly is shipped, the assembly must be fully signed with the corresponding private key. This is done using an SDK tool called SN.exe (Strong Name). Strong name signing does not involve certificates like Authenticode does. There are no third party organizations involved, no fees to pay, and no certificate chains. In addition, the overhead for verifying a strong name is much less than it is for Authenticode. However, strong names do not make any statements about trusting a particular publisher. Strong names allow you to ensure that the contents of a given assembly haven't been tampered with, and that the assembly loaded on your behalf at run time comes from the same publisher as the one you developed against. But it makes no statement about whether you can trust the identity of that publisher. What is the difference between a namespace and an assembly name? A namespace is a logical naming scheme for types in which a simple type name, such as MyType, is preceded with a dot-separated hierarchical name. Such a naming scheme is completely under the control of the developer. For example, types MyCompany.FileAccess.A and MyCompany.FileAccess.B might be logically expected to have functionality related to file access. The .NET Framework uses a hierarchical naming scheme for grouping types into logical categories of related functionality, such as the Microsoft ASP.NET application framework, or remoting functionality. Design tools can make use of namespaces to make it easier for developers to browse and reference types in their code. The concept of a namespace is not related to that of an assembly. A single assembly may contain types whose hierarchical names have different namespace roots, and a logical namespace root may span multiple assemblies. In the .NET Framework, a namespace is a logical designtime naming convenience, whereas an assembly establishes the name scope for types at run time.

Application Deployment and Isolation What options are available to deploy my .NET applications? The .NET Framework simplifies deployment by making zero-impact install and XCOPY deployment of applications feasible. Because all requests are resolved first to the private application directory, simply copying an application's directory files to disk is all that is needed to run the application. No registration is required. This scenario is particularly compelling for Web applications, Web Services, and selfcontained desktop applications. However, there are scenarios where XCOPY is not sufficient as a distribution mechanism. An example is when the application has little private code and relies on the availability of shared assemblies, or when the application is not locally installed (but rather downloaded on demand). For these cases, the .NET Framework provides extensive code download services and integration with the Windows Installer. The code download support provided by the .NET Framework offers several advantages over current platforms, including incremental download, code access security (no more Authenticode dialogs), and application isolation (code downloaded on behalf of one application doesn't affect other applications). The Windows Installer is another powerful deployment mechanism available to .NET applications. All of the features of Windows Installer, including publishing, advertisement, and application repair will be available to .NET applications in Windows Installer 2.0. I've written an assembly that I want to use in more than one application. Where do I deploy it? Assemblies that are to be used by multiple applications (for example, shared assemblies) are deployed to the global assembly cache. In the prerelease and Beta builds, use the /i option to the GACUtil SDK tool to install an assembly into the cache: Copy gacutil /i myDll.dll Windows Installer 2.0, which ships with Windows XP and Visual Studio .NET will be able to install assemblies into the global assembly cache. How can I see what assemblies are installed in the global assembly cache? The .NET Framework ships with a Windows shell extension for viewing the assembly cache. Navigating to % windir%\assembly with the Windows Explorer activates the viewer. What is an application domain? An application domain (often AppDomain) is a virtual process that serves to isolate an application. All objects created within the same application scope (in other words, anywhere along the sequence of object activations beginning with the application entry point) are created within the same application domain. Multiple application domains can exist in a single operating system process, making them a lightweight means of application isolation.

An OS process provides isolation by having a distinct memory address space. While this is effective, it is also expensive, and does not scale to the numbers required for large web servers. The Common Language Runtime, on the other hand, enforces application isolation by managing the memory use of code running within the application domain. This ensures that it does not access memory outside the boundaries of the domain. It is important to note that only type-safe code can be managed in this way (the runtime cannot guarantee isolation when unsafe code is loaded in an application domain). Garbage Collection What is garbage collection? Garbage collection is a mechanism that allows the computer to detect when an object can no longer be accessed. It then automatically releases the memory used by that object (as well as calling a clean-up routine, called a "finalizer," which is written by the user). Some garbage collectors, like the one used by .NET, compact memory and therefore decrease your program's working set. How does non-deterministic garbage collection affect my code? For most programmers, having a garbage collector (and using garbage collected objects) means that you never have to worry about deallocating memory, or reference counting objects, even if you use sophisticated data structures. It does require some changes in coding style, however, if you typically deallocate system resources (file handles, locks, and so forth) in the same block of code that releases the memory for an object. With a garbage collected object you should provide a method that releases the system resources deterministically (that is, under your program control) and let the garbage collector release the memory when it compacts the working set. Can I avoid using the garbage collected heap? All languages that target the runtime allow you to allocate class objects from the garbagecollected heap. This brings benefits in terms of fast allocation, and avoids the need for programmers to work out when they should explicitly 'free' each object. The CLR also provides what are called ValueTypesthese are like classes, except that ValueType objects are allocated on the runtime stack (rather than the heap), and therefore reclaimed automatically when your code exits the procedure in which they are defined. This is how "structs" in C# operate. Managed Extensions to C++ lets you choose where class objects are allocated. If declared as managed Classes, with the __gc keyword, then they are allocated from the garbagecollected heap. If they don't include the __gc keyword, they behave like regular C++ objects, allocated from the C++ heap, and freed explicitly with the "free" method. For additional information about Garbage Collection see: Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework Garbage Collection, Part 2: Automatic Memory Management in the Microsoft .NET Framework

Remoting How do in-process and cross-process communication work in the Common Language Runtime? There are two aspects to in-process communication: between contexts within a single application domain, or across application domains. Between contexts in the same application domain, proxies are used as an interception mechanism. No marshaling/serialization is involved. When crossing application domains, we do marshaling/serialization using the runtime binary protocol. Cross-process communication uses a pluggable channel and formatter protocol, each suited to a specific purpose. If the developer specifies an endpoint using the tool soapsuds.exe to generate a metadata proxy, HTTP channel with SOAP formatter is the default. If a developer is doing explicit remoting in the managed world, it is necessary to be explicit about what channel and formatter to use. This may be expressed administratively, through configuration files, or with API calls to load specific channels. Options are: HTTP channel w/ SOAP formatter (HTTP works well on the Internet, or anytime traffic must travel through firewalls) TCP channel w/ binary formatter (TCP is a higher performance option for local-area networks (LANs)) When making transitions between managed and unmanaged code, the COM infrastructure (specifically, DCOM) is used for remoting. In interim releases of the CLR, this applies also to serviced components (components that use COM+ services). Upon final release, it should be possible to configure any remotable component. Distributed garbage collection of objects is managed by a system called "leased based lifetime." Each object has a lease time, and when that time expires, the object is disconnected from the remoting infrastructure of the CLR. Objects have a default renew time-the lease is renewed when a successful call is made from the client to the object. The client can also explicitly renew the lease. Interoperability Can I use COM objects from a .NET Framework program? Yes. Any COM component you have deployed today can be used from managed code, and in common cases the adaptation is totally automatic. Specifically, COM components are accessed from the .NET Framework by use of a runtime callable wrapper (RCW). This wrapper turns the COM interfaces exposed by the COM component into .NET Framework-compatible interfaces. For OLE automation interfaces, the RCW can be generated automatically from a type library. For non-OLE automation interfaces, a developer may write a custom RCW and manually map the types exposed by the COM interface to .NET Framework-compatible types.

Can .NET Framework components be used from a COM program? Yes. Managed types you build today can be made accessible from COM, and in the common case the configuration is totally automatic. There are certain new features of the managed development environment that are not accessible from COM. For example, static methods and parameterized constructors cannot be used from COM. In general, it is a good idea to decide in advance who the intended user of a given type will be. If the type is to be used from COM, you may be restricted to using those features that are COM accessible. Depending on the language used to write the managed type, it may or may not be visible by default. Specifically, .NET Framework components are accessed from COM by using a COM callable wrapper (CCW). This is similar to an RCW (see previous question), but works in the opposite direction. Again, if the .NET Framework development tools cannot automatically generate the wrapper, or if the automatic behavior is not what you want, a custom CCW can be developed. Can I use the Win32 API from a .NET Framework program? Yes. Using platform invoke, .NET Framework programs can access native code libraries by means of static DLL entry points. Here is an example of C# calling the Win32 MessageBox function: Copy using System; using System.Runtime.InteropServices; class MainApp { [DllImport("user32.dll", EntryPoint="MessageBox")] public static extern int MessageBox(int hWnd, String strMessage, String strCaption, uint uiType); public static void Main() { MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 ); } }

Security What do I have to do to make my code work with the security system? Usually, not a thingmost applications will run safely and will not be exploitable by malicious attacks. By simply using the standard class libraries to access resources (like files) or perform protected operations (such as a reflection on private members of a type), security will be enforced by these libraries. The one simple thing application developers may

want to do is include a permission request (a form of declarative security) to limit the permissions their code may receive (to only those it requires). This also ensures that if the code is allowed to run, it will do so with all the permissions it needs. Only developers writing new base class libraries that expose new kinds of resources need to work directly with the security system. Instead of all code being a potential security risk, code access security constrains this to a very small bit of code that explicitly overrides the security system. Why does my code get a security exception when I run it from a network shared drive? Default security policy gives only a restricted set of permissions to code that comes from the local intranet zone. This zone is defined by the Internet Explorer security settings, and should be configured to match the local network within an enterprise. Since files named by UNC or by a mapped drive (such as with the NET USE command) are being sent over this local network, they too are in the local intranet zone. The default is set for the worst case of an unsecured intranet. If your intranet is more secure you can modify security policy (with the .NET Framework Configuration tool or the CASPol tool) to grant more permissions to the local intranet, or to portions of it (such as specific machine share names). How do I make it so that code runs when the security system is stopping it? Security exceptions occur when code attempts to perform actions for which it has not been granted permission. Permissions are granted based on what is known about code; especially its location. For example, code run from the Internet is given fewer permissions than that run from the local machine because experience has proven that it is generally less reliable. So, to allow code to run that is failing due to security exceptions, you must increase the permissions granted to it. One simple way to do so is to move the code to a more trusted location (such as the local file system). But this won't work in all cases (web applications are a good example, and intranet applications on a corporate network are another). So, instead of changing the code's location, you can also change security policy to grant more permissions to that location. This is done using either the .NET Framework Configuration tool or the code access security policy utility (caspol.exe). If you are the code's developer or publisher, you may also digitally sign it and then modify security policy to grant more permissions to code bearing that signature. When taking any of these actions, however, remember that code is given fewer permissions because it is not from an identifiably trustworthy sourcebefore you move code to your local machine or change security policy, you should be sure that you trust the code to not perform malicious or damaging actions. How do I administer security for my machine? For an enterprise? The .NET Framework includes the .NET Framework Configuration tool, an MMC snap-in (mscorcfg.msc), to configure several aspects of the CLR including security policy. The snapin not only supports administering security policy on the local machine, but also creates enterprise policy deployment packages compatible with System Management Server and Group Policy. A command line utility, CASPol.exe, can also be used to script policy changes on the computer. In order to run either tool, in a command prompt, change the current directory to the installation directory of the .NET Framework (located in %windir %\Microsoft.Net\Framework\v1.0.2914.16\) and type mscorcfg.msc or caspol.exe.

How does evidence-based security work with Windows 2000 security? Evidence-based security (which authorizes code) works together with Windows 2000 security (which is based on log on identity). For example, to access a file, managed code must have both the code access security file permission and must also be running under a log on identity that has NTFS file access rights. The managed libraries that are included with the .NET Framework also provide classes for role-based security. These allow the application to work with Windows log on identities and user groups.

Assembly 1.It is a collection of Single file or Multiple files. 2.If it has more than one file then it contains Dynamic Link Library or an EXE File. 3.It also contains the meta data.That is also known as Assembly Manifest. 4.The Assembly Manifest contains Versioning requirements,author name,security requirements and various files that form part of assembly. There are 3 types of Assem 1) Private :- Used by only one application and store in it's own folder 2) Public :- Used by more than one application and store in GAC (Global asseb. Cache) 3) Satellite :- It is ude during localozation and Globalization

What is the difference between Namespace and Assembly? Namespace: 1. It is a Collection of names wherein each name is Unique. 2. They form the logical boundary for a Group of classes. 3. Namespace must be specified in Project-Properties. Assembly: 1. It is an Output Unit. It is a unit of Deployment & a unit of versioning. Assemblies contain MSIL code. 2. Assemblies are Self-Describing. [e.g. metadata,manifest] 3. An assembly is the primary building block of a .NET Framework application. It is a collection of functionality that is built, versioned, and deployed as a single implementation unit (as one or more files). All managed types and resources are marked either as accessible only within their implementation unit, or by code outside that unit.

Manifest:-

manifest contains the metadata + some additional tables. Metadata is data about itself whereas manifest includes references to outside classes, dependencies on other assemblies and information (tables) about that along with the metadata.Also remember Metadata is contained in assembly and modules, manifest is present in assemblies. An Assembly Manifest is nothing but some extra tables in the Metadata section of the PE file which contains the assembly's identity, culture, files, and publicly exported types, and all of the files (modules etc) that comprise the assembly. It also references other referenced assemblies on which the assembly is dependent. This is the main difference between a assembly and a module. A assembly contains a assembly manifest while a module does not contain a assembly manifest. One point to be noted here is that both assemblies and modules contain Metadata which describes them. It is the self-describing assembly manifest which gives applications on the .NET Platform independence from the registry. In layman's terms say if you have a application comprising of a assembly named Assem.exe and a module named Mod.dll. Then in the assembly manifest which will be stored within the PE Assem.exe will not only contain metadata about the classes, methods etc contained within the Assem.exe file but also it will contain references to the classes, methods etc exported in the Mod.dll file. While the module Mod.dll will only contain metadata describing itself. Where is version information stored of an assembly ? Version information is stored in assembly in manifest. What is the maximum date value that can be stored in a SMALLDATETIME data type?

December 31, 2079

What are the different type of objects fetched by the sp_tables catalog stored procedure? This catalog SP returns objects of type: Tables and Views. This includes system tables as well. Where is version information stored of an assembly ? Version information is stored in assembly in manifest. Where are shared assemblies stored in .NET? Shared Assemblies are stored in Global Assembly Cache also known as GAC. What are the contents of assembly? In general, a static assembly can consist of four elements: The assembly manifest, which contains assembly metadata. Type metadata. Microsoft intermediate language (MSIL) code that implements the types. A set of resources. What is Assembly manifest? what all details the assembly manifest will contain? Every assembly, whether static or dynamic, contains a collection of data that describes how the elements in the assembly relate to each other. The assembly manifest contains this assembly metadata. An assembly manifest contains all the metadata needed to specify the assembly's version requirements and security identity, and all metadata needed to define the scope of the assembly and resolve references to resources and classes. The assembly manifest can be stored in either a PE file (an .exe or .dll) with Microsoft intermediate language (MSIL) code or in a standalone PE file that contains only assembly manifest information. It contains Assembly name, Version number, Culture, Strong name information, List of all files in the assembly, Type reference information, Information on referenced assemblies. Difference between assembly manifest & metadata? assembly manifest - An integral part of every assembly that renders the assembly selfdescribing. The assembly manifest contains the assembly's metadata. The manifest establishes the assembly identity, specifies the files that make up the assembly implementation, specifies the types and resources that make up the assembly, itemizes the compile-time dependencies on other assemblies, and specifies the set of permissions required for the assembly to run properly. This information is used at run time to resolve references, enforce version binding policy, and validate the integrity of loaded assemblies.

The self-describing nature of assemblies also helps makes zero-impact install and XCOPY deployment feasible. metadata - Information that describes every element managed by the common language runtime: an assembly, loadable file, type, method, and so on. This can include information required for debugging and garbage collection, as well as security attributes, marshaling data, extended class and member definitions, version binding, and other information required by the runtime. Difference between type constructor and instance constructor? What is static constructor, when it will be fired? And what is its use?

(Class constructor method is also known as type constructor or type initializer) Instance constructor is executed when a new instance of type is created and the class constructor is executed after the type is loaded and before any one of the type members is accessed. (It will get executed only 1st time, when we call any static methods/fields in the same class.) Class constructors are used for static field initialization. Only one class constructor per type is permitted, and it cannot use the vararg (variable argument) calling convention. Is versioning applicable to private assemblies? Versioning concept is only applicable to global assembly cache (GAC) as private assembly lie in their individual folders.

What is GAC? A shared assembly has version constraints. It is stored in the Global Assembly Cache (GAC). GAC is a repository of shared assemblies maintained by the .NET runtime. The shared assemblies may be used by many applications. To make an assembly a shared assembly, it has to be strongly named. To know more on how to share an assembly, create a strongly named assembly Click Here GAC is located at C:\Windows\Assembly OR C:\Winnt\Assembly

How to share an assembly? How to make it strongly named? What is SN.EXE? In order to share an assembly with many applications, it must have a strong name. In order to convert a private assembly to a shared assembly, i.e. to create a strongly named assembly, follow the steps below... 1) Create a strong key using the sn.exe tool. This is used to created a cryptographic key pair. The key pair that is generated by the Strong Name tool can be kept in a file or we can store it our your local machine's Crytographic Service Provider (CSP). For this, goto the .NET command interpreter, and type the following... sn -k C:\samplekey.snk This will create a strong key and save it to the location C:\samplekey.snk 2) If the key is stored in a file, just like we have done above, we use the attribute AssemblyKeyFileAttribute. This belongs to the namespace System.Reflection.AssemblyKeyFileAttribute. If the key was in the CSP, we would make use of System.Reflection.AssemblyKeyNameAttribute. Go to the assemblyinfo.vb file of your project. Open this file. Make the following changes in this file... <assembly: assemblykeyfileattribute("C:\samplekey.snk")> We may write this in our code as well, like this... Imports System.Reflection <assembly: assemblykeyfileattribute("C:\samplekey.snk")> Namespace StrongName Public class Sample End Class End Namespace

3) Build your project. Your assembly is now strongly named. Installing the Shared assembly in GAC... Go to .NET command interpreter, use the tool gacutil.exe Type the following... gacutil /i sampleclass.dll To uninstall it, use... gacutil /u sampleclass.dll Visual Studio.NET provides a GUI tool for viewing all shared assemblies in the GAC. Folder of GAC: C:\Windows\Assembly OR C:\Winnt\Assembly

.NET Languages Versions Tools CLI CTS Metadata CLS IL VES CLR Class Library Managed Class Assembly ILDASM Reflection Assembly Types Strong Assembly GAC GC IDisposable Serialization Code Access Security Attribute Thread Globalization Generations COM

What is the concept of strong names What is the concept of strong namesHow do we generate strong names ? or What is use the of SN.EXE ? or How do we apply strong names to assembly? or How do you sign an assembly?By: fyicenter.com Strong name is similar to GUID(It is supposed to be unique in space and time) in COM components.Strong Name is only needed when we need to deploy assembly in GAC. Strong Names helps GAC to differentiate between two versions. Strong names use public key cryptography (PKC) to ensure that no one can spoof it.PKC use public key and private key concept. Following are the step to generate a strong name and sign a assembly :Go to Visual Studio Command Prompt. See below figure Visual studio Command Prompt. Note the samples are compiled in 2005 but 2003 users do not have to worry about it. Same type of command prompt will be seen in 2003 also.

After you are in command prompt type sn.exe -k gc:\test.snk h.

After generation of the file you can view the SNK file in a simple notepad. After the SNK file is generated its time to sign the project with this SNK file."

Click on project -- properties and the browse the SNK file to the respective folder and

compile the project.

Add/Remove RadControls to the Global Assembly Cache

Add to Global Assembly Cache You can add a control to the Global Assembly Cache (GAC) by using the Global Assembly Cache tool (Gacutil.exe). The Global Assembly Cache tool is automatically installed with Visual Studio. In earlier versions of the .NET Framework, the Shfusion.dll Windows shell extension enabled you to install assemblies by dragging them in Windows Explorer. Beginning with the .NET Framework version 4, Shfusion.dll is obsolete.

To install the Telerik.Web.UI assembly, open Visual Studio Command Prompt (Start > Programs > Microsoft Visual Studio <VS version> > Visual Studio Tools) and run the gacutil.exe tool with -i parameter (install) and the name of the control, e.g. [VS prompt] gacutil.exe -i "C:\Program Files (x86)\Telerik\RadControls for ASP.NET AJAX Q2 2010\Bin40\Telerik.Web.UI.dll" Remove from Global Assembly Cache In order to remove Telerik RadControls for ASP.NET AJAX from GAC, please use the following command: [VS prompt]

gacutil.exe -u Telerik.Web.UI Add/Remove RadControls to the Global Assembly Cache

The following topic describes what steps you should perform in order to add/remove the Telerik RadControls for Silverlight to the Global Assembly Cache (GAC). Add RadControls to the GAC There are two ways to add a control to the GAC: Automatically Manually

In order to automatically add Telerik RadControls for Silverlight to the GAC, you should perform the following instructions: 1. Go to Start->Control Panel->Administrative Tools and run the Microsoft .NET Framework 2.0 Configuration.

Microsoft .NET Framework 2.0 Configuration is part of the Microsoft .NET Framework Software Development Kit (SDK), which can be downloaded from here. 2. The .NET Framework 2.0 Configuration dialog will open.

3. Expand all nodes and locate Assembly Cache. Right click on it and in the context menu select Add.

4. Browse to the Telerik bin directory and select the needed DLLs. 5. Click Open.

In order to manually add Telerik RadControls for Silverlight to the GAC, you should perform the following instructions: 1. Run the .NET command prompt (Start->All Programs->Microsoft Visual Studio>Visual Studio Tools->Visual Studio Command Prompt)

2. Start the .NET gacutil.exe with -i parameter (install) and the name of the control,e.g. gacutil.exe -i "C:\Program Files\Telerik\RadControls for Silverlight\Bin\Telerik.Windows.Controls.dll"

Remove from GAC In order to remove Telerik RadControls from GAC, use the following command: gacutil.exe -u Telerik.Windows.Controls.dll

Delay Signing an Assembly Visual Studio 2005 Other Versions

An organization can have a closely guarded key pair that developers do not have access to on a daily basis. The public key is often available, but access to the private key is restricted to only a few individuals. When developing assemblies with strong names, each assembly that references the strong-named target assembly contains the token of the public key used to give the target assembly a strong name. This requires that the public key be available during the development process. You can use delayed or partial signing at build time to reserve space in the portable executable (PE) file for the strong name signature, but defer the actual signing until some later stage (typically just before shipping the assembly). The following steps outline the process to delay sign an assembly:

1. Obtain the public key portion of the key pair from the organization that will do the 2.
eventual signing. Typically this key is in the form of an .snk file, which can be created using the Strong Name tool (Sn.exe) provided by the .NET Framework SDK. Annotate the source code for the assembly with two custom attributes from System.Reflection: o AssemblyKeyFileAttribute, which passes the name of the file containing the public key as a parameter to its constructor. o AssemblyDelaySignAttribute, which indicates that delay signing is being used by passing true as a parameter to its constructor. For example: [assembly:AssemblyKeyFileAttribute("myKey.snk")] [assembly:AssemblyDelaySignAttribute(true)] 3. The compiler inserts the public key into the assembly manifest and reserves space in the PE file for the full strong name signature. The real public key must be stored while the assembly is built so that other assemblies that reference this assembly can obtain the key to store in their own assembly reference. 4. Because the assembly does not have a valid strong name signature, the verification of that signature must be turned off. You can do this by using the Vr option with the Strong Name tool. The following example turns off verification for an assembly called myAssembly.dll. sn Vr myAssembly.dll Caution Use the -Vr option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to also skip verification.

5. Later, usually just before shipping, you submit the assembly to your organization's
signing authority for the actual strong name signing using the R option with the Strong Name tool.

The following example signs an assembly called myAssembly.dll with a strong name using the sgKey.snk key pair. sn -R myAssembly.dll sgKey.snk

in simple terms:The strong name contains the public/private key pair. But at the developement time, if we want to use only the public key we should use this concept.

Delay signing is the high-end process. If we want to create the private key at the instalation time, we should use this concept. For this we set the "deley signing=true" in the assemblyinfo.vb/cs.

What are the different types of JIT ? JIT compiler is a part of the runtime execution environment. In Microsoft .NET there are three types of JIT compilers: Pre-JIT: - Pre-JIT compiles complete source code into native code in a single compilation cycle. This is done at the time of deployment of the application. Econo-JIT: - Econo-JIT compiles only those methods that are called at runtime. However, these compiled methods are removed when they are not required. Normal-JIT: - Normal-JIT compiles only those methods that are called at runtime. These methods are compiled the first time they are called, and then they are stored in cache. When the same methods are called again, the compiled code from cache is used for execution.

Complete Comparison for VB.NET and C# Contents

1. 2. 3. 4. 5. 6. 7. 8.

Introduction Advantages of both languages Keyword Differences Data types Differences Operators Differences Programming Difference New Features of both languages in 2005 version Conclusion 9. History Introduction Some people like VB.NET's natural language, case-insensitive approach, others like C#'s terse syntax. But both have access to the same framework libraries. We will discuss about the differences in the following topics: 1. Advantages of both languages 2. Keyword Differences

3. Data types Differences 4. Operators Differences 5. Programming Difference


Advantages of both languages VB.NET C# Support for optional parameters - very handy for some COM interoperability. Support for late binding with Option Strict off - type safety at compile time goes out of the window, but legacy libraries which don't have strongly typed interfaces become easier to use. Support for named indexers. Various legacy VB functions (provided in the Microsoft.VisualBasic namespace, and can be used by other languages with a reference to the Microsoft.VisualBasic.dll). Many of these can be harmful to performance if used unwisely, however, and many people believe they should be avoided for the most part. The with construct: it's a matter of debate as to whether this is an advantage or not, but it's certainly a difference. Simpler (in expression - perhaps more complicated in understanding) event handling, where a method can declare that it handles an event, rather than the handler having to be set up in code. The ability to implement interfaces with methods of different names. (Arguably this makes it harder to find the implementation of an interface, however.) Catch ... When ... clauses, which allow exceptions to be filtered based on runtime expressions rather than just by type. The VB.NET parts of Visual Studio .NET compiles your code in the background. While this is considered as an advantage for small projects, people creating very large projects have found that the IDE slows down considerably as the project gets larger.

XML documentation generated from source code comments. (This is coming in VB.NET with Whidbey (the code name for the next version of Visual Studio and .NET), and there are tools which will do it with existing VB.NET code already.) Operator overloading - again, coming to VB.NET in Whidbey. Language support for unsigned types (you can use them from VB.NET, but they aren't in the language itself). Again, support for these is coming to VB.NET in Whidbey. The using statement, which makes unmanaged resource disposal simple. Explicit interface implementation, where an interface which is already implemented in a base class can be re-implemented separately in a derived class. Arguably this makes the class harder to understand, in the same way that member hiding normally does. Unsafe code. This allows pointer arithmetic etc, and can improve performance in some situations. However, it is not to be used lightly, as a lot of the normal safety of C# is lost (as the name implies). Note that unsafe code is still managed code, i.e., it is compiled to IL, JITted, and run within the CLR.

Keyword Differences Purpose VB.NET C#

Declare a variable

Declare a named constant Create a new object New, CreateObject() Function/method does Sub not return a value Overload a function or Overloads method (Visual Basic: overload a procedure or method) Refer to the current Me object Make a nonvirtual call MyClass to a virtual method of the current object Retrieve character GetChar Function from a string Declare a compound Structure <members> End data type (Visual Structure Basic: Structure) Initialize an object Sub New() (constructors) Terminate an object n/a directly Method called by the Finalize system just before garbage collection reclaims an object7 Initialize a variable Collapse where it is declared Dim x As Long = 5 Collapse Dim c As New _ Car(FuelTypeEnum.Gas)

Private, Public, Friend, Protected, Static1, Shared, Dim Const

declarators (keywords include userdefined types and built-in types) const new void (No language keyword required for this purpose)

this n/a

[] struct, class, interface

Constructors, or system default type constructors n/a destructor

Collapse // initialize to a value: int x = 123; // or use default // constructor: int x = new int(); delegate

Take the address of a AddressOf (For class function members, this operator returns a reference to a function in the form of a delegate instance) Declare that an object n/a can be modified asynchronously Force explicit Option Explicit

volatile

n/a. (All variables must be declared

declaration of variables Test for an object obj = Nothing variable that does not refer to an object Value of an object Nothing variable that does not refer to an object Test for a database IsDbNull null expression Test whether a n/a Variant variable has been initialized Define a default Default property Refer to a base class MyBase Declare an interface Interface Specify an interface to Implements (statement) be implemented Declare a class Class <implementation> Specify that a class MustInherit can only be inherited. An instance of the class cannot be created. Specify that a class NotInheritable cannot be inherited Declare an Enum <members> End Enum enumerated type Declare a class Const constant Derive a class from a Inherits C2 base class Override a method Overrides Declare a method that MustOverride must be implemented in a deriving class Declare a method that NotOverridable (Methods are can't be overridden not overridable by default.) Declare a virtual Overridable method, property (Visual Basic), or property accessor (C#, C++) Hide a base class Shadowing member in a derived class Declare a typesafe Delegate

prior to use) obj == null

null

n/a n/a

by using indexers base interface class C1 : I1 class abstract

sealed enum const (Applied to a field declaration) class C1 : C2 override abstract

sealed virtual

n/a

delegate

reference to a class method Specify that a variable WithEvents can contain an object whose events you wish to handle Specify the events for Handles (Event procedures which an event can still be associated with a procedure will be WithEvents variable by called naming pattern.) Evaluate an object Collapse expression once, in With objExpr order to access <.member> multiple members <.member> End With Structured exception Collapse handling Try <attempt> Catch <handle errors> Finally <always execute> End Try Decision structure Select Case ..., Case, Case (selection) Else, End Select Decision structure If ... Then, ElseIf ... Then, (if ... then) Else, End If Loop structure While, Do [While, Until] ..., (conditional) Loop [While, Until] Loop structure For ..., [Exit For], Next (iteration) For Each ..., [Exit For,] Next Declare an array Collapse Dim a() As Long Collapse

(Write code - no specific keyword)

n/a

n/a

try, catch, finally, throw

switch, case, default, goto, break if, else do, while, continue for, foreach Collapse int[] x = new int[5]; Collapse

Initialize an array

Reallocate array Visible outside the project or assembly Invisible outside the Friend assembly (C#/Visual Basic) or within the package (Visual J#, JScript) Visible only within the Private project (for nested classes, within the

Dim a() As Long = {3, 4, 5} int[] x = new int[5] { 1, 2, 3, 4, 5}; Redim n/a Public public internal

private

enclosing class) Accessible outside class and project or module Accessible outside the class, but within the project Only accessible within class or module Only accessible to current and derived classes Preserve procedure's local variables Shared by all instances of a class Comment code Case-sensitive? Call Windows API Declare and raise an event Threading primitives Go to

Public

public

Friend

internal

Private Protected

private protected

Static Shared ' Rem No Declare <API> Event, RaiseEvent SyncLock Goto

n/a static //, /* */ for multi-line comments /// for XML comments Yes use Platform Invoke event lock goto

Data types Differences Purpose/Size Decimal Date (varies) 1 byte 2 bytes 2 bytes 4 8 4 8 bytes bytes bytes bytes VB.NET Decimal Date String Byte Boolean Short, Char (Unicode character) Integer Long Single Double C# decimal DateTime string byte bool short, char (Unicode character) int long float double

Operators Differences Purpose Integer division Modulus (division returning only the VB.NET \ Mod C# / %

remainder) Exponentiation ^ Integer division \= Assignment Concatenate &= NEW Modulus n/a Bitwise-AND n/a Bitwise-exclusive-OR n/a Bitwise-inclusive-OR n/a Equal = Not equal <> Compare two object Is reference variables Compare object reference TypeOf x Is Class1 type Concatenate strings & Shortcircuited Boolean AndAlso AND Shortcircuited Boolean OR OrElse Scope resolution . Array element () Type cast Cint, CDbl, ..., CType Postfix increment n/a Postfix decrement n/a Indirection n/a Address of AddressOf Logical-NOT One's complement Prefix increment Prefix decrement Size of type Bitwise-AND Bitwise-exclusive-OR Bitwise-inclusive-OR Logical-AND Logical-OR Conditional Pointer to member Not Not n/a n/a n/a And Xor Or And Or If Function () n/a

n/a /= += %= &= ^= |= == != == x is Class1 + && || . and base [] (type) ++ -* (unsafe mode only) & (unsafe mode only; also see fixed) ! ~ ++ -sizeof & ^ | && || ?: . (Unsafe mode only)

Programming Difference Purpose Declaring VB.NET Collapse C# Collapse

Variables

Dim x As Integer Public x As Integer = 10 Comments Collapse ' comment x = 1 ' comment Rem comment Assignment Collapse Statements nVal = 7 Conditional Collapse Statements If nCnt <= nMax Then ' Same as nTotal = ' nTotal + nCnt. nTotal += nCnt ' Same as nCnt = nCnt + 1. nCnt += 1 Else nTotal += nCnt nCnt -= 1 End If Collapse Select Case n Case 0 MsgBox ("Zero") ' Visual Basic .NET exits ' the Select at ' the end of a Case. Case 1 MsgBox ("One") Case 2 MsgBox ("Two") Case Else MsgBox ("Default") End Select

int x; int x = 10; Collapse // comment /* multiline comment */ Collapse nVal = 7; Collapse if (nCnt <= nMax) { nTotal += nCnt; nCnt++; } else { nTotal +=nCnt; nCnt--; }

Selection Statements

Collapse switch(n) { case 0: Console.WriteLine("Zero"); break; case 1: Console.WriteLine("One"); break; case 2: Console.WriteLine("Two"); break; default: Console.WriteLine("?"); break; }

FOR Loops

Collapse For n = 1 To 10

Collapse for (int i = 1; i <= 10; i++)

MsgBox("The number is " & n) Next For Each prop In obj prop = 42 Next prop Hiding Base Collapse Class Public Class BaseCls Members ' The element to be shadowed Public Z As Integer = 100 public Sub Test() System.Console.WriteLine( _ "Test in BaseCls") End Sub End Class Public Class DervCls Inherits BaseCls ' The shadowing element. Public Shadows Z As String = "*" public Shadows Sub Test() System.Console.WriteLine( _ "Test in DervCls") End Sub End Class Public Class UseClasses ' DervCls widens to BaseCls. Dim BObj As BaseCls = New DervCls() ' Access through derived ' class. Dim DObj As DervCls = New DervCls() Public Sub ShowZ() System.Console.WriteLine( _ "Accessed through base "&_ "class: " & BObj.Z) System.Console.WriteLine(_ "Accessed through derived "&_ "class: " & DObj.Z) BObj.Test() DObj.Test() End Sub End Class

Console.WriteLine( "The number is {0}", i); foreach(prop current in obj) { current=42; } Collapse public class BaseCls { // The element to be hidden public int Z = 100; public void Test() { System.Console.WriteLine( "Test in BaseCls"); }

public class DervCls : BaseCls { // The hiding element public new string Z = "*"; public new void Test() { System.Console.WriteLine( "Test in DervCls"); }

public class UseClasses { // DervCls widens to BaseCls BaseCls BObj = new DervCls(); // Access through derived //class DervCls DObj = new DervCls(); public void ShowZ() { System.Console.WriteLine( "Accessed through " + "base class: {0}", BObj.Z); System.Console.WriteLine( "Accessed through" + " derived class:{0}", DObj.Z);

} WHILE Loops Collapse ' Test at start of loop While n < 100 . ' Same as n = n + 1. n += 1 End While ' Parameter Collapse Passing by ' The argument Y is Value 'passed by value. Public Sub ABC( _ ByVal y As Long) 'If ABC changes y, the ' changes do not affect x. End Sub ABC(x) ' Call the procedure. ' You can force parameters to ' be passed by value, ' regardless of how ' they are declared, ' by enclosing ' the parameters in ' extra parentheses. ABC((x)) Parameter Collapse Passing by Reference Public Sub ABC(ByRef y As Long) ' The parameter y is declared 'by referece:

BObj.Test(); DObj.Test(); } Collapse

while (n < 100) n++;

Collapse /* Note that there is no way to pass reference types (objects) strictly by value. You can choose to either pass the reference (essentially a pointer), or a reference to the reference (a pointer to a pointer).*/ // The method: void ABC(int x) { ... } // Calling the method: ABC(i);

Collapse /* Note that there is no way to pass reference types (objects) strictly by value. You can choose to either pass the reference

' If ABC changes y, the changes are ' made to the value of x. End Sub ABC(x) ' Call the procedure.

(essentially a pointer), or a reference to the reference (a pointer to a pointer).*/ // Note also that unsafe C# //methods can take pointers //just like C++ methods. For //details, see unsafe. // The method: void ABC(ref int x) { ... } // Calling the method: ABC(ref i); Collapse // try-catch-finally try { if (x == 0) throw new System.Exception( "x equals zero"); else throw new System.Exception( "x does not equal zero"); } catch (System.Exception err) { System.Console.WriteLine( err.Message); } finally { System.Console.WriteLine( "executing finally block"); }

Structured Collapse Exception Try Handling If x = 0 Then Throw New Exception( _ "x equals zero") Else Throw New Exception( _ "x does not equal zero") End If Catch err As System.Exception MsgBox( _ "Error: " & Err.Description) Finally MsgBox( _ "Executing finally block.") End Try

Set an Collapse Object Reference o = Nothing to Nothing Initializing Collapse

Collapse o = null; Collapse

Value TypesDim dt as New System.DateTime( _ 2001, 4, 12, 22, 16, 49, 844) System.DateTime dt = new System.DateTime( 2001, 4, 12, 22, 16, 49, 844); New Features of both languages in 2005 version VB.NET C# Visual Basic 2005 has many new and improved With the release of Visual Studio 2005, the language features -- such as inheritance, C# language has been updated to version interfaces, overriding, shared members, and 2.0. This language has following new overloading -- that make it a powerful objectfeatures: oriented programming language. As a Visual Basic developer, you can now create 1. Generics types are added to the multithreaded, scalable applications using explicit language to enable programmers to multithreading. This language has following new achieve a high level of code reuse features, and enhanced performance for collection classes. Generic types can 1. Continue Statement, which immediately differ only by arity. Parameters can skips to the next iteration of a Do, For, or also be forced to be specific types. While loop. 2. Iterators make it easier to dictate 2. IsNot operator, which you can avoid using how a for each loop will iterate over the Not and Is operators in an awkward a collection's contents. order. 3. 3. Using...End. Using statement block Collapse ensures disposal of a system resource when your code leaves the block for any // Iterator Example reason. Collapse Public Sub setbigbold( _ ByVal c As Control) Using nf As New _ System.Drawing.Font("Arial",_ 12.0F, FontStyle.Bold) c.Font = nf c.Text = "This is" &_ "12-point Arial bold" End Using End Sub public class NumChar { string[] saNum = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Zero"}; public System.Collections.IEnumerator GetEnumerator() { foreach (string num in saNum) yield return num; } } // Create an instance of // the collection class NumChar oNumChar = new NumChar();

4. Explicit Zero Lower Bound on an

Array, Visual Basic now permits an array declaration to specify the lower bound (0) of each dimension along with the upper bound. 5. Unsigned Types, Visual Basic now

supports unsigned integer data types (UShort, UInteger, and ULong) as well as the signed type SByte. 6. Operator Overloading, Visual Basic now allows you to define a standard operator (such as +, &, Not, or Mod) on a class or structure you have defined. 7. Partial Types, to separate generated code from your authored code into separate source files. 8. Visual Basic now supports type parameters on generic classes, structures, interfaces, procedures, and delegates. A corresponding type argument specifies at compilation time the data type of one of the elements in the generic type. 9. Custom Events. You can declare custom events by using the Custom keyword as a modifier for the Event statement. In a custom event, you specify exactly what happens when code adds or removes an event handler to or from the event, or when code raises the event. 10. Compiler Checking Options, The /nowarn and /warnaserror options provide more control over how warnings are handled. Each one of these compiler options now takes a list of warning IDs as an optional parameter, to specify to which warnings the option applies. 11. There are eight new command-line compiler options: a. The /codepage option specifies which codepage to use when opening source files. b. The /doc option generates an XML documentation file based on comments within your code. c. The /errorreport option provides a convenient way to report a Visual Basic internal compiler error to Microsoft. d. The /filealign option specifies the size of sections in your output file. e. The /noconfig option causes the compiler to ignore the Vbc.rsp file. f. The /nostdlib option prevents the import of mscorlib.dll, which defines the entire System namespace. g. The /platform option specifies the processor to be targeted by the

// Iterate through it with foreach foreach (string num in oNumChar) Console.WriteLine(num);

3. Partial type definitions allow a


single type, such as a class, to be split into multiple files. The Visual Studio designer uses this feature to separate its generated code from user code. 4. Nullable types allow a variable to contain a value that is undefined. 5. Anonymous Method is now possible to pass a block of code as a parameter. Anywhere a delegate is expected, a code block can be used instead: There is no need to define a new method. Collapse button1.Click += delegate { MessageBox.Show( "Click!") };

6. . The namespace alias qualifier

(::) provides more control over accessing namespace members. The global :: alias allows to access the root namespace that may be hidden by an entity in your code. 7. Static classes are a safe and convenient way of declaring a class containing static methods that cannot be instantiated. In C# v1.2 you would have defined the class constructor as private to prevent the class being instantiated. 8. 8. There are eight new compiler options: a. /langversion option: Can be used to specify compatibility with a specific version of the language. b. /platform option: Enables you to target IPF (IA64 or Itanium) and AMD64 architectures. c. #pragma warning: Used to disable and enable individual

output file, in those situations where it is necessary to explicitly specify it.

warnings in code.

d. /linkresource option:

Contains additional options. used to report internal compiler errors to Microsoft over the Internet.

e. /errorreport option: Can be h. The /unify option suppresses


warnings resulting from a mismatch between the versions of directly and indirectly referenced assemblies.

f. /keycontainer and

/keyfile: Support specifying cryptographic keys.

what is the difference between system exception and application exception There r 2 important classes in the hierarchy that r derived from System.Exception: 1) System.SystemException -> This class is for exceptions that r usually thrown by the .net runtime, or which r considered to be of a generic nature and must be thrown by almost any application. For example, StackOverflowException will be thrown by the .net runtime if it detects the stack is full. On the other hand, u might choose to throw ArgumentException or its subclasses in ur code, if u detect that a method has been called with inappropriate arguments. Subclasses of System.SystemException includes classes that represent both fatal and non-fatal errors. 2) System.ApplicationException-> This class is important, becoz it is the intended base for any class of exception defined by third parties. Hence, if u define any exceptions covering error conditions unique to ur application, u should derive these directly or indirectly from System.ApplicationException

Understanding .NET Code Access Security

Introduction Over the past years, I've learned many things from CodeProject ... and now I'm giving back to the CodeProject. Since I didn't find any articles on Code Access Security, here's my one. Enjoy! I'm not going to bore you with theory, but before we wet our feet, there are some concepts, keywords that you should learn. .NET has two kinds of security:

1. Role Based Security (not being discussed in this article) 2. Code Access Security
The Common Language Runtime (CLR) allows code to perform only those operations that the code has permission to perform. So CAS is the CLR's security system that enforces

security policies by preventing unauthorized access to protected resources and operations. Using the Code Access Security, you can do the following: Restrict what your code can do Restrict which code can call your code Identify code

We'll be discussing about these things through out this article. Before that, you should get familiar with the jargon. Jargon Code access security consists of the following elements: permissions permission sets code groups evidence policy

Permissions Permissions represent access to a protected resource or the ability to perform a protected operation. The .NET Framework provides several permission classes, like FileIOPermission (when working with files), UIPermission (permission to use a user interface), SecurityPermission (this is needed to execute the code and can be even used to bypass security) etc. I won't list all the permission classes here, they are listed below. Permission sets A permission set is a collection of permissions. You can put FileIOPermission and UIPermission into your own permission set and call it "My_PermissionSet". A permission set can include any number of permissions. FullTrust, LocalIntranet, Internet, Execution and Nothing are some of the built in permission sets in .NET Framework. FullTrust has all the permissions in the world, while Nothing has no permissions at all, not even the right to execute. Code groups Code group is a logical grouping of code that has a specified condition for membership. Code from http://www.somewebsite.com/ can belong to one code group, code containing a specific strong name can belong to another code group and code from a specific assembly can belong to another code group. There are built-in code groups like My_Computer_Zone, LocalIntranet_Zone, Internet_Zone etc. Like permission sets, we can create code groups to meet our requirements based on the evidence provided by .NET Framework. Site, Strong Name, Zone, URL are some of the types of evidence. Policy Security policy is the configurable set of rules that the CLR follows when determining the permissions to grant to code. There are four policy levels - Enterprise, Machine, User and

Application Domain, each operating independently from each other. Each level has its own code groups and permission sets. They have the hierarchy given below.

Figure 1 Okay, enough with the theory, it's time to put the theory into practice. Quick Example Let's create a new Windows application. Add two buttons to the existing form. We are going to work with the file system, so add the System.IO namespace. Collapse using System.IO;

Figure 2 Write the following code: Collapse private void btnWrite_click(object sender, System.EventArgs e)

StreamWriter myFile = new StreamWriter("c:\\Security.txt"); myFile.WriteLine("Trust No One"); myFile.Close();

} private void btnRead_click(object sender, System.EventArgs e) { StreamReader myFile = new StreamReader("c:\\Security.txt"); MessageBox.Show(myFile.ReadLine()) myFile.Close() } The version number should be intact all the time, for our example to work. Make sure that you set the version number to a fixed value, otherwise it will get incremented every time you compile the code. We're going to sign this assembly with a strong name which is used as evidence to identify our code. That's why you need to set the version number to a fixed value. Collapse [assembly: AssemblyVersion("1.0.0.0")] That's it ... nothing fancy. This will write to a file named Security.txt in C: drive. Now run the code, it should create a file and write the line, everything should be fine ... unless of course you don't have a C: drive. Now what we are going to do is put our assembly into a code group and set some permissions. Don't delete the Security.txt file yet, we are going to need it later. Here we go. .NET Configuration Tool We can do this in two ways, from the .NET Configuration Tool or from the command prompt using caspol.exe. First we'll do this using the .NET Configuration Tool. Go to Control Panel --> Administrative Tools --> Microsoft .NET Framework Configuration. You can also type "mscorcfg.msc" at the .NET command prompt. You can do cool things with this tool ... but right now we are only interested in setting code access security.

Figure 3 Creating a new permission set Expand the Runtime Security Policy node. You can see the security policy levels Enterprise, Machine and User. We are going to change the security settings in Machine policy. First we are going to create our own custom permission set. Right click the Permission Sets node and choose New. Since I couldn't think of a catchy name, I'm going to name it MyPermissionSet.

Figure 4 In the next screen, we can add permissions to our permission set. In the left panel, we can see all the permissions supported by the .NET Framework. Now get the properties of File IO permission. Set the File Path to C:\ and check Read only, don't check others. So we didn't give write permission, we only gave read permission. Please note that there is another option saying "Grant assemblies unrestricted access to the file system." If this is selected, anything can be done without any restrictions for that particular resource, in this case the file system.

Figure 5 Now we have to add two more permissions - Security and User Interface. Just add them and remember to set the "Grant assemblies unrestricted access". I'll explain these properties soon. Without the Security permission, we don't have the right to execute our code, and without the User Interface permission, we won't be able to show a UI. If you're done adding these three permissions, you can see there is a new permission set created, named MyPermissionSet. Creating a new code group Now we will create a code group and set some conditions, so our assembly will be a member of that code group. Notice that in the code groups node, All_Code is the parent node. Right Click the All_Code node and choose New. You'll be presented with the Create Code Group wizard. I'm going to name it MyCodeGroup.

Figure 6 In the next screen, you have to provide a condition type for the code group. Now these are the evidence that I mentioned earlier. For this example, we are going to use the Strong Name condition type. First, sign your assembly with a strong name and build the project. Now press the Import button and select your assembly. Public Key, Name and Version will be extracted from the assembly, so we don't have to worry about them. Now move on to the next screen. We have to specify a permission set for our code group. Since we have already created one - MyPermissionSet, select it from the list box.

Figure 7 Exclusive and LevelFinal If you haven't messed around with the default .NET configuration security settings, your assembly already belongs to another built-in code group - My_Computer_Zone. When permissions are calculated, if a particular assembly falls into more than one code group within the same policy level, the final permissions for that assembly will be the union of all the permissions in those code groups. I'll explain how to calculate permissions later, for the time being we only need to run our assembly only with our permission set and that is MyPermissionSet associated with the MyCodeGroup. So we have to set another property to do just that. Right click the newly created MyCodeGroup node and select Properties. Check the check box saying "This policy level will only have the permissions from the permission set associated with this code group." This is called the Exclusive attribute. If this is checked then the run time will never grant more permissions than the permissions associated with this code group. The other option is called LevelFinal. These two properties come into action when calculating permissions and they are explained below in detail.

Figure 8 I know we have set lots of properties, but it'll all make sense at the end (hopefully). Okay .. it's time to run the code. What we have done so far is, we have put our code into a code group and given permissions only to read from C: drive. Run the code and try both buttons. Read should work fine, but when you press Write, an exception will be thrown because we didn't set permission to write to C: drive. Below is the error message that you get.

Figure 9

So thanks to Code Access Security, this kind of restriction to a resource is possible. There's a whole lot more that you can do with Code Access Security, which we're going to discuss in the rest of this article. Functions of Code Access Security According to the documentation, Code Access Security performs the following functions: (straight from the documentation) Defines permissions and permission sets that represent the right to access various system resources. Enables administrators to configure security policy by associating sets of permissions with groups of code (code groups). Enables code to request the permissions it requires in order to run, as well as the permissions that would be useful to have, and specifies which permissions the code must never have. Grants permissions to each assembly that is loaded, based on the permissions requested by the code and on the operations permitted by security policy. Enables code to demand that its callers have specific permissions. Enables code to demand that its callers possess a digital signature, thus allowing only callers from a particular organization or site to call the protected code. Enforces restrictions on code at run time by comparing the granted permissions of every caller on the call stack to the permissions that callers must have.

We have already done the top two, and that is the administrative part. There's a separate namespace that we haven't looked at yet - System.Security, which is dedicated to implementing security. Security Namespace These are the main classes in System.Security namespace: Classes CodeAccessPermission PermissionSet SecurityException Description Defines the underlying structure of all code access permissions. Represents a collection that can contain many different types of permissions. The exception that is thrown when a security error is detected.

These are the main classes in System.Security.Permissions namespace: Classes EnvironmentPermission FileDialogPermission FileIOPermission Description Controls access to system and user environment variables. Controls the ability to access files or folders through a file dialog. Controls the ability to access files and

folders. IsolatedStorageFilePermission IsolatedStoragePermission ReflectionPermission RegistryPermission SecurityPermission UIPermission Specifies the allowed usage of a private virtual file system. Represents access to generic isolated storage capabilities. Controls access to metadata through the System.Reflection APIs. Controls the ability to access registry variables. Describes a set of security permissions applied to code. Controls the permissions related to user interfaces and the clipboard.

You can find more permission classes in other namespaces. For example, SocketPermission and WebPermission in System.Net namespace, SqlClientPermission in System.Data.SqlClient namespace, PerformanceCounterPermission in System.Diagnostics namespace etc. All these classes represent a protected resource. Next, we'll see how we can use these classes. Declarative vs. Imperative You can use two different kinds of syntax when coding, declarative and imperative. Declarative syntax Declarative syntax uses attributes to mark the method, class or the assembly with the necessary security information. So when compiled, these are placed in the metadata section of the assembly. Collapse [FileIOPermission(SecurityAction.Demand, Unrestricted=true)] public calss MyClass { public MyClass() {...} // all these methods public void MyMethod_A() {...} // demands unrestricted access to public void MyMethod_B() {...} // the file system } Imperative syntax Imperative syntax uses runtime method calls to create new instances of security classes. Collapse public calss MyClass

public MyClass() { } public void Method_A() { // Do Something FileIOPermission myPerm = new FileIOPermission(PermissionState.Unrestricted); myPerm.Demand(); // rest of the code won't get executed if this failed // Do Something } // No demands public void Method_B() { // Do Something

The main difference between these two is, declarative calls are evaluated at compile time while imperative calls are evaluated at runtime. Please note that compile time means during JIT compilation (IL to native). There are several actions that can be taken against permissions.

First, let's see how we can use the declarative syntax. Take the UIPermission class. Declarative syntax means using attributes. So we are actually using the UIPermissionAttribute class. When you refer to the MSDN documentation, you can see these public properties: Action - one of the values in SecurityAction enum (common) Unrestricted - unrestricted access to the resource (common) Clipboard - type of access to the clipboard, one of the values in UIPermissionClipboard enum (UIPermission specific) Window - type of access to the window, one of the values in UIPermissionWindow enum (UIPermission specific).

Action and Unrestricted properties are common to all permission classes. Clipboard and Window properties are specific to UIPermission class. You have to provide the action that you are taking and the other properties that are specific to the permission class you are using. So in this case, you can write like the following: Collapse [UIPermission(SecurityAction.Demand, Clipboard=UIPermissionClipboard.AllClipboard)] or with both Clipboard and Window properties: Collapse [UIPermission(SecurityAction.Demand, Clipboard=UIPermissionClipboard.AllClipboard, Window=UIPermissionWindow.AllWindows)] If you want to declare a permission with unrestricted access, you can do it as the following: Collapse [UIPermission(SecurityAction.Demand, Unrestricted=true)] When using imperative syntax, you can use the constructor to pass the values and later call the appropriate action. We'll take the RegistryPermission class. Collapse RegistryPermission myRegPerm = new RegistryPermission(RegistryPermissionAccess.AllAccess, "HKEY_LOCAL_MACHINE\\Software"); myRegPerm.Demand(); If you want unrestricted access to the resource, you can use PermissionState enum in the following way: Collapse RegistryPermission myRegPerm = new RegistryPermission(PermissionState.Unrestricted); myRegPerm.Demand();

This is all you need to know to use any permission class in the .NET Framework. Now, we'll discuss about the actions in detail. Security Demands Demands are used to ensure that every caller who calls your code (directly or indirectly) has been granted the demanded permission. This is accomplished by performing a stack walk. What .. a cat walk? No, that's what your girl friend does. I mean a stack walk. When demanded for a permission, the runtime's security system walks the call stack, comparing the granted permissions of each caller to the permission being demanded. If any caller in the call stack is found without the demanded permission then a SecurityException is thrown. Please look at the following figure which is taken from the MSDN documentation.

Figure 10 Different assemblies as well as different methods in the same assembly are checked by the stack walk. Now back to demands. These are the three types of demands. Demand Link Demand Inheritance Demand

Demand Try this sample coding. We didn't use security namespaces before, but we are going to use them now. Collapse using System.Security; using System.Security.Permissions; Add another button to the existing form. Collapse private void btnFileRead_Click(object sender, System.EventArgs e)

try {

InitUI(1); } catch (SecurityException err) { MessageBox.Show(err.Message,"Security Error"); } catch (Exception err) { MessageBox.Show(err.Message,"Error"); }

InitUI just calls the ShowUI function. Note that it has been denied permission to read the C: drive. Collapse // Access is denied for this function to read from C: drive // Note: Using declrative syntax [FileIOPermission(SecurityAction.Deny,Read="C:\\")] private void InitUI(int uino) { // Do some initializations ShowUI(uino); // call ShowUI } ShowUI function takes uino in and shows the appropriate UI. Collapse private void ShowUI(int uino) { switch (uino) { case 1: // That's our FileRead UI ShowFileReadUI(); break; case 2: // Show someother UI } } ShowFileReadUI shows the UI related to reading files. Collapse private void ShowFileReadUI() break;

MessageBox.Show("Before calling demand"); FileIOPermission myPerm = new FileIOPermission(FileIOPermissionAccess.Read, "C:\\"); myPerm.Demand(); // All callers must have read permission to C: drive // Note: Using imperative syntax // code to show UI MessageBox.Show("Showing FileRead UI"); // This is excuted if only the Demand is successful.

I know that this is a silly example, but it's enough to do the job. Now run the code. You should get the "Before calling demand" message, and right after that the custom error message - "Security Error". What went wrong? Look at the following figure:

Figure 11 We have denied read permission for the InitUI method. So when ShowFileReadUI demands read permission to C: drive, it causes a stack walk and finds out that not every caller is granted the demanded permission and throws an exception. Just comment out the Deny statement in InitUI method, then this should be working fine because all the callers have the demanded permission. Note that according to the documentation, most classes in .NET Framework already have demands associated with them. For example, take the StreamReader class. StreamReader automatically demands FileIOPermission. So placing another demand just before it causes an unnecessary stack walk. Link Demand

A link demand only checks the immediate caller (direct caller) of your code. That means it doesn't perform a stack walk. Linking occurs when your code is bound to a type reference, including function pointer references and method calls. A link demand can only be applied declaratively. Collapse [FileIOPermission(SecurityAction.LinkDemand,Read="C:\\")] private void MyMethod() { // Do Something } Inheritance Demand Inheritance demands can be applied to classes or methods. If it is applied to a class, then all the classes that derive from this class must have the specified permission. Collapse [SecurityPermission(SecurityAction.InheritanceDemand)] private class MyClass() { // what ever } If it is applied to a method, then all the classes that derive from this class must have the specified permission to override that method. Collapse private class MyClass() { public class MyClass() {} [SecurityPermission(SecurityAction.InheritanceDemand)] public virtual void MyMethod() { // Do something } }

Like link demands, inheritance demands are also applied using declarative syntax only. Requesting Permissions Imagine a situation like this. You have given a nice form to the user with 20+ fields to enter and at the end, all the information would be saved to a text file. The user fills all the necessary fields and when he tries to save, he'll get this nice message saying it doesn't have the necessary permission to create a text file! Of course you can try to calm him down explaining all this happened because of a thing called stack walk .. caused by a demand ..

and if you are really lucky you can even get away by blaming Microsoft (believe me ... sometimes it works!). Wouldn't it be easier if you can request the permissions prior to loading the assembly? Yes you can. There are three ways to do that in Code Access Security. RequestMinimum RequestOptional RequestRefuse

Note that these can only be applied using declarative syntax in the assembly level, and not to methods or classes. The best thing in requesting permissions is that the administrator can view the requested permissions after the assembly has been deployed, using the permview.exe (Permission View Tool), so what ever the permissions needed can be granted. RequestMinimum You can use RequestMinimum to specify the permissions your code must have in order to run. The code will be only allowed to run if all the required permissions are granted by the security policy. In the following code fragment, a request has been made for permissions to write to a key in the registry. If this is not granted by the security policy, the assembly won't even get loaded. As mentioned above, this kind of request can only be made in the assembly level, declaratively. Collapse using System; using System.Windows.Forms; using System.IO; using System.Security; using System.Security.Permissions; // placed in assembly level // using declarative syntax [assembly:RegistryPermission(SecurityAction.RequestMinimum, Write="HKEY_LOCAL_MACHINE\\Software")] namespace SecurityApp { // Rest of the implementation } RequestOptional Using RequestOptional, you can specify the permissions your code can use, but not required in order to run. If somehow your code has not been granted the optional permissions, then you must handle any exceptions that is thrown while code segments that need these optional permissions are being executed. There are certain things to keep in mind when working with RequestOptional.

If you use RequestOptional with RequestMinimum, no other permissions will be granted except these two, if allowed by the security policy. Even if the security policy allows additional permissions to your assembly, they won't be granted. Look at this code segment: Collapse [assembly:FileIOPermission(SecurityAction.RequestMinimum, Read="C:\\")] [assembly:FileIOPermission(SecurityAction.RequestOptional, Write="C:\\")] The only permissions that this assembly will have are read and write permissions to the file system. What if it needs to show a UI? Then the assembly still gets loaded but an exception will be thrown when the line that shows the UI is executing, because even though the security policy allows UIPermission, it is not granted to this assembly. Note that, like RequestMinimum, RequestOptional doesn't prevent the assembly from being loaded, but throws an exception at run time if the optional permission has not been granted. RequestRefuse You can use RequestRefuse to specify the permissions that you want to ensure will never be granted to your code, even if they are granted by the security policy. If your code only wants to read files, then refusing write permission would ensure that your code cannot be misused by a malicious attack or a bug to alter files. Collapse [assembly:FileIOPermission(SecurityAction.RequestRefuse, Write="C:\\")] Overriding Security Sometimes you need to override certain security checks. You can do this by altering the behavior of a permission stack walk using these three methods. They are referred to as stack walk modifiers. Assert You can call the Assert method to stop the stack walk from going beyond the current stack frame. So the callers above the method that has used Assert are not checked. If you can trust the upstream callers, then using Assert would do no harm. You can use the previous example to test this. Modify the code in ShowUI method, just add the two new lines shown below: Collapse private void ShowUI(int uino) { // using imperative syntax to create a instance of FileIOPermission FileIOPermission myPerm = new Assert Deny PermitOnly

FileIOPermission(FileIOPermissionAccess.Read, "C:\\"); myPerm.Assert(); // don't check above stack frames. switch (uino) { case 1: // That's our FileRead UI ShowFileReadUI(); break; case 2: // Show someother UI break; } CodeAccessPermission.RevertAssert(); } Make sure that the Deny statement is still there in InitUI method. Now run the code. It should be working fine without giving any exceptions. Look at the following figure: // cancel assert

Figure 12 Even though InitUI doesn't have the demanded permission, it is never checked because the stack walk stops from ShowUI. Look at the last line. RevertAssert is a static method of CodeAccessPermission. It is used after an Assert to cancel the Assert statement. So if the code below RevertAssert is accessing some protected resources, then a normal stack walk would be performed and all callers would be checked. If there's no Assert for the current stack frame, then RevertAssert has no effect. It is a good practice to place the RevertAssert in a finally block, so it will always get called. Note that to use Assert, the Assertion flag of the SecurityPermission should be set. Warning from Microsoft!: If asserts are not handled carefully it may lead into luring attacks where malicious code can call our code through trusted code.

Deny We have used this method already in the previous example. The following code sample shows how to deny permission to connect to a restricted website using imperative syntax: Collapse WebPermission myWebPermission = new WebPermission(NetworkAccess.Connect, "http://www.somewebsite.com"); myWebPermission.Deny(); // Do some work CodeAccessPermission.RevertDeny(); // cancel Deny RevertDeny is used to remove a previous Deny statement from the current stack frame. PermitOnly You can use PermitOnly in some situations when needed to restrict permissions granted by security policy. The following code fragment shows how to use it imperatively. When PermitOnly is used, it means only the resources you specify can be accessed. Collapse WebPermission myWebPermission = new WebPermission(NetworkAccess.Connect, "http://www.somewebsite.com"); myWebPermission.PermitOnly(); // Do some work CodeAccessPermission.PermitOnly(); // cancel PermitOnly You can use PermitOnly instead of Deny when it is more convenient to describe resources that can be accessed instead of resources that cannot be accessed. Calculating Permissions In the first example, we configured the machine policy level to set permissions for our code. Now we'll see how those permissions are calculated and granted by the runtime when your code belongs to more than one code group in the same policy level or in different policy levels. The CLR computes the allowed permission set for an assembly in the following way:

1. Starting from the All_Code code group, all the child groups are searched to
determine which groups the code belongs to, using identity information provided by the evidence. (If the parent group doesn't match, then that group's child groups are not checked.)

2. When all matches are identified for a particular policy level, the permissions
associated with those groups are combined in an additive manner (union).

3. This is repeated for each policy level and permissions associated with each policy
level are intersected with each other. So all the permissions associated with matching code groups in one policy level are added together (union) and the result for each policy level is intersected with one another. An intersection is used to ensure that policy lower down in the hierarchy cannot add permissions that were not granted by a higher level. Look at the following figure taken from a MSDN article, to get a better understanding:

Figure 13 Have a quick look at the All_Code code group's associated permission set in Machine policy level. Hope it makes sense by now.

Figure 14 The runtime computes the allowed permission set differently if the Exclusive or LevelFinal attribute is applied to the code group. If you are not suffering from short term memory loss, you should remember that we set the Exclusive attribute for our code group - MyCodeGroup in the earlier example. Here's what happens if these attributes are set. Exclusive - The permissions with the code group marked as Exclusive are taken as the only permissions for that policy level. So permissions associated with other code groups are not considered when computing permissions. LevelFinal - Policy levels (except the application domain level) below the one containing this code group are not considered when checking code group membership and granting permissions.

Now you should have a clear understanding why we set the Exclusive attribute earlier. Nice Features in .NET Configuration Tool There are some nice features in .NET Configuration Tool. Just right click the Runtime Security Policy node and you'll see what I'm talking about.

Figure 15 Among other options there are two important ones. Evaluate Assembly - This can be used to find out which code group(s) a particular assembly belongs to, or which permissions it has. Create Deployment Package - This wizard will create a policy deployment package. Just choose the policy level and this wizard will wrap it into a Windows Installer Package (.msi file), so what ever the code groups and permissions in your development PC can be quickly transferred to any other machine without any headache.

Tools Permissions View Tool - permview.exe The Permissions View tool is used to view the minimal, optional, and refused permission sets requested by an assembly. Optionally, you can use permview.exe to view all declarative security used by an assembly. Please refer to the MSDN documentation for additional information. Examples: permview SecurityApp.exe - Displays the permissions requested by the assembly SecurityApp.exe.

Code Access Security Policy Tool - caspol.exe The Code Access Security Policy tool enables users and administrators to modify security policy for the machine policy level, the user policy level and the enterprise policy level. Please refer to the MSDN documentation for additional information.

Examples: Here's the output when you run "caspol -listgroups", this will list the code groups that belong to the default policy level - Machine level.

Figure 16 Note that label "1." is for All_Code node because it is the parent node. It's child nodes are labeled as "1.x", and their child nodes are labeled as "1.x.x", get the picture? caspol -listgroups - Displays the code groups caspol -machine -addgroup 1. -zone Internet Execution - Adds a child code group to the root of the machine policy code group hierarchy. The new code group is a member of the Internet zone and is associated with the Execution permission set. caspol -user -chggroup 1.2. Execution - Changes the permission set in the user policy of the code group labeled 1.2. to the Execution permission set. caspol -security on - Turns code access security on. caspol -security off - Turns code access security off.

Summary Using .NET Code Access Security, you can restrict what your code can do, restrict which code can call your code and identify code. There are four policy levels - Enterprise, Machine, User and Application Domain which contains code groups with associated permissions. Can use declarative syntax or imperative syntax. Demands can be used to ensure that every caller has the demanded permission.

Requests can be used to request (or refuse) permissions in the grant time. Granted permissions can be overridden.

How to prevent my .NET DLL to be decompiled?

By design .NET embeds rich Meta data inside the executable code using MSIL. Any one can easilydecompile your DLL back using tools like ILDASM (owned by Microsoft) or Reflector for.NET which is a third party. Secondly there are many third party tools which make this decompilingprocess a click away. So any one can easily look in to your assemblies and reverse engineer themback in to actual source code and understand some real good logic which can make it easy tocrack your application. The process by which you can stop this reverse engineering is using obfuscation. Its a techniquewhich will foil the decompilers. There are many third parties (XenoCode, Demeanor for .NET)which provide .NET obfuscation solution. Microsoft includes one that is Dotfuscator CommunityEdition with Visual Studio.NET

Difference Between ToString() vs Convert.ToString()

vs (string) cast

There is a simple but important difference between these three ToString() raise exception when the object is null So in the case of object.ToString(), if object is null, it raise NullReferenceException. Convert.ToString() return string.Empty in case of null object (string) cast assign the object in case of null So in case of MyObject o = (string)NullObject; But when you use o to access any property, it will raise NullReferenceException.

Native Image Generator (Ngen.exe)

The Native Image Generator (Ngen.exe) is a tool that improves the performance of managed applications. Ngen.exe creates native images, which are files containing compiled processor-specific machine code, and installs them into

the native image cache on the local computer. The runtime can use native images from the cache instead using the just-in-time (JIT) compiler to compile the original assembly. Ngen.exe has changed significantly in the .NET Framework version 2.0: Installing an assembly also installs its dependencies, simplifying the syntax of Ngen.exe. Native images can now be shared across application domains. A new action, update, re-creates images that have been invalidated. Actions can be deferred for execution by a service that uses idle time on the computer to generate and install images. Some causes of image invalidation have been eliminated.

For additional information on using Ngen.exe and the native image service, see Native Image Service. Note Ngen.exe syntax for versions 1.0 and 1.1 of the .NET Framework can be found in Native Image Generator (Ngen.exe) Legacy Syntax. Copy ngen <action> [options] ngen /? | /help Actions

The following table shows the syntax of each action. For descriptions of the individual parts of actionArguments, see the Arguments, Scenarios, and Config tables. The Options table describes the options and the help switches. Action Description Generate native images for an assembly and its dependencies and install the images in the native image cache. If /queue is specified, the action is queued for the native image service. The default priority is 3. Delete the native images of an assembly and its dependencies from the native image cache. To uninstall a single image and its dependencies, use the same command-line arguments that were used to install the image. Update native images that have become invalid. If /queue is specified, the updates are queued for the native image service. Updates are always scheduled at priority 3, so they run when the computer is idle. Display the state of the native images for an assembly and its dependencies. If no argument is supplied, everything in the native image cache is displayed. Execute queued compilation jobs.

install [assemblyName | assemblyPath] [scenarios] [config] [/queue[:{1|2|3}]]

uninstall [assemblyName | assemblyPath | *] [scenarios] [config]

update [/queue]

display [assemblyName | assemblyPath]

executeQueuedItems [1|2|3]

queue {pause | continue | status} Arguments

If a priority is specified, compilation jobs with greater or equal priority are executed. If no priority is specified, all queued compilation jobs are executed. Pause the native image service, allow the paused service to continue, or query the status of the service.

Argument

Description The full display name of the assembly. For example, "myAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0038abc9deabfle5". Note You can supply a partial assembly name, such as myAssembly, for the display and uninstall actions. Only one assembly can be specified per Ngen.exe command line. The explicit path of the assembly. You can specify a full or relative path.

assemblyName

assemblyPath

If you specify a file name without a path, the assembly must be located in the current directory. Only one assembly can be specified per Ngen.exe command line.

Scenarios

Scenario

Description

/Debug Generate native images that can be used under a debugger. /Profile Generate native images that can be used under a profiler. /NoDependencies Generate the minimum number of native images required by the specified scenario options. Config

Configuration

Description Use the configuration of the specified executable assembly.

Ngen.exe needs to make the same decisions as the loader when binding to dependencies. When a shared component is loaded at run time, using the Load method, the application's configuration file determines the dependencies that are loaded for the shared component for example, the version of a dependency that is loaded. The /ExeConfig switch gives Ngen.exe guidance on which dependencies would be loaded at run time. /AppBase:directoryPath When locating dependencies, use the specified directory as the application base. Options /ExeConfig:exePath

Option

Description

/nologo Suppress the Microsoft startup banner display. /silent Suppress the display of success messages. Display detailed information for debugging. /verbose Note

Due to operating system limitations, this option does not display as much additional information on Windows 98 and Windows Millennium Edition.
/help, /? Display command syntax and options for the current release. Remarks

To run Ngen.exe, you must have administrative privileges. Ngen.exe generates native images for the specified assembly and all its dependencies. Dependencies are determined from references in the assembly manifest. The only scenario in which you need to install a dependency separately is when the application loads it using reflection, for example by calling the System.Reflection.Assembly.Load method. Important Do not use the System.Reflection.Assembly.LoadFrom method with native images. An image loaded with this method cannot be used by other assemblies in the execution context. Ngen.exe maintains a count on dependencies. For example, suppose MyAssembly.exe and YourAssembly.exe are both installed in the native image cache, and both have references to OurDependency.dll. If MyAssembly.exe is uninstalled, OurDependency.dll is not uninstalled. It is only removed when YourAssembly.exe is also uninstalled. If you are generating a native image for an assembly in the global assembly cache, specify its display name. See System.Reflection.Assembly.FullName. The native images that Ngen.exe generates can be shared across application domains. This means you can use Ngen.exe in application scenarios that require assemblies to be shared across application domains. To specify domain neutrality: Apply the LoaderOptimizationAttribute attribute to your application. Set the System.AppDomainSetup.LoaderOptimization property when you create setup information for a new application domain.

Always use domain-neutral code when loading the same assembly into multiple application domains. If a native image is loaded into a nonshared application domain after having been loaded into a shared domain, it cannot be used. Note Domain-neutral code cannot be unloaded, and performance may be slightly slower, particularly when accessing static members. Generating Images for Different Scenarios

After you have generated a native image for an assembly, the runtime automatically attempts to locate and use this native image each time it runs the assembly. Multiple images can be generated, depending on usage scenarios. For example, if you run an assembly in a debugging or profiling scenario, the runtime looks for a native image that was generated with the /Debug or /Profile options. If it is unable to find a matching native image, the runtime reverts to standard JIT compilation. The only way to debug native images is to create a native image with the /Debug option. The uninstall action also recognize scenarios, so you can uninstall all scenarios or only selected scenarios. Determining When to Use Native Images Native images can provide performance improvements in two areas: improved memory use and reduced startup time. Note Performance of native images depends on a number of factors that make analysis difficult, such as code and data access patterns, how many calls are made across module boundaries, and how many dependencies have already been loaded by other applications. The only way to determine whether native images benefit your application is by careful performance measurements in your key deployment scenarios. Improved Memory Use Native images can significantly improve memory use when code is shared between processes. Native images are Windows PE files, so a single copy of a .dll file can be shared by multiple processes; by contrast, native code produced by the JIT compiler is stored in private memory and cannot be shared. Applications that are run under terminal services can also benefit from shared code pages. In addition, not loading the JIT compiler saves a fixed amount of memory for each application instance. Faster Application Startup Precompiling assemblies with Ngen.exe can improve the startup time for some applications. In general, gains can be made when applications share component assemblies because after the first application has been started the shared components are already loaded for subsequent applications. Cold startup, in which all the assemblies in an application must be loaded from the hard disk, does not benefit as much from native images because the hard disk access time predominates. Hard binding can affect startup time, because all images that are hard bound to the main application assembly must be loaded at the same time. Note If you have shared components that are strong-named, place them in the global assembly cache. The loader performs extra validation on strong-named assemblies that are not in the global assembly cache, effectively eliminating any improvement in startup time gained by using native images. Importance of Assembly Base Addresses

Because native images are Windows PE files, they are subject to the same rebasing issues as other executable files. The performance cost of relocation is even more pronounced if hard binding is employed. To set the base address for a native image, use the appropriate option of your compiler to set the base address for the assembly. Ngen.exe uses this base address for the native image. Note Native images are larger than the managed assemblies from which they were created. Base addresses must be calculated to allow for these larger sizes. You can use a tool such as dumpbin.exe to view the preferred base address of a native image. Summary of Usage Considerations The following general considerations and application considerations may assist you in deciding whether to undertake the effort of evaluating native images for your application: Native images load faster than MSIL because they eliminate the need for many startup activities, such as JIT compilation and type-safety verification. Native images require a smaller initial working set because there is no need for the JIT compiler. Native images enable code sharing between processes. Native images require more hard disk space than MSIL assemblies and may require considerable time to generate. Native images must be maintained. o Images need to be regenerated when the original assembly or one of its dependencies is serviced. o A single assembly may need multiple native images for use in different applications or different scenarios. For example, the configuration information in two applications might result in different binding decisions for the same dependent assembly. o Native images must be generated by an administrator; that is, from a Windows account in the Administrators group.

In addition to these general considerations, the nature of your application must be considered when determining whether native images might provide a performance benefit: If your application runs in an environment that uses many shared components, native images allow the components to be shared by multiple processes. If your application uses multiple application domains, native images allow code pages to be shared across domains. Note In the .NET Framework versions 1.0 and 1.1, native images cannot be shared across application domains. This is not the case in version 2.0. If your application will be run under Terminal Server, native images allow sharing of code pages. Large applications generally benefit from compilation to native images. Small applications generally do not benefit. For long-running applications, run-time JIT compilation performs slightly better than native images. (Hard binding can mitigate this performance difference to some degree.)

Hard Binding

Hard binding increases throughput and reduces working set size for native images. The disadvantage of hard binding is that all the images that are hard bound to an assembly must be loaded when the assembly is loaded. This can significantly increase startup time for a large application. Hard binding is appropriate for dependencies that are loaded in all your application's performance-critical scenarios. As with any aspect of native image use, careful performance measurements are the only way to determine whether hard binding improves your application's performance. The DependencyAttribute and DefaultDependencyAttribute attributes allow you to provide hard binding hints to Ngen.exe. Note These attributes are hints to Ngen.exe, not commands. Using them does not guarantee hard binding. The meaning of these attributes may change in future releases. Specifying a Binding Hint for a Dependency Apply the DependencyAttribute to an assembly to indicate the likelihood that a specified dependency will be loaded. System.Runtime.CompilerServices.LoadHint.Always indicates that hard binding is appropriate, Default indicates that the default for the dependency should be used, and Sometimes indicates that hard binding is not appropriate. The following code shows the attributes for an assembly that has two dependencies. The first dependency (Assembly1) is an appropriate candidate for hard binding, and the second (Assembly2) is not.

using System.Runtime.CompilerServices; [assembly:DependencyAttribute("Assembly1", LoadHint.Always)] [assembly:DependencyAttribute("Assembly2", LoadHint.Sometimes)] The assembly name does not include the file name extension. Display names can be used. Specifying a Default Binding Hint for an Assembly Default binding hints are only needed for assemblies that will be used immediately and frequently by any application that has a dependency on them. Apply the DefaultDependencyAttribute with System.Runtime.CompilerServices.LoadHint.Always to such assemblies to specify that hard binding should be used. Note There is no reason to apply DefaultDependencyAttribute to .dll assemblies that do not fall into this category, because applying the attribute with any value other than System.Runtime.CompilerServices.LoadHint.Always has the same effect as not applying the attribute at all. Microsoft uses the DefaultDependencyAttribute to specify that hard binding is the default for a very small number of assemblies in the .NET Framework, such as mscorlib.dll. Troubleshooting

To confirm that native images are being used by your application, you can use the Assembly Binding Log Viewer (Fuslogvw.exe). Select Native Images in the Log Categories box on the binding log viewer window. Fuslogvw.exe provides information about why a native image was rejected. You can use the JitCompilationStart managed debugging assistant (MDA) to determine when the JIT compiler starts to compile a function. Deferred Processing Generation of native images for a very large application can take considerable time. Similarly, changes to a shared component or changes to computer settings might require many native images to be updated. The install and update actions have a /queue option that queues the operation for deferred execution by the native image service. In addition, Ngen.exe has queue and executeQueuedItems actions that provide some control over the service. For more information, see Native Image Service. Native Images and JIT Compilation If Ngen.exe encounters any methods in an assembly that it cannot generate, it excludes them from the native image. When the runtime executes this assembly, it reverts to JIT compilation for the methods that were not included in the native image. In addition, native images are not used if the assembly has been upgraded, or if the image has been invalidated for any reason. Invalid Images When you use Ngen.exe to create a native image of an assembly, the output depends upon the command-line options that you specify and certain settings on your computer. These settings include the following: The version of the .NET Framework. The version of the operating system, if the change is from the Windows 9x family to the Windows NT family. The exact identity of the assembly (recompilation changes identity). The exact identity of all assemblies that the assembly references (recompilation changes identity). Security factors.

Ngen.exe records this information when it generates a native image. When you execute an assembly, the runtime looks for the native image generated with options and settings that match the computer's current environment. The runtime reverts to JIT compilation of an assembly if it cannot find a matching native image. The following changes to a computer's settings and environment cause native images to become invalid: The version of the .NET Framework. If you apply an update to the .NET Framework, all native images that you have created using Ngen.exe become invalid. For this reason, all updates of the .NET Framework execute the Ngen Update command, to ensure that all native images are regenerated. The .NET Framework automatically creates new native images for the .NET Framework libraries that it installs. The version of the operating system, if the change is from the Windows 9x family to the Windows NT family.

For example, if the version of the operating system running on a computer changes from Windows 98 to Windows XP, all native images stored in the native image cache become invalid. However, if the operating system changes from Windows 2000 to Windows XP, the images are not invalidated. The exact identity of the assembly. If you recompile an assembly, the assembly's corresponding native image becomes invalid. The exact identity of any assemblies the assembly references. If you update a managed assembly, all native images that directly or indirectly depend on that assembly become invalid and need to be regenerated. This includes both ordinary references and hard-bound dependencies. Whenever a software update is applied, the installation program should execute an Ngen Update command to ensure that all dependent native images are regenerated. Security factors. Changing machine security policy to restrict permissions previously granted to an assembly can cause a previously compiled native image for that assembly to become invalid. For detailed information about how the common language runtime administers code access security and how to use permissions, see Code Access Security Examples

The following command generates a native image for ClientApp.exe, located in the current directory, and installs the image in the native image cache. If a configuration file exists for the assembly, Ngen.exe uses it. In addition, native images are generated for any .dll files that ClientApp.exe references. Copy ngen install ClientApp.exe An image installed with Ngen.exe is also called a root. A root can be an application or a shared component. The following command generates a native image for MyAssembly.exe with the specified path. Copy ngen install c:\myfiles\MyAssembly.exe When locating assemblies and their dependencies, Ngen.exe uses the same probing logic used by the common language runtime. By default, the directory that contains ClientApp.exe is used as the application base directory, and all assembly probing begins in this directory. You can override this behavior by using the /AppBase option. Note This is a change from Ngen.exe behavior in the .NET Framework versions 1.0 and 1.1, where the application base is set to the current directory.

An assembly can have a dependency without a reference, for example if it loads a .dll file by using the System.Reflection.Assembly.Load method. You can create a native image for such a .dll file by using configuration information for the application assembly, with the /ExeConfig option. The following command generates a native image for MyLib.dll, using the configuration information from MyApp.exe. Copy ngen install c:\myfiles\MyLib.dll /ExeConfig:c:\myapps\MyApp.exe Assemblies installed in this way are not removed when the application is removed. To uninstall a dependency, use the same command-line options that were used to install it. The following command uninstalls the MyLib.dll from the previous example. Copy ngen uninstall c:\myfiles\MyLib.dll /ExeConfig:c:\myapps\MyApp.exe To create a native image for an assembly in the global assembly cache, use the display name of the assembly. For example: Copy ngen install "ClientApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c7ba247adcd2081, processorArchitecture=MSIL" NGen.exe generates a separate set of images for each scenario you install. For example, the following commands install a complete set of native images for normal operation, another complete set for debugging, and a third for profiling: Copy ngen install MyApp.exe ngen install MyApp.exe /debug ngen install MyApp.exe /profile Displaying the Native Image Cache Once native images are installed in the cache, they can be displayed using Ngen.exe. The following command displays all native images in the native image cache. Copy ngen display The display action lists all the root assemblies first, followed by a list of all the native images on the computer. Use the simple name of an assembly to display information only for that assembly. The following command displays all native images in the native image cache that match the partial name MyAssembly, their dependencies, and all roots that have a dependency on MyAssembly: Copy

ngen display MyAssembly Knowing what roots depend on a shared component assembly is useful in gauging the impact of an update action after the shared component is upgraded. If you specify an assembly's file extension, you must either specify the path or execute Ngen.exe from the directory containing the assembly: Copy ngen display c:\myApps\MyAssembly.exe The following command displays all native images in the native image cache with the name MyAssembly and the version 1.0.0.0. Copy ngen display "myAssembly, version=1.0.0.0" Updating Images Images are typically updated after a shared component has been upgraded. To update all native images that have changed, or whose dependencies have changed, use the update action with no arguments. Copy ngen update Updating all images can be a lengthy process. You can queue the updates for execution by the native image service by using the /queue option. For more information on the /queue option and installation priorities, see Native Image Service. Copy ngen update /queue Uninstalling Images Ngen.exe maintains a list of dependencies, so that shared components are removed only when all assemblies that depend on them have been removed. In addition, a shared component is not removed if it has been installed as a root. The following command uninstalls all scenarios for the root ClientApp.exe: Copy ngen uninstall ClientApp The uninstall action can be used to remove specific scenarios. The following command uninstalls all debug scenarios for ClientApp.exe: Copy

ngen uninstall ClientApp /debug Note Uninstalling /debug scenarios does not uninstall a scenario that includes both /profile and /debug. The following command uninstalls all scenarios for a specific version of ClientApp.exe: Copy ngen uninstall "ClientApp, Version=1.0.0.0" The following commands uninstall all scenarios for "ClientApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c7ba247adcd2081, processorArchitecture=MSIL", or just the debug scenario for that assembly: Copy ngen uninstall "ClientApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c7ba247adcd2081, processorArchitecture=MSIL" ngen uninstall "ClientApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c7ba247adcd2081, processorArchitecture=MSIL" /debug As with the install action, supplying an extension requires either executing Ngen.exe from the directory containing the assembly or specifying a full path. For examples relating to the native image service, see Native Image Service.

Native Image Service The native image service is a Windows service that generates and maintains native images. The native image service allows the developer to defer the installation and update of native images to periods when the computer is idle. Normally, the native image service is initiated by the installation program (installer) for an application or update. For priority 3 actions, the service executes during idle time on the computer. The service saves its state and is capable of continuing through multiple reboots if necessary. Multiple image compilations can be queued. The service also interacts with the manual Ngen.exe command. Manual commands take precedence over background activity. Launching Deferred Operations Before beginning an installation or upgrade, pausing the service is recommended. This ensures that the service does not execute while the installer is copying files or putting assemblies in the global assembly cache. The following Ngen.exe command line pauses the service: ngen queue pause When all deferred operations have been queued, the following command allows the service to resume:

ngen queue continue To defer native image generation when installing a new application or when updating a shared component, use the /queue option with the install or update actions. The following Ngen.exe command lines install a native image for a shared component and perform an update of all roots that may have been affected: ngen install MyComponent /queue ngen update /queue The update action regenerates all native images that have been invalidated, not just those that use MyComponent. If your application consists of many roots, you can control the priority of the deferred actions. The following commands queue the installation of three roots. Assembly1 is installed first, without waiting for idle time. Assembly2 is also installed without waiting for idle time, but after all priority 1 actions have completed. Assembly3 is installed when the service detects that the computer is idle. ngen install Assembly1 /queue:1 ngen install Assembly2 /queue:2 ngen install Assembly3 /queue:3 You can force queued actions to occur synchronously by using the executeQueuedItems action. If you supply the optional priority, this action affects only the queued actions that have equal or lower priority. The default priority is 3, so the following Ngen.exe command processes all queued actions immediately, and does not return until they are finished: ngen executeQueuedItems Synchronous commands are executed by Ngen.exe and do not use the native image service. You can execute actions using Ngen.exe while the native image service is running. Service Shutdown After being initiated by the execution of an Ngen.exe command that includes the /queue option, the service runs in the background until all actions have been completed. The service saves its state so that it can continue through multiple reboots if necessary. When the service detects that there are no more actions queued, it resets its status so that it will not restart the next time the computer is booted, and then it shuts itself down. Service Interaction with Clients In the .NET Framework version 2.0, the only interaction with the native image service is through the command-line tool Ngen.exe. Use the command-line tool in installation scripts to queue actions for the native image service and to interact with the service. SDK Command Prompt The SDK Command Prompt is new in the .NET Framework 2.0, and automatically sets the SDK environment variables that allow you to easily use the .NET Framework tools.

The required environment variable values are provided by the sdkvars.bat batch file located in the SDK\v2.0\bin folder. The SDK Command Prompt calls this batch file, but the variables expire when you close the command prompt. To make the settings permanent, you can add the variable values to your system variables by using the Environment Variables dialog box, which you can access from the Advanced tab of System Properties. To start the SDK Command Prompt Click Start, point to All Programs, point to Microsoft .NET Framework SDK v2.0, and then click SDK Command Prompt.

If we have two version of same assembly in GAC how do we make a choice ? Note: I really want to explain this in depth for two reasons. First I have seen this question been frequently asked and second its of real practical importance. I have faced this in every of my .NET projectsSo lets try to get this fundamental not in our brain but in our heart. OK first lets try to understand what the interviewer is talking about. Lets say you have made an application and its using a DLL which is present in GAC. Now for some reason you make second version of the same DLL and put it in GAC. Now which DLL does the application refer? Ok by default it always refers the latest one. But you want that it should actually use the older version. So first we answer in short. You need to specify bindingRedirect in your config file. For instance in the below case ClassLibraryVersion has two versions 1.1.1830.10493 and 1.0.1830.10461 from which 1.1.1830.10493 is the recent version. But using the bindingRedirect we can specify saying 1.0.1830.10461 is the new version. So the client will not use 1.1.1830.10493. <configuration> <runtime> <assemblyBinding xmlns=urn:schemas-microsoft-com:asm.v1> <dependentAssembly> <assemblyIdentity name=ClassLibraryVersion publicKeyToken=b035c4774706cc72 culture=neutral/> <bindingRedirect oldVersion= 1.1.1830.10493 newVersion= 1.0.1830.10461/> </dependentAssembly> </assemblyBinding> </runtime> </configuration>

Ok now I will try to answer it in long way by doing a small sample project. Again this project will be done using C#. So in CD you can find the Versioning project. Below is the solution display, it has two projects one the windows client project ( WindowsVersioningCSharp ) and second the class library project ( ClassLibraryVersion ) which will be installed in GAC with two versions.

System.CodeDom Namespace The System.CodeDom namespace contains classes that can be used to represent the elements and structure of a source code document. The classes in this namespace can be used to model the structure of a source code document that can be output as source code in a supported language using the functionality provided by the System.CodeDom.Compiler namespace. For more information about using the CodeDOM to represent and generate source code, see Dynamic Source Code Generation and Compilation. For a table that lists the CodeDOM elements by type and function, see the CodeDOM Quick Reference. Classes

Class CodeArgumentReferenceExpression CodeArrayCreateExpression CodeArrayIndexerExpression CodeAssignStatement CodeAttachEventStatement CodeAttributeArgument CodeAttributeArgumentCollection CodeAttributeDeclaration CodeAttributeDeclarationCollection CodeBaseReferenceExpression CodeBinaryOperatorExpression

Description Represents a reference to the value of an argument passed to a method. Represents an expression that creates an array. Represents a reference to an index of an array. Represents a simple assignment statement. Represents a statement that attaches an eventhandler delegate to an event. Represents an argument used in a metadata attribute declaration. Represents a collection of CodeAttributeArgument objects. Represents an attribute declaration. Represents a collection of CodeAttributeDeclaration objects. Represents a reference to the base class. Represents an expression that consists of a binary

operation between two expressions. CodeCastExpression CodeCatchClause CodeCatchClauseCollection CodeChecksumPragma CodeComment CodeCommentStatement CodeCommentStatementCollection CodeCompileUnit CodeConditionStatement CodeConstructor CodeDefaultValueExpression CodeDelegateCreateExpression CodeDelegateInvokeExpression CodeDirectionExpression CodeDirective CodeDirectiveCollection CodeEntryPointMethod CodeEventReferenceExpression CodeExpression CodeExpressionCollection CodeExpressionStatement Represents an expression cast to a data type or interface. Represents a catch exception block of a try/catch statement. Represents a collection of CodeCatchClause objects. Represents a code checksum pragma code entity. Represents a comment. Represents a statement consisting of a single comment. Represents a collection of CodeCommentStatement objects. Provides a container for a CodeDOM program graph. Represents a conditional branch statement, typically represented as an if statement. Represents a declaration for an instance constructor of a type. Represents a reference to a default value. Represents an expression that creates a delegate. Represents an expression that raises an event. Represents an expression used as a method invoke parameter along with a reference direction indicator. Serves as the base class for code directive classes. Represents a collection of CodeDirective objects. Represents the entry point method of an executable. Represents a reference to an event. Represents a code expression. This is a base class for other code expression objects that is never instantiated. Represents a collection of CodeExpression objects. Represents a statement that consists of a single expression.

CodeFieldReferenceExpression CodeGotoStatement CodeIndexerExpression

Represents a reference to a field. Represents a goto statement. Represents a reference to an indexer property of an object. Represents a for statement, or a loop through a block of statements, using a test expression as a condition for continuing to loop. Represents a labeled statement or a stand-alone label. Represents a specific location within a specific file. Represents a declaration for an event of a type. Represents a declaration for a field of a type. Represents a declaration for a method of a type. Represents a declaration for a property of a type. Represents an expression that invokes a method. Represents a reference to a method. Represents a return value statement. Represents a namespace declaration. Represents a collection of CodeNamespace objects. Represents a namespace import directive that indicates a namespace to use. Represents a collection of CodeNamespaceImport objects. Provides a common base class for most Code Document Object Model (CodeDOM) objects. Represents an expression that creates a new instance of a type. Represents a parameter declaration for a method, property, or constructor.

CodeIterationStatement

CodeLabeledStatement CodeLinePragma CodeMemberEvent CodeMemberField CodeMemberMethod CodeMemberProperty CodeMethodInvokeExpression CodeMethodReferenceExpression CodeMethodReturnStatement CodeNamespace CodeNamespaceCollection CodeNamespaceImport CodeNamespaceImportCollection CodeObject CodeObjectCreateExpression CodeParameterDeclarationExpression

CodeParameterDeclarationExpressionC Represents a collection of ollection CodeParameterDeclarationExpression objects. CodePrimitiveExpression Represents a primitive data type value.

CodePropertyReferenceExpression

Represents a reference to the value of a property.

CodePropertySetValueReferenceExpres Represents the value argument of a property set sion method call within a property set method. CodeRegionDirective CodeRemoveEventStatement CodeSnippetCompileUnit CodeSnippetExpression CodeSnippetStatement CodeSnippetTypeMember CodeStatement CodeStatementCollection CodeThisReferenceExpression CodeThrowExceptionStatement CodeTryCatchFinallyStatement CodeTypeConstructor CodeTypeDeclaration CodeTypeDeclarationCollection CodeTypeDelegate CodeTypeMember CodeTypeMemberCollection CodeTypeOfExpression CodeTypeParameter Specifies the name and mode for a code region. Represents a statement that removes an event handler. Represents a literal code fragment that can be compiled. Represents a literal expression. Represents a statement using a literal code fragment. Represents a member of a type using a literal code fragment. Represents the abstract base class from which all code statements derive. Represents a collection of CodeStatement objects. Represents a reference to the current local class instance. Represents a statement that throws an exception. Represents a try block with any number of catch clauses and, optionally, a finally block. Represents a static constructor for a class. Represents a type declaration for a class, structure, interface, or enumeration. Represents a collection of CodeTypeDeclaration objects. Represents a delegate declaration. Provides a base class for a member of a type. Type members include fields, methods, properties, constructors and nested types. Represents a collection of CodeTypeMember objects. Represents a typeof expression, an expression that returns a Type for a specified type name. Represents a type parameter of a generic type or

method. CodeTypeParameterCollection CodeTypeReference CodeTypeReferenceCollection CodeTypeReferenceExpression CodeVariableDeclarationStatement CodeVariableReferenceExpression Enumerations Represents a collection of CodeTypeParameter objects. Represents a reference to a type. Represents a collection of CodeTypeReference objects. Represents a reference to a data type. Represents a variable declaration. Represents a reference to a local variable.

Enumeration

Description

CodeBinaryOperatorTy Defines identifiers for supported binary operators. pe CodeRegionMode Specifies the start or end of a code region.

CodeTypeReferenceOp Specifies how the code type reference is to be resolved. tions FieldDirection MemberAttributes Defines identifiers used to indicate the direction of parameter and argument declarations. Defines member attribute identifiers for class members.

Вам также может понравиться