Welcome to WindowsClient.net | Sign in | Join

.NET Licensing

Get the samples for this article

Introduction

This paper gives detailed information about the licensing scheme built into the .NET Framework. It also drills into different licensing schemes available and how to implement some of these schemes with the .NET Framework. This is how to make money with .NET controls and components

Running the samples

Extract the .zip file to a folder and then open the Visual Studio.NET solution for each sample. For the license host samples, it will be necessary to manually add a reference to the assembly of the licensed class that is being consumed. For each Host solution, the assembly to reference is in the \bin\debug directory.

Definitions

Below are some terms and their definitions that will be used throughout this paper.


Web Service - A SOAP based web service.
Web Control - An ASP.NET web control.
Windows Forms Control - A Windows Forms control.
Controls - Both ASP.NET web controls and Windows Forms controls.
VS - Visual Studio.NET
Designer - The Visual Studio.NET Form Designer. Used to visually create Windows Forms or ASP.NET applications.
Runtime - The Microsoft Common Language Runtime.

Licensing Schemes

Below are the five main ways of making money selling software:

Free - This model applies to all types of software. Giving content away has been the traditional approach on the web in the past. Giving away content is a good way to build a market; it is also possible when the content is subsidized by advertising. Free is also good for lower quality "trial" services. An example of this is WinZip, the free version of WinZip always works but has a nag screen, when the user pays for a license, and the nag screen goes away. The .NET Framework allows for components to dynamically change their content and behavior based on what type of license the customer has.

One time fee - This model also applies to all types of software. Because this is the way that COM supports licensing, it has been the traditional method for control vendors.

Per CPU - This method is for all software except web services. It isn't applicable to web services because web services run on machines provided by the owner of the web service. With the recent surge of web controls, licensing per CPU has become quite popular. The scalability that is implied by the number of processors in a machine is a good indicator how heavily a server control will be used and hence, how much the vendor can charge for it. This is essentially a solution halfway between per hit licensing and one time fee licensing. A one time fee is paid for use based on the count of processors in a system, which is an assumption of how may hits that server will get.

Per Hit - This model is applicable to web controls and web services only. Windows Forms controls do not have an appropriate analogy for a web server hit. This method is the sweet spot for web controls and web services. This model allows the end user to pay for exactly what is used. Essentially pay as you play. The snag in per hit licensing is the proxy caller scenario. An example of this is a stock ticker web service that is invoked by MSN for one of its users. This forces either MSN to propagate the per hit cost to its users, or charge a monthly subscription fee for use. This is a look into how a future web app might work. Weaving together disparate web services to create an application that is more valuable than the sum of its parts. Then the application author could charge a monthly service fee.

Time Based Fee - This method could be applied to all controls and web services. The most interesting scenario is a web control vendor or web service provider that finds it easier to charge a subscription fee than to keep track of each individual hit or use.

COM Licensing

COM wasn't originally designed with design time versus runtime licensing in mind. Support for runtime licensing was tacked on with COM2 and ICLassFactory2. The methods on IClassFactory2 provided a way to do one time fee licensing. This was used mostly with ActiveX controls that were used to create applications in environments like Microsoft's Visual Basic and Inprise's Delphi. An application builder pays a one time fee to a control developer for the design license for a control and the rights to distribute the run time version of the control for free.

This method worked well at the time and spawned a burgeoning ActiveX control developer community. But, due to the fact that COM licensing isn't extensible, it doesn't provide hooks appropriate for server controls.

Also, COM licensing forces the control consumer to think about licensing when they shouldn't have to. When an instance of a licensed control is created in COM (through IClassFactory) it will fail if there isn't a design time license available on that machine. The control consumer will have to catch this failure and then make a call to IClassFactory2 to try and create the control with a runtime license.

.NET Licensing Overview

In the .Net Framework, licensing is designed into the runtime. All classes are instantiated the same way whether or not they are licensed. Simply calling "new Foo()" causes the runtime to use the proper validation scheme specified by the creator of foo.

