Creating a license provider

Although this won’t apply for many types of applications, the .NET framework has a provider for licensing applications and components, it’s System.ComponentModel.LicenseProvider. It’s quite easy to implement – below are the parts you’ll need:

Create a license:

Simply create a class, and inherit from System.ComponentModel.License – and have the .LicenseKey be whatever you like:

    public class MyCustomLicense : License

    {

        public override void Dispose()

        {

        }

 

        public override string LicenseKey

        {

            get

            {

                return Guid.NewGuid().ToString();

            }

        }

    }

Create a license provider:

Next, create a license provider by inheriting from System.ComponentModel.LicenseProvider, then implement the abstract members:

    public class MyCustomLicenseProvider : LicenseProvider

    {

        public override License GetLicense(

            LicenseContext context, Type type,

            object instance, bool allowExceptions)

        {

            // Do some logic to go figure out if this type or instance

            // is licensed. This can be implemented however you want.

            bool licenseIsValid;

 

 

            // If license check isn’t successful:

            if (licenseIsValid)

            {

                throw new LicenseException(type, instance, "Invalid license.");

            }

            else

            {

                return new MyCustomLicense();

            }

        }

    }

How to actually license an application:

To actually use these, wrap the startup of your application with the LicenseProvider attribute, then attempt to validate the license. Something like this:

    [LicenseProvider(typeof(MyCustomLicenseProvider))]

    static class Program

    {

        /// <summary>

        /// The main entry point for the application.

        /// </summary>

        [STAThread]

        static void Main()

        {

            try

            {

                // Attempt to validate the license

                LicenseManager.Validate(typeof(Program));

 

                Application.EnableVisualStyles();

                Application.SetCompatibleTextRenderingDefault(false);

                Application.Run(new Form1());

            }

            catch (Exception exception)

            {

                MessageBox.Show("An unhandled application exception occurred." + Environment.NewLine + Environment.NewLine + exception.ToString());

            }

        }

    }

So when you call LicenseManager.Validate() – the run-time kicks off a new thread, and runs the .GetLicense() for the current type.

One part that may not be clear (and wasn’t to me, when I was reading up this) – was HOW does .GetLicense() check to see if “the license” is valid?? Well, that’s the logic you need to write. What I mean is, you can create a file – and store license information in it – then, at run-time, .GetLicense() will make sure the file is there, open it, then verify the license somehow. Put another way, this license run-time takes care of calling .GetLicense() for you – and you can do ANYTHING in that method to implement a licensing scheme however you want. So the run-time takes care of the overhead, and you write the specific implementation of how you want it to work.

I did write an actual implementation of this, and this is more or less how mine works:

    public override License GetLicense(LicenseContext context, Type type,

        object instance, bool allowExceptions)

    {

        // Get the path of the would-be license file

        string path = Path.GetFullPath(".");

        string licenseFile = Path.Combine(path, "MyCustomLicense.lic");

 

        // See if the file exists, if it doesn’t – exception out

        if (!File.Exists(licenseFile))

        {

            throw new LicenseException(type, instance,

                "A licensing error occurred. The MyCustomLicense licensing file was not found in the following location: ‘"

                + licenseFile + "’. Please place the license file in this location and try the application again.");

        }

 

        // Read the contents of the file, if it’s null or empty – exception out

        string fileContents = File.ReadAllText(licenseFile);

        if ( string.IsNullOrEmpty(fileContents))

        {

            throw new LicenseException(type, instance,

                "A licensing error occurred. The MyCustomLicense licensing file was found in the following location: ‘"

                + licenseFile + "’. However, the file is empty. Please place the license file in this location and try the application again.");

        }

 

        // Deserialize this XML file into a real data structure. If there was a problem deserializing – exception out

        XmlDomainObjects.License license = null;

        try

        {

            license =

                LicenseUtilities.Deserialize<XmlDomainObjects.License>(fileContents, "license");

        }

        catch (LicenseUtilityException exception)

        {

            throw new LicenseException(type, instance,

                "A licensing error occurred. The MyCustomLicense licensing file was found in the following location: ‘"

                + licenseFile + "’. However, the file does not appear to be a valid license file. Please place the license file in this location and try the application again.");

        }

 

        // Generate a hash from the domain properties

        string hash = LicenseUtilities.GetHashForLicense(license);

 

        // See if the generated hash matches what was in the file, if not – exception out

        if (!license.Hash.Equals(hash, StringComparison.InvariantCulture))

        {

            throw new LicenseException(type, instance,

                "A licensing error occurred. The MyCustomLicense licensing file was found in the following location: ‘"

                + licenseFile + "’. However, it has been modified and can no longer be verified. Please replace this file with the correct license file or contact support for a new license file.");

        }

 

        return license;

    }

