1.组件初始化失败
Error: ArcGIS version not specified. You must first bind to an ArcGIS version prior to using any ArcGIS components
官方解决方案
10.0版本开始需要执行Runtime绑定,即开发前确定具体的产品。执行该操作需引用ESRI.ArcGIS.Version,具体代码如下:
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop);
2.NO License
System.ComponentModel.LicenseException:“您必须有许可证才能使用此ActiveX控件”
解决方案:进行许可证初始化
IAoInitialize m_AoInitialize = new AoInitializeClass();
esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable;
licenseStatus = m_AoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
以上方法在低版本中适用,但在10.3以上的版本中无法正常初始化许可证。
3.通用许可证初始化方法
在winform中开发时,可以添加LicenseControl控件,并通过设置属性进行对应产品和扩展模块开发,如下所示;
但在实际开发过程中,有时会不方便直接添加LicenseControl控件,此时需要用代码进行许可证初始化,以下方法经验证,比2中介绍的方法更加适用,在10.2.2、10.6、10.7版本中都得以初始化成功:
private static IAoInitialize aoInitialize;
public static bool AlreadyInitialized { get; private set; }
/// <summary>
/// 需要添加许可的产品
/// </summary>
private static List<esriLicenseProductCode> ProductList = new List<esriLicenseProductCode>()
{
esriLicenseProductCode.esriLicenseProductCodeAdvanced,
esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB,
esriLicenseProductCode.esriLicenseProductCodeEngine
};
/// <summary>
/// 需要添加许可的扩展
/// </summary>
private static List<esriLicenseExtensionCode> ExtensionList = new List<esriLicenseExtensionCode>()
{
esriLicenseExtensionCode.esriLicenseExtensionCode3DAnalyst,
esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst,
esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork
};
private static object lockObject=new object();
public static Dictionary<esriLicenseExtensionCode, bool> ExtensionCodes { get; } = new Dictionary<esriLicenseExtensionCode, bool>();
public static bool InitializeApplication()
{
//避免多线程访问时重复初始化
lock (lockObject)
{
if (AlreadyInitialized)
{
return AlreadyInitialized;
}
AlreadyInitialized = false;
//Runime绑定
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop);
//许可证初始化
aoInitialize = new AoInitializeClass();
var licenseStatus = esriLicenseStatus.esriLicenseUnavailable;
//产品许可初始化
foreach (esriLicenseProductCode licenseProductCode in ProductList)
{
licenseStatus = aoInitialize.IsProductCodeAvailable(licenseProductCode);
if (licenseStatus != esriLicenseStatus.esriLicenseAvailable)
{
continue;
}
licenseStatus = aoInitialize.Initialize(licenseProductCode);
if (licenseStatus != esriLicenseStatus.esriLicenseCheckedOut)
{
continue;
}
AlreadyInitialized = true;
//扩展模块初始化
CheckOutExtensions(licenseProductCode);
string extensionMessage = "ArcGIS扩展模块:";
foreach (esriLicenseExtensionCode extensionCode in ExtensionCodes.Keys)
{
extensionMessage = string.Format("{0}\n {1,-20} {2}", extensionMessage, extensionCode.ToString().Substring("esriLicenseExtensionCode".Length), ExtensionCodes[extensionCode] ? "可用" : "不可用");
}
return true;
}
throw new Exception($"ArcGIS授权失败:{LicenseMessage(licenseStatus)}");
}
}
/// <summary>
/// //扩展模块初始化
/// </summary>
/// <param name="productCode"></param>
private static void CheckOutExtensions(esriLicenseProductCode productCode)
{
foreach (esriLicenseExtensionCode extensionCode in ExtensionList)
{
esriLicenseStatus licenseStatus = aoInitialize.IsExtensionCodeAvailable(productCode, extensionCode);
if (licenseStatus == esriLicenseStatus.esriLicenseAvailable)
{
licenseStatus = aoInitialize.CheckOutExtension(extensionCode);
}
ExtensionCodes[extensionCode] = licenseStatus == esriLicenseStatus.esriLicenseCheckedOut;
}
}
private static string LicenseMessage(esriLicenseStatus licenseStatus)
{
string licenseMessage = "";
if ((licenseStatus == esriLicenseStatus.esriLicenseNotLicensed))
{
licenseMessage = "当前产品未被授权!";
}
else if ((licenseStatus == esriLicenseStatus.esriLicenseUnavailable))
{
licenseMessage = "当前授权信息不可用!";
}
else if ((licenseStatus == esriLicenseStatus.esriLicenseFailure))
{
licenseMessage = "未预料到的授权错误!请联系管理员。";
}
else if ((licenseStatus == esriLicenseStatus.esriLicenseAlreadyInitialized))
{
licenseMessage = "授权已被初始化!请检查功能实现。";
}
return licenseMessage;
}
其中esriLicenseProductCode相当于上图左侧的系列产品,esriLicenseExtensionCode相当于上图右侧的系列扩展。
当然,整个程序关闭时不要忘记执行如下ShutdownApplication函数关闭许可,否则程序进程关闭后依然会存在。
/// <summary>
/// 程序结束时调用,否则程序进程在程序关闭后依然存在
/// </summary>
public static void ShutdownApplication()
{
if (aoInitialize == null)
return;
ExtensionList.ForEach(c =>
{
aoInitialize.CheckInExtension(c);
});
aoInitialize.Shutdown();
aoInitialize = null;
}