The piece that holds licensing together in .NET is the LicenseManager. The LicenseManager is part of the runtime and whenever a class is instantiated, the LicenseManager accesses the proper validation mechanism for the control or component. Classes are marked as licensed by adorning the class with the LicenseProviderAttribute. This attribute also specifies the type of validation that occurs.

License providers are the place to put custom validation code. By extending System.ComponentModel.LicenseProvider and overriding IsKeyValid and GetLicense custom licensing schemes can be created.

Just like COM, there are two modes of consumption for licensed classes, design time and runtime. This amounts to two different paths for validation. At design time, a license provider may look anywhere for a valid license. Looking on the hard disk for a .LIC file or to a web service for a magic bit of XML are two types of things a license provider might do.

Then at runtime for client apps, this license is converted into a license key and embedded into the executing assembly. For ASP.NET web applications and Windows Forms controls in Internet Explorer, there is no executing assembly, so the runtime license must be stored elsewhere.

The creation of runtime license keys is handled by the command line tool LC.exe (License Compiler) or by Visual Studio. LC takes a text file containing the assembly qualified names of licensed classes used in an application and returns a binary .licenses file which contains all the runtime keys for the specified licensed classes. This binary .licenses file is then embedded into the executing assembly using either the compiler or AL.exe (Assembly Linker). More information on LC.exe and AL.exe is available in the .NET Framework documentation. Also, an example of LC.exe usage is shown below.

If you are using Visual Studio.NET, the binary .licenses file is automatically generated and embedded into the executing assembly by the project system.

Creating Licensed .NET Classes

This section will outline how to create a simple licensed class, a simple licensed Windows Forms control and a simple ASP.NET web control. These are presented in the order of complexity.

Creating Licensed Classes

From a creation standpoint, creating a licensed class is the simplest scenario. To see a sample licensed class, open the LicensedClass example solution.

        [LicenseProviderAttribute(typeof(LicFileLicenseProvider))]
        public class LicensedClass : IDisposable
        {
        	private License license = null;
        
        	public LicensedClass()
        	{
        		license = LicenseManager.Validate(typeof(LicensedClass), this);
        		Console.WriteLine("Hello from the licensed class.");
        	}
        
        	public void Dispose() 
        	{
        		if (license != null) 
        		{
        			license.Dispose();
        			license = null;
        		}
        	}
        }

The first interesting bit is the LicenseProviderAttribute. This attribute specifies the license provider that will be used to validate the license of this control. In this case, the LicFileLicenseProvider, which is provided as part of the .NET framework is specified.

LicFileLicenseProvider is the only license provider that ships with the .NET Framework. This provider has a very similar validation mechanism to that of COM's IClassFactory2. At design time, .LIC files are used and runtime licenses are embedded into the executing assembly.

The next part of the code to notice is the declaration of a private License field in the class. The code in the constructor asks the LicenseManager to fill the license by validating this instance of the LicensedWinControl. In this sample, the license is of type System.ComponetnModel.License, but this could also be a custom type that inherits from System.ComponentModel.License and has extra properties to give the class information to control behavior. An example usage of this might be to define a license type that has a Boolean property defining whether or not the license is in demo mode. If it is in demo mode, the control could disable some features.

Finally, notice the code in Dispose which cleans up the license. This is an important step to take so that your control doesn't leak licenses. Not doing this might allow malicious code to get the license before the garbage collector does.

In summary, there are 4 key things to note

  1. The LicenseProviderAttribute
  2. The private license field
  3. The line in the constructor that fills the license
  4. Disposing the license in Dispose

This is all that is necessary to add simple .LIC file based licensing to any class. The only other step is to create a design time .LIC file for your new class and put it where the built assembly will live. For all of the samples in this paper, the .LIC files are in the bin\debug directory of the VS project. The naming conventions and procedure for creating .LIC files are described in the next section.

More on the LicFileLicenseProvider

Moving back to VS, in the Solution Explorer, if you drill into the bin -> debug folder, you'll notice a file called "Licensing.LicensedClass.LIC". This is the design time license for the control that the LicFileLicenseProvider is looking for. The naming convention for these .LIC file is "..LIC".