There are a couple of things to note. I used a couple of helpers for hashing and serializing, which are not included – but hopefully the pseudo-code makes sense. Also, and this is important – if you write this in a managed language, like C# or VB.NET, then any savvy developer would be able to use Reflector and see exactly how your licensing is implemented. So, this licensing model written in managed code would not be appropriate for any critical licensing needs – or for software products that cost money. In my case, we had a free product and need metrics on who is using which version and how many. In my case, it will be far easier for ANYone to get a license, than it would be to try to circumvent this – which also helps us.

Another critical point is that if you use this for a component, instead of an application – the consuming developer can simply catch and swallow the LicenseException(), which is another major factor that can undermine this approach.

My point is, this is a easy lightweight licensing scheme but probably is not appropriate for a real, retail software product – unless you relied on some external method too, like using a public-key technique for “activation” for example. But if you have some simple needs – this is pretty fast and easy to implement.

Posted in General, Uncategorized
10 comments on “Creating a license provider
  1. Islam says:

    Great articleVery Usefulthanks a lot

    Like

  2. Anthony says:

    Sure, but why bother with LicenceProvider et al?

    Just put a call to your GetLicence directly in your main instead of calling Validate.

    Thanks for the article. Makes some code I am untangling clearer.

    Anthony

    Like

    • Rob Seder says:

      Anthony,

      The point of .Validate is that you can just make a simple call. If you were to call GetLicense, you would actually have to analyze what you got back, and determine if the license is valid (what Validate does). So by seperating out this logic, you make calling easier, and you have better separation of concerns with your license logic. I hope that helps

      -Rob

      Like

    • aston says:

      The framework LicenseProviderAttribute sets up the chain of events whereby the license resource with your validated key is serialized to the end user’s assembly when they compile. You can’t do this yourself, least not easily.

      Like

  3. Anthony says:

    Sure, but why bother with LicenceProvider et al?

    Just put a call to your GetLicence directly in your main instead of calling Validate.

    Thanks for the article. Makes some code I am untangling clearer.

    Anthony

    Like

  4. Anthony says:

    Sure, but why bother with LicenceProvider et al?

    Just put a call to your GetLicence directly in your main instead of calling Validate.

    Thanks for the article. Makes some code I am untangling clearer.

    Anthony

    Like

    • Rob Seder says:

      Anthony,

      The point of .Validate is that you can just make a simple call. If you were to call GetLicense, you would actually have to analyze what you got back, and determine if the license is valid (what Validate does). So by seperating out this logic, you make calling easier, and you have better separation of concerns with your license logic. I hope that helps

      -Rob

      Like

      • aston says:

        ‘can simply catch and swallow the LicenseException

        When the component consumer/user is siting a component in during design, ie dropping from the toolbox, is when the exception happens, and only the IDE/designer is in position to catch it. But it doesn’t, by design.

        Like

    • aston says:

      The framework LicenseProviderAttribute sets up the chain of events whereby the license resource with your validated key is serialized to the end user’s assembly when they compile. You can’t do this yourself, least not easily.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 5 other followers

%d bloggers like this: