Tuesday, March 5, 2013

ArcObjects: Licensing

This post is the 7th post in my ArcObjects series.

ESRI has a very annoying licensing settings which I curse every time my license expires (once a year using EDN). Lets start by saying ESRI delivers the license in the form of ABC######: EFL123456, ESU123456, ECP123456, RUD123456 and each has a different set of instructions. I usually get an ECP license (ArcGis Server) and there is a guide for that.

Assuming you managed to pass the nightmare and tried to use ArcObjects in your code then you will get an Exception. In this case I just run this code:

IPoint point = new PointClass { X = x, Y = y, SpatialReference = CreateWgsSpatialReference() };

And got this exception:

System.Runtime.InteropServices.COMException : Retrieving the COM class factory for component with CLSID {00A5CB41-52DA-11D0-A8F2-00608C85EDE5} failed due to the following error: 80040111 ClassFactory cannot supply requested class (Exception from HRESULT: 0x80040111 (CLASS_E_CLASSNOTAVAILABLE)).

As you can see it is very descriptive. But basically it tells you that without initializing the license you won’t be able to use any ArcObjects (even IPoint). In version 9.3 the license was done using class RuntimeManager but in version 10 the IAoInitialize interface was added. I usually add them together like this:

private static bool Initialize(ProductCode product, esriLicenseProductCode esriLicenseProduct)
{
    if (RuntimeManager.Bind(product))
    {
        IAoInitialize aoInit = new AoInitializeClass();
        aoInit.Initialize(esriLicenseProduct);
        return true;
    }
    return false;
}

This method checks if the current machine has a license of ProductCode which is an enum with values like Server or Engine and if it does returns true. The usage looks like this:

private static bool _isStarted = false;

public static void Start()
{
    if (_isStarted)
        return;

    if (!Initialize(ProductCode.Server, esriLicenseProductCode.esriLicenseProductCodeArcServer))
    {
        if(!Initialize(ProductCode.Engine, esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB))
        {
            throw new ApplicationException(
                "Unable to bind to ArcGIS license Server nor to Engine. Please check your licenses.");
        }
    }
    _isStarted = true;
}

Since the production machines are usually ArcGis Server and the development machines are Engine we usually check if the machine has Server license and if it doesn’t then we go to the fallback of Engine. Now the creation of PointClass will work.

 

That’s it.