The reason this file is placed in the bin -> debug directory is that this is where the built assembly is output to. The LicFileLicenseProvider looks for a .LIC file in the same directory as the assembly that contains the licensed class.

Opening the .LIC file reveals the line:

        Licensing. LicensedClass is a licensed component.

This is the string that the LicFileLicensedProvider looks for in the .LIC file. The format for this string is ". is a licensed component." As mentioned previously, the LicFileLicenseProvider is the only license provider implementation that ships with the .NET Framework. The validation mechanism of the LicFileLicenseProvider should seem very familiar to those who have used COM licensing, as it was designed to mimic the COM model.

Creating Licensed Windows Forms Controls

The next sample outlines creating a licensed Windows Forms control. Licensing a Windows Forms control is no different than licensing a class. Open the LicensedWinControl solution in VS.NET and look at the following code:

        [LicenseProviderAttribute(typeof(LicFileLicenseProvider))]
        public class LicensedWinControl :System.Windows.Forms.UserControl
        {
        	/// 
        	/// Required designer variable.
        	/// 
        	private System.ComponentModel.Container components = null;
        
        	private License license = null;
        
        	public LicensedWinControl()
        	{
        		// This call is required by the Windows.Forms FormDesigner.
        		InitializeComponent();
        
        		// TODO: Add any initialization after the InitForm call
        license = LicenseManager.Validate(typeof(LicensedWinControl), this);
        
        	}
        	...

Notice the LicenseProviderAttribute, the private License field, the call to LicenseManager.Validate and the destruction of the license in the Dispose method. These are the exact same steps to provide licensing to any class.

Creating Licensed ASP.NET Web Controls

Because the ASP.NET web control architecture is so similar to Windows Forms, creating licensed web controls follows basically the same process.

Beta 2 note: A bug in the Visual Studio designer for Web Controls prevents the LicFileLicenseProvider from working with ASP.NET Web Controls. This will be fixed for the final release. Because of this bug, the LicensedWebControlHost project won't load in the browser.Simple .LIC file based licensing is far less interesting for server controls then for client controls. Because server controls are always connected to the internet, LicenseProviders for server controls can perform tasks like validating based on a return value from a web service. This scenario is covered in the Advanced Licensing section of the paper.

To see an example In the LicensedWebControl.cs file, notice the attribute block of the LicensedWebControl class:

                [DefaultProperty("Text"),
ToolboxData("<{0}:LicensedWebControl
runat=server></{0}:LicensedWebControl>"),
LicenseProviderAttribute(typeof(LicFileLicenseProvider))]
 

Web controls have other standard attributes but the LicenseProviderAttribute is in there. And also, like any other licensed class, the private license field and the line to fill the license in the constructor are present. Finally, web control's Disposing method cleans up the license.

        public class LicensedWebControl : System.Web.UI.WebControls.WebControl
        {
        	private string text;
        	private License license = null;
        
        	public LicensedWebControl() : base() 
        	{
        		license = LicenseManager.Validate(typeof(LicensedWebControl), this);
        	}
        
        	[Bindable(true),
        		Category("Appearance"),
        		DefaultValue("")]
        	public string Text
        	{
        		get
        		{
        			return text;
        		}
        
        		set
        		{
        			text = value;
        		}
        	}
        
        	public override void Dispose () 
        	{
        		if (license != null) 
        		{
        			license.Dispose();
        			license = null;
        		}
        		base.Dispose();
        	}
        ...

Consuming Licensed .NET Objects

This section will outline how to use the licensed objects created in the previous section. Using a licensed class should be as painless as using any other class. This is something COM didn't do very well. If an object supported licensing, it had to be created in a different way than if it didn't. Visual Basic 6 did a good job of hiding this deficiency from the end user, but in .NET this issue is fixed completely: instantiating a licensed class is just like using any other class.

Consuming Licensed Classes in Visual Studio.NET

Opening the LicensedClassHost example solution shows an example of using the LicensedClass constructed previously in a console app. The code to create the licensed class looks like the code to create any other class:

        class LicensedClassHost
        {
        	static void Main(string[] args)
        	{
        		LicensedClass LicensedClass1 = new LicensedClass();
        	}
        }

The only caveat of using classes instead of controls or components is that classes must be created through manually entering code and not through the VS.NET designer. For licensed controls and components, the designer does the dirty work of identifying to the VS.NET build system which licensed classes are used in a project. For classes this must be done explicitly.

This is analogous to using a licensed class in VB6. In VB6 controls automatically did the right thing for licensing. But classes needed to have their runtime license added to the collection through code.

Notice the licenses.licx file in the solution explorer of VS.NET. .licx files are text files that identify which licensed classes are used in a project. There should be one .licx file for each project in a VS.NET solution. For controls and components this is automatically created, but, because there is no designer involved in adding this class to the console application, a .licx file must be manually created and added to the project.

To create a .licx file:
  1. Right click on the project and select "Add -> New Item"
  2. Select a "Text File" and name it "licenses.licx"
  3. For each licensed class in the project, add one line to the .licx file containing the assembly qualified name of the class.

The .licx file in the LicensedClassHost application only contains one line:

        Licensing.LicensedClass,LicensedClass

The format of the entry is <Namespace>.<Class name>,<Assembly name without file extension> This is the assembly qualified name of the class.

Pressing "F5" will build and run the project. The build system will extract the runtime license key and embed it into the .exe. At runtime, the LicFileLicenseProvider will look for a .LIC file and if it can't find one, it looks for a key embedded into the executing assembly. To prove that this works, rename the .LIC file in the LicensedClass project and run LicensedClassHost again. The licensed control will still get instantiated despite not having the .LIC file present.

Consuming Licensed Windows Forms Controls

Using a licensed Windows Forms control is completely transparent to the end user. Open the LicensedWinControlHost Visual Studio.NET solution and look at the contents of the form code. The code looks exactly identical to any other form. The control is instantiated with a call to "new" and its constructor. There is no special code required to use the licensed control.

Clicking the "Show All Files" button in the VS solution explorer shows a "licenses.licx" file. Opening this file shows the line:

        Licensing.LicensedWinControl, LicensedWinControl, Version=1.0.518.15407, Culture=neutral, PublicKeyToken=null

Notice that the form designer automatically generates a .licx file whenever a licensed control is added to the form. Using a licensed control or component is no different than using an unlicensed one.

Consuming Licensed ASP.NET Web Controls

Consuming licensed ASP.NET web controls is also completely invisible to the end user. Drag, drop and press F5. To see an example of this, open the LicensedWebControlHost solution is Visual Studio.NET. Notice that the .licx file gets generated automatically when a licensed control is added to the web form.

Licensed Windows Forms Controls in Internet Explorer

Not only can Windows Forms controls can be used in Windows Forms applications, but they can also be hosted in Internet Explorer. Consuming a licensed Windows Forms control in the browser has a few caveats which will be discussed here. The first issue to be addressed is that there is no executing assembly to store the license keys for the licensed controls.

ActiveX controls faced this same issue and once again, the .NET Framework tackled the problem is a similar manner as ActiveX. IE knew about a special "LPKPath" "PARAM" tag in the HTML "OBJECT" tag for licensed ActiveX controls. .LPK files are "License Package Files" that contain the runtime licenses for ActiveX controls. The "LPKPath" param tag points the browser to the .LPK file which is downloaded and used to create the control. An example of what the HTML for a licensed ActiveX control in the browser looks like is below.

        <OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">
<PARAM NAME="LPKPath" VALUE="LPKfilename.LPK">
</OBJECT>

<OBJECT
classid="clsid:F651BF93-239B-11D0-8908-00A0C90395F4"
id=ShapeLabel
codebase="ControlDemo.CAB#version=1,0,0,1">
</OBJECT>

In .NET there is a special attribute on the "LINK" HTML tag that specifies the location of the .licenses file. .licenses files contain the runtime license keys for licensed .NET classes. An example of the HTML for a licensed Windows Forms control is below:

        <LINK REL="licenses" HREF="licensedwincontrol.html.licenses">
<OBJECT id = ctrl HEIGHT="200" WIDTH="200"
classid="http:LicensedWinControl.dll#Licensing.LicensedWinControl" >
<PARAM ID="Text" VALUE="Hello from the licensed control">
<PARAM ID="Backcolor" VALUE="Red">
</OBJECT >
To run this sample, follow these steps:
  1. Open a command window and run "build.bat" from the LicensedControlInIE folder. This batch file uses LC.exe to generate the binary .licenses file.
  2. An IIS virtual directory needs to be setup to run the HTML page from. To set one up, right click on "My Computer" on the desktop. Select "Manage" from the context menu. Drill into "Services and Applications" -> "Internet Information Services". Right click on "Default Web Site" and select "New -> Virtual Directory". Follow the steps in the wizard to create a new virtual directory for the LicensedControlInIE folder.
  3. Open a new Internet Explorer window and navigate to LicensedWinControl.html under the virtual directory just created.

Advanced Licensing

This section deals with the command line tools the ship with the .NET framework for licensing and creating more advanced custom LicenseProviders

LC.exe

In the "Licensed Windows Forms Controls in Internet Explorer" above, a batch file was used to create a binary .licenses file. This batch file contained the line:

        lc /target:LicensedWinControl.html /complist:LicensedWinControl.html.licx /i:LicensedWinControl.DLL

LC.exe is the license complier. This tool looks at a text file for a list of licensed classes, instantiates these classes, extracts the runtime license key and embeds the collection of runtime keys in a binary .licenses file. LC also burns the name of the target into the .licenses file so that this .licenses file cannot be blindly used by another app looking for free licenses.

When Visual Studio.NET processes a .licx file, it is actually calling LC.exe to create a .licenses file and then it embeds that file automatically into the output assembly.

LC.exe can be used to create applications which use licensed controls outside of VS.NET. Simply use LC to create the binary .licenses file and then use the compiler with a "/res:.licenses" flag to embed it into the output assembly.

Custom LicenseProviders

All of the licensing samples above relied on the simple LicFileLicenseProvider. This LicenseProvider is easy to use because it is built into the .NET Framework, but its validation logic isn't very interesting or secure. A more complex custom provide is presented here to show how to do licensing based on the number of processors in a machine.

To create a custom LicenseProvider, a class must inherit from LicenseProvider and override the IsKeyValid and GetLicense methods. Often a custom license type will also be defined to provide extra information to classes using the custom license provider.

Open the LicensedProcCountingClass solution in Visual Studio.NET and take a look at ProcCountLicenseProvider.cs. This first thing to note is that this class is a modified version of the .NET Framework's LicFileLicensedProvider. The functionality of that provider was extended by adding support to look at the number of processors on a machine and license based on that.

Looking at the IsKeyValidMethod:

protected virtual bool IsKeyValid(string key, Type type) 
        {
        	// If string isn't empty
        	if (key != null) 
        	{
        		//Get number of system processors
        		SYSTEM_INFO si;
        		GetSystemInfo(out si);
        		uint procCount = si.dwNumberOfProcessors;
        
        		//Get number of processors license is valid for
        		int validProcCount = Int32.Parse(key.Substring(key.IndexOf(',') + 1));
        				
        		//validate license string and number of processors
        		return (procCount <= validProcCount && key.StartsWith(string.Format("{0} is a licensed component.",type.FullName)));
        	}
        	return false;
        }

The method takes two arguments, a string which is the license key and a Type which is the Type being licensed. The ProcCounLicensProvider implementation of IsKeyValid first checks if the license key passed in isn't null. Next, it retrieves the number of processors on the system and then gets the number of processors the license is valid for. Finally it makes sure the license key starts with the proper string and is valid for at least as many processors as the current system has.

Next look at the GetLicense method:

        public override License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions) 
        {
        	ProcCountLicense lic = null;
                    
        	Debug.Assert(context != null, "No context provided!");
        	//if no context is provided, do nothing
        	if (context != null) 
        	{
        		//if this control is in runtime mode
        		if (context.UsageMode == LicenseUsageMode.Runtime) 
        		{
        			//retreive the stored license key
        			string key = context.GetSavedLicenseKey(type, null);
        			//check if the stored license key is null
        			// and call IsKeyValid to make sure its valid
        			if (key != null && IsKeyValid(key, type)) 
        			{
        				//if the key is valid create a new license
        				lic = new ProcCountLicense(this, key);
        			}
        		}
        
        		//if we're in design mode or 
        		//a suitable license key wasn't found in 
        		//the runtime context.
        		//attempt to look for a .LIC file
        		if (lic == null) 
        		{
        			//build up the path where the .LIC file
        			//should be
        			string modulePath = null;
        			// try and locate the file for the assembly
        			if (context != null) 
        			{
        				ITypeResolutionService resolver = (ITypeResolutionService)context.GetService(typeof(ITypeResolutionService));
        				if (resolver != null)
        					modulePath = resolver.GetPathOfAssembly(type.Assembly.GetName());
        			}
        
        			if (modulePath == null)
        				modulePath = type.Module.FullyQualifiedName;
        
        			//get the path from the file location
        			string moduleDir = Path.GetDirectoryName(modulePath);
        				
        			//build the path of the .LIC file
        			string licenseFile = moduleDir + "\\" + type.FullName + ".lic";
        
        
        			//if the .LIC file exists, dig into it
        			if (File.Exists(licenseFile)) 
        			{
        				//crack the file and get the first line
        				Stream licStream = new FileStream(licenseFile, FileMode.Open, FileAccess.Read, FileShare.Read);
        				StreamReader sr = new StreamReader(licStream);
        				string s = sr.ReadLine();
        				sr.Close();
        
        
        				//check if the key is valid
        				if (IsKeyValid(s, type)) 
        				{
        					//valid key so create a new License
        					lic = new ProcCountLicense(this, s);
        				}
        			}
        
        			//if we managed to create a license, stuff it into the context
        			if (lic != null) 
        			{
        				context.SetSavedLicenseKey(type, lic.LicenseKey);
        			}
        		}
        	}
        	return lic;
        }

GetLicense takes four arguments, A LicenseContext that tells the LicenseProvider whether its runtime or design time, A Type representing the Type to check get a license for, an object which is the instance to get a license for and a bool which tells the method whether it should throw exceptions or not.

The ProcCountLicenseProvider implementation of GetLicense first checks if its in runtime mode and looks for a stored license in the context. This is where the license manager will put the license key it retrieves from the embedded .licenses file. If there is a stored key and its valid it creates a new license.

If a license couldn't be created from the context, the method then looks for a .LIC file. If it finds a .LIC file the first line is extracted and sent to IsKeyValid. If it is valid a new license is created.

This sample provider also has a special license type, ProcCountLicense that has a field representing the number of valid processors. Classes that use this provider can use the extra property on the ProcCountLicense to disable features if the license isn't for enough processors. The ProcCountLicenseClass is below:

        public class ProcCountLicense : License 
        {
        	private ProcCountLicenseProvider owner;
        	private string key;
        	private int validProcCount;
        
        	public ProcCountLicense(ProcCountLicenseProvider owner, string key) 
        	{
        		this.owner = owner;
        		this.key = key;
        		this.validProcCount = Int32.Parse(key.Substring(key.IndexOf(',') + 1));
        	}
        	public override string LicenseKey 
        	{ 
        		get 
        		{
        			return key;
        		}
        	}
        
        	public int ValidProcCount 
        	{
        		get 
        		{
        			return validProcCount;
        		}
        	}
        
        	public override void Dispose() 
        	{
        	}
        }

This class is public, but for maximum security, custom license types should only be public if it has extra information that a class could use.

Debugging Custom Providers

It can often be difficult to debug a custom license provider. But there are some good places to put debug information. Because the GetLicense and IsKeyValid methods are called not only at runtime, but also by LC.exe (and LC.exe is called by Visual Studio.NET), inserting debug information into this method can be useful to see what order each method is called in, and what part of your custom provider is failing.

Other Custom Providers

A web service based provider sample is coming soon! Below is the model:

Conclusion

Licensing in the .NET Framework is more flexible and easier to use than licensing was in COM. With licensing built into the runtime and custom license providers, the .NET framework provides powerful ways to protect your intellectual property.

Microsoft Communities