Finding extensions with IApplication
The most straightforward way to get a reference to an extension is to use either the FindExtensionByCLSID or FindExtensionByName method of IApplication. The following two code examples show how to get a reference to the ArcMap Editor extension.
To find the Editor extension by the unique identifier object (UID), see the following code:
[C#]
private void GetEditorExtension(IApplication application)
{
//Find extension by CLSID or ProgId.
UID extensionID = new UIDClass();
extensionID.Value = "esriEditor.Editor";
//{F8842F20-BB23-11D0-802B-0000F8037368}.
IExtension editExtension = application.FindExtensionByCLSID(extensionID);
}
[VB.NET]
Sub GetEditorExtension (application As IApplication)
'Find extension by CLSID or ProgId.
Dim extensionID As New UIDClass()
extensionID.Value = "esriEditor.Editor" '{F8842F20-BB23-11D0-802B-0000F8037368}.
Dim editExtension As IExtension = application.FindExtensionByCLSID(extensionID)
End Sub
To find the Editor extension by the name string, see the following code:
[C#]
private void GetEditorExtensionByName(IApplication application)
{
//Find extension by the name.
IExtension editExtension = application.FindExtensionByName("ESRI Object Editor");
}
[VB.NET]
Sub GetEditorExtensionByName (application As IApplication)
'Find extension by the name.
Dim editExtension As IExtension = application.FindExtensionByName("ESRI Object Editor")
End Sub
For more information, see Names and IDs of Esri extensions under Working with ArcGIS Components, General reference, Names and IDs, Extensions.
Just-in-time extensions
Unlike FindExtensionByCLSID, FindExtensionByName only returns extensions that are already loaded in the application. Prior to ArcGIS 9.0, you could use both methods because all extensions were loaded at startup. When the just-in-time (JIT) extension type was introduced at 9.0 to improve application startup performance, these extensions were only loaded by request when FindExtensionByCLSID was called. On the other hand, FindExtensionByName does not perform extension loading for custom JIT extensions, so it may return nothing.
An extension is labeled as loaded only if its IExtension.Startup method has been called by the framework. An extension can be initialized but not loaded.
Many of the extension products shipped with ArcGIS for Desktop are implemented as JIT extensions. The application framework is still capable of loading some of these product extensions by name for backward capability, but it is highly recommended that you update your code using FindExtensionByCLSID instead.
FindExtensionByCLSID is guaranteed to return an extension if a valid identifier is provided. A number of Esri extension products can still be loaded by name; however, third-party JIT extensions must be loaded by the CLSID.
Listing extensions with extension manager interfaces
The application object also implements the IExtensionManager and IJITExtensionManager interfaces, which have properties to get a reference to a particular extension and to get a count of how many extensions are currently loaded. If you're using the IExtensionManager interface to iterate extensions, it will not list JIT extensions. Similarly, if you are using IJITExtensionManager, ordinary extensions are not listed. Iterating JIT extensions by calling FindExtensionByCLSID starts each JIT extension at that point, leaving them in this state until the application exits.
The following code shows how to list all extensions registered in the ArcGIS for Desktop application:
[C#]
private void ExtensionList(IApplication application)
{
List < string > loadedExtensions = new List < string > ();
List < string > unloadedExtensions = new List < string > ();
//All extensions returned by extension manager have been loaded at startup.
IExtensionManager regularExtManager = application as IExtensionManager;
for (int i = 0; i < regularExtManager.ExtensionCount; i++)
{
IExtension ext = regularExtManager.get_Extension(i);
loadedExtensions.Add(ext.Name);
}
//Use IsLoaded to test if a JIT extension has already been loaded by request.
IJITExtensionManager jitExtManager = application as IJITExtensionManager;
for (int i = 0; i < jitExtManager.JITExtensionCount; i++)
{
UID extID = jitExtManager.get_JITExtensionCLSID(i);
if (jitExtManager.IsLoaded(extID))
{
IExtension ext = application.FindExtensionByCLSID(extID);
loadedExtensions.Add(ext.Name);
}
else
//Just show the extension ID.
{
unloadedExtensions.Add(extID.Value.ToString());
}
}
//Print extension information.
Console.WriteLine("Extensions loaded in Application:");
foreach (string ext in loadedExtensions)
Console.WriteLine("\t" + ext);
Console.WriteLine("CLSID of extensions haven't been loaded yet:");
foreach (string extID in unloadedExtensions)
Console.WriteLine("\t" + extID);
}
[VB.NET]
Sub ExtensionList(ByVal application As IApplication)
Dim loadedExtensions As New List(Of String)
Dim unloadedExtensions As New List(Of String)
'All extensions returned by extension manager have been loaded at startup.
Dim regularExtManager As IExtensionManager = DirectCast(application, IExtensionManager)
For i As Integer = 0 To regularExtManager.ExtensionCount - 1
Dim ext As IExtension = regularExtManager.Extension(i)
loadedExtensions.Add(ext.Name)
Next
'Use IsLoaded to test if a JIT extension has already been loaded by request.
Dim jitExtManager As IJITExtensionManager = DirectCast(application, IJITExtensionManager)
For i As Integer = 0 To jitExtManager.JITExtensionCount - 1
Dim extID As UID = jitExtManager.JITExtensionCLSID(i)
If jitExtManager.IsLoaded(extID) Then
Dim ext As IExtension = application.FindExtensionByCLSID(extID)
loadedExtensions.Add(ext.Name)
Else 'Just show the extension ID.
unloadedExtensions.Add(extID.Value.ToString())
End If
Next
'Print extension information.
Console.WriteLine("Extensions loaded in Application:")
For Each ext As String In loadedExtensions
Console.WriteLine("\t" + ext)
Next
Console.WriteLine("CLSID of extensions haven't been loaded yet:")
For Each extID As String In unloadedExtensions
Console.WriteLine("\t" + extID)
Next
End Sub
IExtensionManager.FindExtension works similar to FindExtensionByCLSID or FindExtensionByName on IApplication. Although it accepts either a UID or a name string, the same rule applies when loading JIT extensions. Loading by UID is guaranteed to return an extension if a valid identifier is provided.
Getting enable state of configurable extensions
Some extensions are configurable with the Extension Manager dialog box that shows their enable state (esriExtensionState), product name, and description. These extensions implement IExtensionConfig, so you can access these properties programmatically with this interface. See the following code example:
[C#]
IExtensionManager extManager = application as IExtensionManager;
for (int i = 0; i < extManager.ExtensionCount; i++)
{
IExtension ext = extManager.get_Extension(i);
if (ext is IExtensionConfig)
{
IExtensionConfig extConfig = (IExtensionConfig)ext;
if (extConfig.State == esriExtensionState.esriESEnabled)
Console.WriteLine(extConfig.ProductName + " is enabled");
}
}
[VB.NET]
Dim extManager As IExtensionManager = DirectCast(application, IExtensionManager)
For i As Integer = 0 To extManager.ExtensionCount - 1
Dim ext As IExtension = extManager.get_Extension(i)
If TypeOf ext Is IExtensionConfig Then
Dim extConfig As IExtensionConfig = DirectCast(ext, IExtensionConfig)
If extConfig.State = esriExtensionState.esriESEnabled Then
Console.WriteLine(extConfig.ProductName + " is enabled")
End If
End If
Next
Enable state and JITextensions
A JIT extension can be enabled on the Extension Manager dialog box but still remain unloaded. If you use the IExtensionConfig approach to check the enable state, you will have to load the extension. The IJITExtensionManager interface provides the IsExtensionEnabled method to check the enable state without loading the extension. See the following code example:
[C#]
//Use IsExtensionEnabled for JIT extensions.
IJITExtensionManager jitExtManager = application as IJITExtensionManager;
for (int i = 0; i < jitExtManager.JITExtensionCount; i++)
{
UID extID = jitExtManager.get_JITExtensionCLSID(i);
if (jitExtManager.IsExtensionEnabled(extID))
{
Console.WriteLine("Extension with clsid {0} is enabled", extID.Value);
}
}
[VB.NET]
'Use IsExtensionEnabled for JIT extensions.
Dim jitExtManager As IJITExtensionManager = DirectCast(application, IJITExtensionManager)
For i As Integer = 0 To jitExtManager.JITExtensionCount - 1
Dim extID As UID = jitExtManager.get_JITExtensionCLSID(i)
If jitExtManager.IsExtensionEnabled(extID) Then
Console.WriteLine("Extension with clsid {0} is enabled", extID.Value)
End If
Next
When IsExtensionEnabled returns false, the extension state can be either disabled or unavailable.
Putting it together
Often times, developers create a custom extension to act as a central point of customization, especially when a number of the custom commands and tools must share data or access common UI components. If you're taking advantage of the delay loading mechanism with JIT extensions, your custom commands, tools, and so on, are responsible for controlling when the extension is loaded by calling IApplication.FindExtensionByCLSID.
The following table contains tips on JIT extension loading for custom commands and tools, followed by the sample code:
Commands and tools
|
Description
|
ICommand.OnCreate
|
Delay extension loading (call IApplication.FindExtensionByCLSID) if possible. For example, load at ICommand.OnClick when the command is clicked.
|
ICommand.Enabled
|
To synchronize this with the target extension enable state, use IJITExtensionManager.IsExtensionEnabled instead of loading the extension.
|
Caption, category, bitmap, tooltip, message, and other command appearance properties
|
In general, it is not necessary to load and access the extension unless extension persisted data is required.
|
ICommand.OnClick, ITool.OnMouseDown, IMultiItem.OnPopup, etc.
|
Get the extension by calling IApplication.FindExtensionByCLSID if it is the first time the extension is accessed in the component.
|
See the following code example of an extension and its command:
[C#]
namespace HowToFindExtension
{
[Guid("64c932e1-23c4-4fbd-a46c-6274c766624b")][ClassInterface
(ClassInterfaceType.None)][ProgId("HowToFindExtension.MyExtensionCommand")]
public sealed class MyExtensionCommand: BaseCommand
{
private IApplication m_application;
private UID m_targetExtID;
public MyExtensionCommand()
{
base.m_category = ".NET Samples";
base.m_caption = "Sample Extension Command";
base.m_toolTip = "An extension command";
base.m_name = "CSNetSamples_ExtensionCommand";
}
public override bool Enabled
{
get
{
IJITExtensionManager jitExtMgr = m_application as
IJITExtensionManager;
return jitExtMgr.IsExtensionEnabled(m_targetExtID);
}
}
public override void OnCreate(object hook)
{
m_application = hook as IApplication;
m_targetExtID = new UIDClass();
m_targetExtID.Value = "MyProject.JITConfigurableExtension";
}
public override void OnClick()
{
IExtension ext = m_application.FindExtensionByCLSID(m_targetExtID);
//Code to access the extension object to respond to this event.
}
}
[Guid("0695c804-105f-405d-81d4-8f0a90c19802")][ClassInterface
(ClassInterfaceType.None)][ProgId("MyProject.JITConfigurableExtension")]
public class JITConfigurableExtension: IExtension, IExtensionConfig
{
private IApplication m_application;
private esriExtensionState m_enableState;
#region IExtension Members
public string Name
{
get
{
return "MyJITExtension";
}
}
public void Shutdown()
{
m_application = null;
}
public void Startup(ref object initializationData)
{
m_application = initializationData as IApplication;
}
#endregion
#region IExtensionConfig Members
public string Description
{
get
{
return "My JIT Configurable Extension" + System.Environment.NewLine
+ "This JIT extension is configurable.";
}
}
public string ProductName
{
get
{
return "My JIT Configurable Extension";
}
}
public esriExtensionState State
{
get
{
return m_enableState;
}
set
{
m_enableState = value;
}
}
#endregion
}
}
[VB.NET]
<ComClass(MyExtensionCommand.ClassId, MyExtensionCommand.InterfaceId, MyExtensionCommand.EventsId), _
ProgId("HowToFindExtension.MyExtensionCommand")> _
Public NotInheritable Class MyExtensionCommand
Inherits BaseCommand
#Region "COM GUIDs"
Public Const ClassId As String = "919f7e7e-a3b5-4229-bc1d-93d21f20d87d"
Public Const InterfaceId As String = "405ad9f5-64c3-492c-ac78-aac032c828ba"
Public Const EventsId As String = "70b29988-51ba-4891-9492-99c0cf30abb7"
#End Region
Private m_application As IApplication
Private m_targetExtID As New UIDClass()
Public Sub New()
MyBase.New()
MyBase.m_category = ".NET Samples"
MyBase.m_caption = "Sample Extension Command"
MyBase.m_message = "An extension command"
MyBase.m_name = "VBNetSamples_ExtensionCommand"
End Sub
Public Overrides ReadOnly Property Enabled() As Boolean
Get
Dim jitExtMgr As IJITExtensionManager = DirectCast(m_application, IJITExtensionManager)
Return jitExtMgr.IsExtensionEnabled(m_targetExtID)
End Get
End Property
Public Overrides Sub OnCreate(ByVal hook As Object)
If Not hook Is Nothing Then
m_application = CType(hook, IApplication)
m_targetExtID.Value = "MyProject.JITConfigurableExtension"
End If
End Sub
Public Overrides Sub OnClick()
Dim ext As IExtension = m_application.FindExtensionByCLSID(m_targetExtID)
'Code to access the extension object to respond to this event.
End Sub
End Class
<ComClass(JITConfigurableExtension.ClassId, JITConfigurableExtension.InterfaceId, JITConfigurableExtension.EventsId), _
ProgId("MyProject.JITConfigurableExtension")> _
Public Class JITConfigurableExtension
Implements IExtension
Implements IExtensionConfig
#Region "COM GUIDs"
Public Const ClassId As String = "ff97e400-d940-486f-b92b-608bbae22132"
Public Const InterfaceId As String = "d26ea3da-00a4-44c4-a91e-9cb0385c2db5"
Public Const EventsId As String = "b38c1df9-8ec9-43c4-9522-22a27728a190"
#End Region
Private m_application As IApplication
Private m_enableState As esriExtensionState
Public Sub New()
MyBase.New()
End Sub
#Region "IExtension Members"
Public ReadOnly Property Name() As String Implements IExtension.Name
Get
Return "MyJITExtension"
End Get
End Property
Public Sub Shutdown() Implements IExtension.Shutdown
m_application = Nothing
End Sub
Public Sub Startup(ByRef initializationData As Object) Implements IExtension.Startup
m_application = CType(initializationData, IApplication)
If m_application Is Nothing Then Return
End Sub
#End Region
#Region "IExtensionConfig Members"
Public ReadOnly Property Description() As String Implements IExtensionConfig.Description
Get
Return "My JIT Configurable Extension" + System.Environment.NewLine + _
"This JIT extension is configurable."
End Get
End Property
Public ReadOnly Property ProductName() As String Implements IExtensionConfig.ProductName
Get
Return "My JIT Configurable Extension"
End Get
End Property
Public Property State() As esriExtensionState Implements IExtensionConfig.State
Get
Return m_enableState
End Get
Set(ByVal Value As esriExtensionState)
m_enableState = Value
End Set
End Property
#End Region
End Class
To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)ESRI.ArcGIS.Framework ESRI.ArcGIS.ADF.Local System System.Runtime.InteropServices
Development licensing | Deployment licensing |
---|---|
ArcGIS for Desktop Basic | ArcGIS for Desktop Basic |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |