Building a custom geoprocessing function tool (ArcObjects .NET 10.6 SDK)
ArcObjects Help for .NET developers > Developing with ArcGIS > Learning ArcObjects > Extending ArcObjects > Custom geoprocessing function tools > Building a custom geoprocessing function tool (ArcObjects .NET 10.6 SDK)

Building a custom geoprocessing function tool


Summary
This topic is for developers who want to extend the geoprocessing framework by building geoprocessing tools using ArcObjects. The samples referenced in this topic are programmed using Microsoft Visual Studio. Although this code is developed in VB.NET, the information is applicable to all developers. This topic explains how to build a geoprocessing function tool and describes the ArcObjects necessary for building these tools.

In this topic


Geoprocessing tool overview

A geoprocessing tool can be thought of as an operation that takes an input or set of inputs and generates one or more outputs. These inputs are referred to as parameters. Geoprocessing tools are located in toolboxes and categorized by functionality. Most geoprocessing tools provided by ESRI are implemented as Component Object Model (COM) function tools. A function tool requires implementing a minimum of two objects: a function object that implements IGPFunction2 and a function factory object that implements IGPFunctionFactory.
The following illustration shows the tool relationships, the classes implemented by ESRI, and the classes that are provided to extend the geoprocessing framework. There are four types of geoprocessing tools: GPModelTool, GPFunctionTool, GPCustomTool, and GPScriptTool.
 
Read A quick tour of creating script tools before you begin to create geoprocessing tools. Using the script tool wizard, you can initially prototype the tool by creating parameters and implementing tool validation. This prototype can then be used to help design and implement a function tool.

Rules

There are a few informal rules to keep in mind when building geoprocessing function tools. These rules are useful to begin or conclude discussions about writing functions, and they are as follows:

Properties and methods

There are a number of IGPFunction2 properties and methods that are required when creating geoprocessing function tools, but the following methods are the primary focus of this topic:

IGPFunction2

The IGPFunction2 interface is in the ESRI Geoprocessing library. The following lists each IGPFunction2 property and method with a brief description:
  • Name property—The name of the function tool. This name appears when executing the tool at the command line or in scripting. This name should be unique to each toolbox and cannot contain spaces.
  • DisplayName property—The display name of the function tool. The user interface (UI) utilizes this property to display the name of the tool in ArcToolbox. This name is a user-friendly description of the function tool. The display name can be internationalized.
  • FullName property—The function name object for the geoprocessing function tool. This name object is created and returned by a function factory. A function factory must be created before implementing this property.
  • ParameterInfo property—The location where the parameters to the function tool are defined. This property returns an IArray of parameter objects (IGPParameter). These objects define the characteristics of the input and output parameters.
  • UpdateParameters() method—Called each time a parameter is changed in the tool dialog box or command line. This updates the output data of the tool, which is useful for building models. After returning from UpdateParameters(), geoprocessing calls its internal validation routine, checking that a given set of parameter values are of the appropriate number, data type, and value.
  • UpdateMessages() method—Called after returning from the internal validation routine. You can examine the messages created from internal validation and change them if desired.
  • Validate() method—Validate is an IGPFunction method and no longer needs to be implemented. You stub it out in your class, but you don't have to provide code for it.
  • Execute() method—Executes the tool given the array of parameter values.
  • IsLicensed method—Returns whether the function tool is licensed to execute.
  • HelpFile property (optional)—The path to a .chm file, which is used to describe and explain the function and its operation.
  • HelpContext property (optional)—The unique context identifier in a [MAP] file (.h).
  • MetadataFile property (optional)—The name of the .xml file containing the default metadata for this function object. The metadata file is used to supply the parameter descriptions in the help panel on the dialog box. If no .chm file is provided, the help is based on the metadata file. See Create documentation for custom Geoprocessing tools that are not models or scripts for details.
  • GetRenderer method (optional)—Used to set a custom renderer for the output of the function tool.
  • DialogCLSID property (not for external use)—For ESRI internal use only. DO NOT IMPLEMENT.

IGPParameter3

When designing a geoprocessing function tool, the first step is to define the parameters and set their properties. An IGPParameter3 object is used to create and define the properties of a parameter. The ParameterInfo property returns an array of parameter objects. The IGPParameter3 properties are as follows:
  • Name—The name of the parameter, for example, input_featureclass. It must not contain spaces.
  • DisplayName—The UI uses this name to display the parameter name, for example, Input Features. This can be internationalized.
  • Enabled—Controls whether this parameter is enabled or disabled on the UI.
  • ParameterType—The enumeration for setting the type of geoprocessing parameter. There are three parameter types: esriGPParameterTypeRequired, esriGPParameterTypeOptional, and esriGPParameterTypeDerived.
  • Direction—The enumeration for setting the direction of the parameter. The options are esriGPParameterDirectionInput or esriGPParameterDirectionOutput.
  • DataType—Defines the type of data for this parameter. Examples include FeatureClass, Raster, Table, String, and so on. DataType manages the value for the parameter. If the data type is a feature class, a raster cannot be entered as input.
  • Schema—The structure or design of the feature class or table, raster, and workspace container. The design can be field information, geometry information, or extent.
  • Value—This property defines the default value for a parameter. For every data type, there is an associated value. If the data type is a feature class, the default value for the parameter is a feature class. Values are used as the inputs to the tool containing scalars or a path to the data. For a complete list of value objects, see IGPValue.
  • Domain (optional)—The Domain property can be specified to limit or filter a set of values. An example is a domain for a simple value object, limiting an integer to a range of 1 to 100 (RangeDomain).
  • ParameterDependencies (optional)—Used to set one parameter dependent on another parameter. For example, a field parameter is commonly dependent on another table or feature class parameter, and a list of fields is dependent on the input table.
  • ControlCLSID (optional)—A class identifier can be used to override the default control for the DataType.
  • Category (optional)—Creates a collapsible section on the tool dialog box. This is useful for tools with many optional parameters.
  • ChoiceList (optional)—Supplies a choice list for the command line.
  • DefaultEnvironmentName (optional)—Initializes the environment value to use as the default environment for a parameter.
  • DisplayOrder (optional)—The order in which the parameters are listed on the dialog box. The display order is always the order in the array. In the ParameterInfo property, the parameters should be in this order: required, optional, and derived.
  • Altered—Indicates whether the parameter has been explicitly set by the user.
  • HasBeenValidated—Indicates whether the parameter value has been modified since the last time the parameter was validated.

Parameters

The following illustration shows part of the Add Field function and how a function’s dialog box is created using an array of GPParameter objects. A function publishes an array of its parameters via ParameterInfo(). The array of GPParameter objects is all that is needed to completely define the tool dialog box.
 
Parameters also define the command line syntax for the function as shown in the following illustration:
 
You must always create a new array in ParameterInfo(); never copy or clone an existing array. The following code example shows the general flow of ParameterInfo():
[C#]
Public IArray Parameterinfo
{
    get
    {
        // Array to hold the parameters. Always create a new array.
        IArray parameters=new ArrayClass();

        // Create a parameter and insert it into the parameter array.
        IGPParameterEdit3 inputParameter=new GPParameterClass();
        parameters.Add(inputParameter);

        // Create and insert more parameters as needed.
        // <Insert any required parameters following the steps shown with inputParameter above.>

        // Return the parameter array.
        return parameters;
    }
}
[VB.NET]
Public ReadOnly Property ParameterInfo() As IArray Implements IGPFunction2.ParameterInfo

Get

' Array to hold the parameters. Always create a new array.
Dim parameters As IArray=New ArrayClass()

' Create a parameter and insert it into the parameter array.
Dim inputParameter As IGPParameterEdit3=New GPParameterClass()
parameters.Add(inputParameter)

' Create and insert more parameters as needed.
' <Insert any required parameters following the steps shown with inputParameter above.>


' Return the array.
Return parameters

End Get

End Property

Direction and ParameterType

Direction is either input or output. ParameterType is required, optional, or derived. Required and optional can apply to either input or output parameters. Derived applies only to output parameters. See the following code example:
[C#]
// Required input parameter.
IGPParameterEdit3 inputParameter=new GPParameterClass();
... inputParameter.Direction =
    esriGPParameterDirection.esriGPParameterDirectionInput;
inputParameter.ParameterType=esriGPParameterType.esriGPParameterTypeRequired;
[VB.NET]
' Create the parameter.
Dim inputParameter As IGPParameterEdit3=New GPParameterClass()

' Set parameters as input and required.
inputParameter.Direction=esriGPParameterDirection.esriGPParameterDirectionInput
inputParameter.ParameterType=esriGPParameterType.esriGPParameterTypeRequired
The order of precedence for parameters in the array is required first, optional last. Within each parameter type (required or optional), input parameters are listed before output parameters. In command line and scripting, required parameters are automatically shown with angle brackets (<>) and optional parameters with curly brackets ({}). In the tool dialog box, required parameters that are not filled in are shown with a green dot.
  • ParameterType (derived)A derived parameter is used to indicate when the tool updates the input parameter. For example, the sample tool Calculate area geoprocessing function tool, contains a derived parameter. This tool adds a field to the input feature class and calculates the value for this field. It requires no interaction from the user and does not show up on the tool dialog box or command line. It is used in ModelBuilder to indicate the changed state of the value and to provide proper chaining. Derived parameters are commonly dependent on an input table or feature class parameter. If you drop Add Field into a model, the derived parameter is an output variable, as shown in the following illustration:

Another example of a derived parameter is the Get Count tool, which counts the number of rows in a table and outputs an integer value. The Get Count tool is typically used in models to determine if the application of selection logic will yield features or rows. The Get Count tool's parameters contain an integer output parameter with its ParameterType set to derived. Another example is the Create Feature Class tool, which has a workspace and string (the feature class name) as input and outputs a new derived feature class that is the concatenation of the workspace and string.
The following code example shows how to create a derived parameter:
[C#]
// Output parameter is derived and data type is same as input.
IGPParameterEdit3 outParameter=new GPParameterClass();
... 

// Set output parameter properties.
outParameter.Direction=esriGPParameterDirection.esriGPParameterDirectionOutput;
outParameter.DisplayName="Output Feature Class";
outParameter.Name="output_featureclass";
outParameter.ParameterType=esriGPParameterType.esriGPParameterTypeDerived;
parameters.Add(outParameter);
[VB.NET]
' Output parameter is derived and data type is same as input.
Dim outputParameter As IGPParameterEdit3=New GPParameterClass()

' Set output parameter properties.
outputParameter.Direction=esriGPParameterDirection.esriGPParameterDirectionOutput
outputParameter.DisplayName="Output FeatureClass"
outputParameter.Name="out_featureclass"
outputParameter.ParameterType=esriGPParameterType.esriGPParameterTypeDerived
parameters.Add(outputParameter)
Your function tool can have any number of outputs, and you can use a combination of ParameterTypes. For example, you can have a required output feature class, a derived table, a derived value, and an optional feature class. However, a function tool must always have an output. At the minimum, your function should output a Boolean value containing success or failure.

Name and DisplayName

Name is the language-independent name for the parameter (not localized); DisplayName is the localized name (as it appears in the dialog box) and is contained in resource strings.
A name must not contain spaces and must be unique within a function. As shown in the code example for derived parameters, name can be hard-coded within the function since it is never changed once the function is distributed to users. In code, you are allowed to reference parameters by name. For this reason, do not put the name in a resource file (as is common with DisplayName) since it may be inadvertently localized, which could break your code. Rules for naming parameters are listed as follows:
  • Name parameters are based on the data type (for example, in_features or in_table)
  • Input parameters start with in_, followed by a reference to their data type (for example, in_features or in_table)
  • Output parameters start with out_, followed by a reference to their data type (for example, out_feature_class or out_view)
You can research other functions for parameter naming precedence.

Category

A category is used to group parameters together in the dialog box as shown in the following illustration. Categories are useful when you have many parameters. Using categories can save screen space and allow the user to focus on the primary arguments. Never put required arguments in a category, since the user will not immediately see that they are required.
 

DisplayOrder

The default is to show the parameters in the order they appear in the array returned by ParameterInfo(). For legacy support, you can override this by providing a DisplayOrder. If you override, provide a DisplayOrder for each parameter. You are not building legacy functions, so you do not need to use display order; instead, use the order of the parameters in the array, since they match the scripting and command line usage.

Enabled

False means the control is disabled (unavailable). You can set the initial enabled state when building a parameter; however, it’s not necessary because you may be setting the enabled state in UpdateParameters() based on the contents of other parameters. See the following illustration:

Parameter DataTypes

This section describes a number of parameter DataTypes.

Supporting layers and tables

To support layers and table views in ArcMap and ArcGlobe, the DataType for the parameter must be a FeatureLayer, RasterLayer, or TableView. For a complete list of layer DataType objects, see IGPLayerType.
The following code defines the DataType of an input parameter to support feature layers:
[C#]
// Define input DataType as GPFeatureLayerType to support layers.
IGPParameterEdit3 inputParameter=new GPParameterClass();
inputParameter.DataType=new GPFeatureLayerTypeClass();
[VB.NET]
' Define input DataType as GPFeatureLayerType to support layers.
Dim inputParameter As IGPParameterEdit3=New GPParameterClass()
inputParameter.DataType=New GPFeatureLayerTypeClass()

Multiple values

Tools such as those that perform batch conversion between different formats can have parameters that allow multiple inputs. The following code example shows how to create a parameter that allows for multiple input feature layers:
[C#]
// Multivalue parameter of Feature Layers/Feature Classes.
IGPParameterEdit3 inputFeatures=new GPParameterClass();
IGPDataType inputType=new GPFeatureLayerTypeClass();

IGPMultiValueType mvType=new GPMultiValueTypeClass();
mvType.MemberDataType=inputType;

IGPMultiValue mvValue=new GPMultiValueClass();
mvValue.MemberDataType=inputType;

inputFeatures.Name="input_features";
inputFeatures.DisplayName="Input Features";
inputFeatures.ParameterType=esriGPParameterType.esriGPParameterTypeRequired;
inputFeatures.Direction=esriGPParameterDirection.esriGPParameterDirectionInput;
inputFeatures.DataType=(IGPDataType)mvType;
inputFeatures.Value=(IGPValue)mvValue;

parameters.Add(inputFeatures);
[VB.NET]
' Multivalue parameter of Feature Layers/Feature Classes.
Dim inputParameter As IGPParameterEdit3=New GPParameterClass()
Dim inputType As IGPDataType=New GPFeatureLayerTypeClass()

Dim mvType As IGPMultiValue=New GPMultiValueClass()
mvType.MemberDataType=inputType

Dim mvValue As IGPMultiValue=New GPMultiValueClass()
mvValue.MemberDataType=inputType

inputFeatures.Name="input_features"
inputFeatures.DisplayName="Input Features"
inputFeatures.ParameterType=esriGPParameterType.esriGPParameterTypeRequired
inputFeatures.Direction=esriGPParameterDirection.esriGPParameterDirectionInput
inputFeatures.DataType=CType(mvType, IGPDataType)
inputFeatures.Value=CType(mvValue, IGPValue)

parameters.Add(inputFeatures)

Lists

In some cases, the parameter may be a table of one or more DataTypes. This DataType is referred to as a ValueTable. An example of this is the Union tool. The input parameter for this tool is a table with two columns. The DataType of the first column is a FeatureLayer and the DataType of the second column is a Long. The following code defines a ValueTable DataType:
[C#]
// DataType and value.
IGPValueTableType valueTableType=new GPValueTableTypeClass();
IGPValueTable valueTable=new GPValueTableClass();

// First DataType is GPFeatureLayerType.
IGPDataType inputLayerType=new GPFeatureLayerTypeClass();
valueTableType.AddDataType(inputLayerType, "input_features", 75, null);
valueTable.AddDataType(inputLayerType);

// Second DataType is GPLongType.
IGPDataType inputLongType=new GPLongTypeClass();
valueTableType.AddDataType(inputLongType, "Rank", 25, null);
valueTable.AddDataType(inputLongType);

// Set input parameter.
IGPParameterEdit3 inParameter=new GPParameterClass();
inParameter.DataType=(IGPDataType)valueTableType;
inParameter.Value=(IGPValue)valueTable;
...... parameters.Add(inParameter);
[VB.NET]
' DataType and value.
Dim valueTableType As IGPValueTableType=New GPValueTableTypeClass()
Dim valueTable As IGPValueTable=New GPValueTableClass()

' First data type is GPFeatureLayerType.
Dim inputLayerType As IGPDataType=New GPFeatureLayerTypeClass()
valueTableType.AddDataType(inputLayerType, "Input Features", 75, Nothing)
valueTable.AddDataType(inputLayerType)

' Second type is GPLongType.
Dim inputLongType As IGPDataType=New GPLongTypeClass()
valueTableType.AddDataType(inputLongType, "Rank", 25, Nothing)
valueTable.AddDataType(inputLongType)

' Set the input parameter.
Dim inputParameter As IGPParameterEdit3=New GPParameterClass()
inputParameter.DataType=CType(valueTableType, IGPDataType)
inputParameter.Value=CType(valueTable, IGPValue)
....
parameters.Add(inputParameter)

Composite

In other cases, the input value for the parameter allows different DataTypes. This is referred to as a Composite DataType. This DataType is used when the parameter can be more than one DataType. An example of this is the Append tool. The input can be a raster, a table, or a feature class. The following code defines a Composite DataType:
[C#]
// Create the GPCompositeDataType.
IGPCompositeDataType compositeType=new GPCompositeDataTypeClass();

// Create the DataTypes that are permitted as input.
IGPDataType dataType1=new GPTableViewTypeClass();
IGPDataType dataType2=new GPRasterLayerTypeClass();

// Add DataTypes.
compositeType.AddDataType(dataType1);
compositeType.AddDataType(dataType2);

// Set the input parameter.
IGPParameterEdit3 inputParameter=new GPParameterClass();
inputParameter.DataType=compositeType;
inputParameter.Value=new GPTableViewClass();
[VB.NET]
' Create the GPCompositeDataType.
Dim compositeType As IGPCompositeDataType=New GPCompositeDataTypeClass()

' Create the DataTypes that are permitted as input.
Dim dataType1 As IGPDataType=New GPTableViewTypeClass()
Dim dataType2 As IGPDataType=New GPRasterLayerTypeClass()

' Add DataTypes.
compositeType.AddDataType(dataType1)
compositeType.AddDataType(dataType2)

' Set the input parameter.
Dim inputParameter As IGPParameterEdit3=New GPParameterClass()
inputParameter.DataType=CType(compositeType, IGPDataType)

Updating output data descriptions

All tools should update the description of the output data for use in ModelBuilder. By updating the description, subsequent processes in ModelBuilder can recognize changes to the data before a process is run.
The following illustrations show how subsequent processes recognize pending changes. The first illustration shows a model that contains the Add Field and Calculate Field tools. The output data variable for Add Field, Parks (2), is updated to contain the new field, TrackingID. Because the output is updated, the Calculate Field dialog box shows TrackingID in the list of field names.
The next illustration shows a model where the output of the Clip tool is used as input to the Polygon to Raster tool. Since the Clip tool "cookie cuts" the input features, the output feature class has the same properties as the input feature class with one notable exception: its geographic extent. The geographic extent of the output feature class is the geometric intersection of the input features and clip features geographic extents. The Polygon to Raster tool uses the new geographic extent to determine a default cell size.
 
With IGPFunction2.ParameterInfo(), you can use a Schema object to set rules for building the description of the output. For example, you can set rules such as the following:
  • Make a copy of the input dataset description and add a new field to its list of fields (such as Add Field), or add a list of fixed fields (such as Add XY Coordinates).
  • Set the list of output fields to be all the fields in a collection of datasets and, optionally, add fields to contain the feature IDs from the collection of datasets (such as Union and Intersect).
  • Set the extent to that of a dataset in another parameter, or the union or intersection (such as Clip) of datasets in a list of parameters.
  • Set a specific geometry type (point, line, or polygon), or set the geometry type to that of a dataset in another parameter, or to minimum or maximum type in a list of parameters. The definition of minimum and maximum geometry type is: points=0, polylines=1, and polygons=2. Consequently, the minimum geometry type in the set (point, polyline, polygon) is point and the maximum is polygon.
The Schema property on the IGPParameterEdit3 interface controls the generation and population of outputs providing you control without having to write validation code as was required prior to ArcGIS 9.3. Not all functions can fully populate the output data; however, there is a list of those properties that must be set. For feature data, feature type, geometry type, field schema, and extent are important. For table data, field schema is important. For raster data, extent, cell size, raster format, and raster type are important. For each group, there is a schema object. These objects all support the IGPSchema interface, which is used to update the output parameter’s value. Each object in the following diagram has its own interface that can be used to set the behavior of how the output parameter value is updated:
 

Parameter dependency

You can declare that a parameter is dependent on the value in another parameter. The most common use of parameter dependency is for listing fields in a table. When listing fields, the field parameter is dependent on the input table parameter as shown in the following code example:
[C#]
// Create the field parameter.
IGPParameterEdit3 fieldParameter=new GPParameterClass();
fieldParameter.DataType=new FieldTypeClass();
... 
// Add dependency to the input feature class parameter by name.
fieldParameter.AddDependency("input_features");
[VB.NET]
' Create the field parameter.
Dim fieldParameter As IGPParameterEdit3=New GPParameterClass();
fieldParameter.DataType=New FieldTypeClass();
...
' Add dependency to the input feature class parameter by name.
fieldParameter.AddDependency ("input_features");
When you create a rule such as "copy the fields of the dataset in parameter 3, then add a field", you have to tell the Schema object what parameter you want to copy from (parameter 3 in this case). This is done by adding dependencies to the parameter object.

Updating output data and using dependencies

This section gives two examples of updating output data and using dependencies.

Add field

Add field copies the definition of an input parameter then adds the user-specified field as shown in the following code:
[C#]
public IArray ParameterInfo
{
    get
    {
        //Array to hold the parameters.
        IArray parameters=new ArrayClass();
        ... 

        // Output parameter (derived) and data type is DEFeatureClass.
        IGPParameterEdit3 outputParameter=new GPParameterClass();
        outputParameter.DataType=new GPFeatureLayerTypeClass();

        // Value object is DEFeatureClass.
        outputParameter.Value=new DEFeatureClassClass();

        // Set output parameter properties.
        outputParameter.Direction =
            esriGPParameterDirection.esriGPParameterDirectionOutput;
        outputParameter.DisplayName="Output FeatureClass";
        outputParameter.Name="out_featureclass";
        outputParameter.ParameterType =
            esriGPParameterType.esriGPParameterTypeDerived;

        // Create a schema object. Schema means the structure or design of the feature class 
        // (field  information, geometry information, extent).
        IGPFeatureSchema outputSchema=new GPFeatureSchemaClass();
        IGPSchema schema=(IGPSchema)outputSchema;

        // Clone the schema from the dependency.
        //This means update the output with the same schema by copying the definition of an input parameter.
        schema.CloneDependency=true;

        // Set the schema on the output, because this tool adds an additional field.
        outputParameter.Schema=outputSchema as IGPSchema;
        outputParameter.AddDependency("input_features");
        parameters.Add(outputParameter);

        return parameters;
    }
}

// This method updates the output parameter value with the additional field.
public void UpdateParameters(IArray paramvalues, IGPEnvironmentManager pEnvMgr)
{
    m_Parameters=paramvalues;

    // Retrieve the input parameter value.
    IGPValue parameterValue=m_GPUtilities.UnpackGPValue(m_Parameters.get_Element(0)
        );

    // Get the derived output feature class schema and empty the additional fields. This ensures 
    // that you don't get dublicate entries. 
    // Derived output is the third parameter, so use index 2 for get_Element.
    IGPParameter3 derivedFeatures=(IGPParameter3)paramvalues.get_Element(2);
    IGPFeatureSchema schema=(IGPFeatureSchema)derivedFeatures.Schema;
    schema.AdditionalFields=null;

    // If you have an input value, create a field based on the field name entered.            
    if (parameterValue.IsEmpty() == false)
    {
        // Area field name is the second parameter, so use index 1 for get_Element.
        IGPParameter3 fieldNameParameter=(IGPParameter3)paramvalues.get_Element(1);
        string fieldName=fieldNameParameter.Value.GetAsText();

        // Check if the input field already exists.
        IField areaField=m_GPUtilities.FindField(parameterValue, fieldName);
        if (areaField == null)
        {
            IFieldsEdit fieldsEdit=new FieldsClass();
            IFieldEdit fieldEdit=new FieldClass();
            fieldEdit.Name_2=fieldName;
            fieldEdit.Type_2=esriFieldType.esriFieldTypeDouble;
            fieldsEdit.AddField(fieldEdit);

            // Add the additional field to the derived output.
            IFields fields=fieldsEdit as IFields;
            schema.AdditionalFields=fields;
        }
    }
}
[VB.NET]
Public ReadOnly Property ParameterInfo() As IArray Implements IGPFunction2.ParameterInfo
Get

' Array to the hold the parameters. Always create a new array.
Dim parameters As IArray=New ArrayClass()

' Output parameter (derived).
Dim outputParameter As IGPParameterEdit3=New GPParameterClass()
outputParameter.DataType=New DEFeatureClassTypeClass()

' Value object is DEFeatureClass.
outputParameter.Value=New DEFeatureClassClass()

' Set output parameter properties.
outputParameter.Direction=esriGPParameterDirection.esriGPParameterDirectionOutput
outputParameter.ParameterType=esriGPParameterType.esriGPParameterTypeDerived
outputParameter.Name="out_featureclass"
outputParameter.DisplayName="Output Feature Class"

' Create a schema object. Schema means the structure or design of the feature class
' (field  information, geometry information, extent).
Dim outputSchema As IGPFeatureSchema=New GPFeatureSchemaClass()
Dim schema As IGPSchema=CType(outputSchema, IGPSchema)

' Clone the schema from the dependency.
' This means update the output with the same schema by copying the definition of an input parameter.
schema.CloneDependency=True

' Set the schema on the output, because this tool adds an additional field.

outputParameter.Schema=CType(outSchema, IGPSchema)
outputParameter.AddDependency("input_features")
parameters.Add(outputParameter)

Return parameters

End Get
End Property


' This method updates the output parameter value with the additional field.

Public Sub UpdateParameters(ByVal paramvalues As IArray, ByVal pEnvMgr As IGPEnvironmentManager) Implements IGPFunction2.UpdateParameters
    
    ' m_Parameters is a class member.
    ' Private m_Parameters As IArray.
    m_Parameters=paramvalues
    
    ' Retrieve the input parameter value.
    Dim parameterValue As IGPValue=m_GPUtilities.UnpackGPValue(m_Parameters.Element(0))
    
    ' Get the derived output feature class schema and empty the additional fields.
    ' This will ensure you don't get dublicate entries.
    ' Derived output is the third parameter, so use index 2 for get_Element.
    Dim derivedFeatures As IGPParameter3=CType(paramvalues.Element(2), IGPParameter3)
    Dim schema As IGPFeatureSchema=CType(derivedFeatures.Schema, IGPFeatureSchema)
    schema.AdditionalFields=Nothing
    
    ' Retrieve the field parameter value.
    Dim fieldNameParameter As IGPParameter3=CType(paramvalues.Element(1), IGPParameter3)
    
    ' If you have an input value, create a field based on the field name the user entered.
    If parameterValue.IsEmpty()=False Then
        Dim fieldNameParameter As IGPParameter3
        fieldNameParameter=CType(paramvalues.Element(1), IGPParameter3)
        
        Dim fieldName As String
        fieldName=fieldNameParameter.Value.GetAsText()
        
        ' Check if the user's entered value already exists.
        Dim areaField As IField=m_GPUtilities.FindField(parameterValue, fieldName)
        
        If areaField Is Nothing Then
            
            Dim fieldsEdit As IFieldsEdit=New Fields
            Dim fieldEdit As IFieldEdit=New Field
            
            fieldEdit.Name_2=fieldName
            fieldEdit.Type_2=esriFieldType.esriFieldTypeDouble
            fieldsEdit.AddField(fieldEdit)
            
            ' Add the additional field to the derived output.
            Dim pFields As IFields=fieldsEdit
            
            schema.AdditionalFields=pFields
        End If
    End If
    
End Sub

Clip

Clip makes a copy of the input feature's definition, then sets the extent to the intersection of the input features and the clip features. The following code example shows how this rule is implemented in ParameterInfo():
[C#]
public IArray ParameterInfo
{
    get
    {
        //Array to hold the parameters.
        IArray parameters=new ArrayClass();
        ... 
        // New output features.
        outParameter=new GPParameterClass();
        outParameter.DataType=new DEFeatureClassTypeClass();
        outParameter.Value=new DEFeatureClassClass();
        outParameter.Direction =
            esriGPParameterDirection.esriGPParameterDirectionOutput;
        outParameter.ParameterType=esriGPParameterType.esriGPParameterTypeRequired;
        outParameter.Name="Output_Feature_Class";
        outParameter.DisplayName="Output Feature Class";

        // Set the dependencies for the output and its schema properties.
        outParameter.AddDependency("input_features");
        outParameter.AddDependency("clip_features");

        // Feature type, geometry type, and fields all come from the first dependent—the input features.
        IGPFeatureSchema outSchema=new GPFeatureSchemaClass();
        outSchema.FieldsRule =
            esriGPSchemaFieldsType.esriGPSchemaFieldsFirstDependency;
        outSchema.FeatureTypeRule =
            esriGPSchemaFeatureType.esriGPSchemaFeatureFirstDependency;
        outSchema.GeometryType=esriGeometryType.esriGeometryPolygon;
        outSchema.ExtentRule=esriGPSchemaExtentType.esriGPSchemaExtentIntersection;

        IGPSchema schema=outSchema as IGPSchema;
        // Generate the default output path.
        schema.GenerateOutputCatalogPath=true;
        outParameter.Schema=(IGPSchema)outSchema;

        parameters.Add(outParameter);

        return parameters;
    }
}
[VB.NET]
Public ReadOnly Property ParameterInfo() As IArray Implements IGPFunction2.ParameterInfo
Get

' Array to hold the parameters.
Dim parameters As IArray=New ArrayClass()

' New Output Features - Convex Hull Polygons.
Dim outParameter As IGPParameterEdit3=New GPParameterClass()
outParameter.DataType=New DEFeatureClassTypeClass()
outParameter.Value=New DEFeatureClassClass()
outParameter.Direction=esriGPParameterDirection.esriGPParameterDirectionOutput
outParameter.ParameterType=esriGPParameterType.esriGPParameterTypeRequired
outParameter.Name="out_featureclass"
outParameter.DisplayName="Output Feature Class"

' Set the dependencies for the output and its schema properties.
outParameter.AddDependency("input_features")
outParameter.AddDependency("clip_features")

' Feature type, geometry type, and fields all come from the first dependent—the input features.
Dim outSchema As IGPFeatureSchema=New GPFeatureSchemaClass()
outSchema.FieldsRule=esriGPSchemaFieldsType.esriGPSchemaFieldsFirstDependency
outSchema.FeatureTypeRule=esriGPSchemaFeatureType.esriGPSchemaFeatureFirstDependency
outSchema.GeometryType=esriGeometryType.esriGeometryPolygon
outSchema.ExtentRule=esriGPSchemaExtentType.esriGPSchemaExtentIntersection

' Generate the default output path, which is available through the IGPSchema interface.
Dim schema As IGPSchema=CType(outSchema, IGPSchema)
schema.GenerateOutputCatalogPath=True
outParameter.Schema=CType(outSchema, IGPSchema)

parameters.Add(outParameter)

Return parameters

End Get
End Property
The previous Clip example modifies Schema in ParameterInfo(), but UpdateParameters() does nothing in return. Add Field, however, modifies Schema in UpdateParameters() because it doesn't know the definition of the field to add until you provide the information and UpdateParameters() is called.
Think of these two examples as static versus dynamic. Clip doesn't rely on anything other than the datasets in the dependent parameters (static case), whereas Add Field needs to examine other parameters (such as field name and field type) that are not dependent parameters (dynamic case).
This static and dynamic behavior is evident in the way a tool validation is performed as shown in the following steps:
  1. When the tool dialog box is opened, ParameterInfo() is called. You set the static rules for describing the output. No output description is created since you haven't specified values for the parameters.
  2. Once you interact with the tool dialog box, UpdateParameters() is called. UpdateParameters() can modify Schema to account for dynamic behavior that can't be determined from the parameter dependencies, such as adding a new field (Add Field) for example.
  3. After returning from UpdateParameters(), the internal validation routines are called, and the rules in the Schema object are applied to update the description of the output data.
  4. UpdateMessages() is called. You can examine the warning and error messages that internal validation may have created and modify them, or add warnings and errors based on the interaction of actual parameter values.
When you set the IGPSchema.CloneDependency property to true, you are instructing geoprocessing to make an exact copy (clone) of the description in the first dependent parameter in the parameter dependency list. You set IGPSchema.CloneDependency to true in the ParameterInfo() property, not in the UpdateParameters() method.
If the ParameterType of the output parameter is set to derived, an exact copy is made. This is the behavior of the Add Field tool.
If the ParameterType is set to required, an exact copy is also made, but the catalog path to the dataset is changed. Since most tools create new data, this is the most common behavior. Clone can be thought of as setting the initial state of the output.

Domains

Domains are used to supply a fixed set of values for a parameter or to filter values for a parameter. The most common uses for domains are as follows:
  • Defining input feature types (point, line, polygon)
  • Creating a fixed list of string keywords (point, multipoint, polygon, polyline)
  • Defining a Boolean choice
  • Filtering field types (text, long, double, object ID, and so on)

Feature type

If the input features can only be points, geoprocessing uses a domain to build the choice list of layers or features in the catalog minibrowser. The filtering occurs when the data type validates the value. In ParameterInfo(), the input feature class parameter is built where a domain is used to filter the input feature classes to only polygon features as shown in the following code example:
[C#]
// Filter the input features to polygon features only.
IGPFeatureClassDomain fcDomain=new GPFeatureClassDomainClass();
fcDomain.AddFeatureType(esriFeatureType.esriFTSimple);
fcDomain.AddType(esriGeometryType.esriGeometryPolygon);
... 

inputParameter.Domain=(IGPDomain)fcDomain;
[VB.NET]
' Filter the input features to polygon features only.
Dim fcDomain As IGPFeatureClassDomain=New GPFeatureClassDomainClass()
fcDomain.AddFeatureType(esriFeatureType.esriFTSimple)
fcDomain.AddType(esriGeometryType.esriGeometryPolygon)
...

inputParameter.Domain=CType(fcDomain, IGPDomain)

String keywords

The following code example is from the Add Field function and shows how to build a coded value domain containing keywords for field type (that is, text, float, double, and so on). These keywords are all hard coded in the function since they are never changed once the function is released to users. You can use these hard-coded strings in code, such as in if/then/else logic. For this reason, do not put the keywords in a resource file since they can be inadvertently localized, which could break your code. Do not localize keywords. Keywords should appear in all capital letters. Syntactically, they must be listed with the default keyword first. In documentation, the default keyword is followed by all other keywords separated with a vertical bar (|). (For example, POINT | LINE | POLYGON).
[C#]
// Create a fixed list of string values. 
IGPCodedValueDomain cvDomain=new GPCodedValueDomainClass();
cvDomain.AddStringCode("TEXT", "TEXT");
cvDomain.AddStringCode("FLOAT", "FLOAT");
... inputParameter.Domain=IGPDomain(cvDomain);
[VB.NET]
' Create a fixed list of string values
Dim cvDomain As IGPCodedValueDomain=New GPCodedValueDomainClass()
cvDomain.AddStringCode("TEXT", "TEXT")
cvDomain.AddStringCode("FLOAT", "FLOAT")
...
inputParameter.Domain=CType(cvDomain, IGPDomain)

Boolean parameters

Boolean parameters contain a coded value domain with Boolean values and corresponding string codes. In a dialog, Boolean parameters show as a check box, but in command line and scripting, they show as a choice between two strings. You should always use a coded value domain for a Boolean parameter as shown in the following code example:
[C#]
// Always create a coded value domain for Boolean parameters.
IGPParameterEdit3 pContinueCompare=new GPParameterClass();
... IGPCodedValueDomain pContinueDomain=new GPCodedValueDomainClass();
IGPBoolean pVal1=new GPBooleanClass();
pVal1.Value=true;
IGPBoolean pVal2=new GPBooleanClass();
pVal2.Value=false;

pContinueDomain.AddCode((IGPValue)pVal1, "CONTINUE_COMPARE");
pContinueDomain.AddCode((IGPValue)pVal2, "NO_CONTINUE_COMPARE");
... pContinueCompare.Domain=(IGPDomain)pContinueDomain;
[VB.NET]
' Always use a coded value domain for Boolean parameters
Dim pContinueCompare As IGPParameterEdit3=New GPParameterClass()
...
Dim pContinueDomain As IGPCodedValueDomain=New GPCodedValueDomainClass()
Dim pVal1 As IGPBoolean=New GPBooleanClass()
pVal1.Value=True
Dim pVal2 As IGPBoolean=New GPBooleanClass()
pVal2.Value=False
pContinueDomain.AddCode(CType(pVal1, IGPValue), "CONTINUE_COMPARE")
pContinueDomain.AddCode(CType(pVal2, IGPValue), "NO_CONTINUE_COMPARE")
...
pContinueCompare.Domain=CType(pContinueDomain, IGPDomain)

Dynamic domains

Domains can be dynamic—their values are set in UpdateParameters()—as opposed to static—the CodedValue domain of keywords constructed in ParameterInfo(). For example, you have a parameter containing keywords, but you want the keywords to change depending on another parameter; that is, you want one set of keywords if point features are input, and another set if line features are input. This is not unusual, and the pattern you’ll see most often is to populate the domain of the parameter in UpdateParameters(). Another example is a coded value domain of SDE configuration keywords. The list changes based on the workspace selected. The UpdateParameters() section provides an example of updating dynamic domains.

ControlCLSID

GPDataType has a default UI control named ControlCLSID. For many parameters, the data type’s default control is all you'll use. With other parameters, especially strings, you may want to use another UI control. String parameters are ubiquitous, and there are two methods by which you can change the UI for string input. You can use a domain, as previously described, to create a drop-down list of strings, or, you can use a different (non-default) control. The following illustration shows the default string control and the multivalue control for the same set of strings:
 
The following code example shows how the multiple value control is used to present a checklist of strings:
[C#]
// Create Accumulators parameters.
IGPParameterEdit3 pAccumulators=new GPParameterClass();

IGPDataType pGPDataType2=new GPStringTypeClass();
IGPMultiValue pMultiValue2=new GPMultiValueClass();
pMultiValue2.MemberDataType=pGPDataType2;

IGPCodedValueDomain pAccumulatorsDomain=new GPCodedValueDomainClass();
pAccumulatorsDomain.AddStringCode("Minutes", "Minutes");
pAccumulatorsDomain.AddStringCode("Meters", "Meters");

IGPMultiValueType pMultiValueType2=new GPMultiValueTypeClass();
pMultiValueType2.MemberDataType=pGPDataType2;

pAccumulators.Name="accumulators";
pAccumulators.DisplayName="Accumulators";
pAccumulators.ParameterType=esriGPParameterType.esriGPParameterTypeOptional;
pAccumulators.Direction=esriGPParameterDirection.esriGPParameterDirectionInput;
pAccumulators.Domain=(IGPDomain)pAccumulatorsDomain;
pAccumulators.DataType=(IGPDataType)pMultiValueType2;
pAccumulators.Value=(IGPValue)pMultiValue2;

// MdList Control's GUID—Use OLE Object view to get this.
UID pUID=new UIDClass();
pUID.Value="{38C34610-C7F7-11D5-A693-0008C711C8C1}";
pAccumulators.ControlCLSID=pUID;

m_pParameters.Add(pAccumulators);
[VB.NET]
' Create Accumulators parameter.
Dim pAccumulators As IGPParameterEdit3=New GPParameterClass()

Dim pGPDataType2 As IGPDataType=New GPStringTypeClass()
Dim pMultiValue2 As IGPMultiValue=New GPMultiValueClass()
pMultiValue2.MemberDataType=pGPDataType2

Dim pAccumulatorsDomain As IGPCodedValueDomain=New GPCodedValueDomainClass()
pAccumulatorsDomain.AddStringCode("Minutes", "Minutes")
pAccumulatorsDomain.AddStringCode("Meters", "Meters")

Dim pMultiValueType2 As IGPMultiValueType=New GPMultiValueTypeClass()
pMultiValueType2.MemberDataType=pGPDataType2

pAccumulators.Name="accumulators"
pAccumulators.DisplayName="Accumulators"
pAccumulators.ParameterType=esriGPParameterType.esriGPParameterTypeOptional
pAccumulators.Direction=esriGPParameterDirection.esriGPParameterDirectionInput
pAccumulators.Domain=CType(pAccumulatorsDomain, IGPDomain)
pAccumulators.DataType=CType(pMultiValueType2, IGPDataType)
pAccumulators.Value=CType(pMultiValue2, IGPValue)

' MdList Control's GUID—Use OLE Object view to get this.
Dim pUID As UID=New UIDClass()
pUID.Value="{38C34610-C7F7-11D5-A693-0008C711C8C1}"
pAccumulators.ControlCLSID=pUID

parameters.Add(pAccumulators)

Methods

This section describes a number of geoprocessing methods.

UpdateParameters()

This method has been previously discussed and demoed. Additional use cases of UpdateParameters() are described as follows:
  • Parameter interaction—For some tools, it may be necessary to set rules for parameters. For example, when adding a field to an input table, one rule may be to limit the length of the field name by setting a maximum number of allowable characters. Another parameter interaction is enabling and disabling parameters. For instance, when using Add Field and selecting TEXT as the type of field to add, the field length parameter is enabled. The following code is an example of enabling and disabling a parameter based on user input:
[C#]
// Get the Boolean parameter value (second parameter for this tool).
IGPBoolean val1=(IGPBoolean)pGPUtilities.UnpackGPValue(m_Parameters.get_Element(1))
    ;

// Get the string parameter (third parameter for this tool).
IGPParameterEdit3 stringParam=(IGPParameterEdit3)m_Parameters.get_Element(2);

if (val1.Value == true)
{
    stringParam.Enabled=false;
}

else
{
    stringParam.Enabled=true;
}
[VB.NET]
' Get the Boolean parameter value (second parameter for this tool).
Dim val1 As IGPBoolean=CType(m_GPUtilities.UnpackGPValue(m_Parameters.Element(1)), IGPBoolean)

' Get the string parameter (third parameter for this tool).
Dim stringParam As IGPParameterEdit3=CType(m_Parameters.Element(2), IGPParameterEdit3)

If val1.Value=True Then
    stringParam.Enabled=False
Else
    stringParam.Enabled=True
End If
Domains can also change based on user inputs and can be dynamic as explained previously. The following code is an example of updating a coded value domain in UpdateParameters():
[C#]
// Get the Boolean parameter value (second parameter for this tool).
IGPBoolean val1=(IGPBoolean)pGPUtilities.UnpackGPValue(m_Parameters.get_Element(1))
    ;

// Get the coded value parameter.
IGPParameter3 cvParam=(IGPParameter3)m_Parameters.get_Element(3);
IGPParameterEdit3 cvParamEdit=cvParam as IGPParameterEdit3;

IGPCodedValueDomain cvDomain;

// If the Boolean parameter value is true, update the domain with new values.
if (val1.Value == true)
{
    stringParam.Enabled=true;
    cvDomain=new GPCodedValueDomainClass();
    cvDomain.AddStringCode("Seconds", "Seconds");
    cvDomain.AddStringCode("Feet", "Feet");
    cvParamEdit.Domain=cvDomain as IGPDomain;
}
[VB.NET]
'Get the Boolean parameter value (second parameter for this tool).
Dim val1 As IGPBoolean=CType(m_GPUtilities.UnpackGPValue(m_Parameters.Element(1)), IGPBoolean)

'Get the coded value parameter (third parameter for this tool).
Dim cvParam As IGPParameter3=CType(m_Parameters.Element(0), IGPParameter3)
Dim cvParamEdit As IGPParameterEdit3=CType(cvParam, IGPParameterEdit3)

Dim cvDomain As IGPCodedValueDomain

Dim stringParam As IGPParameterEdit3=CType(m_Parameters.Element(0), IGPParameterEdit3)

' If the Boolean parameter value is true, update the domain with new values.
If val1.Value=True Then
    stringParam.Enabled=True
    cvDomain=New GPCodedValueDomainClass()
    cvDomain.AddStringCode("Seconds", "Seconds")
    cvDomain.AddStringCode("Feet", "Feet")
    cvParamEdit.Domain=CType(cvDomain, IGPDomain)
End If
  • Setting a default value—The following code is an example of setting a default value for a parameter. This default value will be set if the parameter has not been altered or is blank.
[C#]
//  Set a default distance value if the user has not set a specific distance (Altered is true).
IGPParameter3 distParam=(IGPParameter3)m_Parameters.get_Element(7);
if (distParam.Altered == false)
{
    distParam.Value.SetAsText("100");
}
[VB.NET]
' Set a default distance value if the user has not set a specific distance (Altered is true).
Dim distParam As IGPParameter3=CType(m_Parameters.Element(7), IGPParameter3)
If distParam.Altered=False
    distParam.Value.SetAsText("100")
End If

UpdateMessages()

This method is called after returning from the internal validation routine performed by the geoprocessing framework. This method is where you can examine the messages created from internal validation and change them if desired. Only change existing messages; do not add new messages. The following code is an example of updating an error message for a parameter:
[C#]
// Check if the distance is greater than zero.
IGPLinearUnit distVal=(IGPLinearUnit)pGPUtilities.UnpackGPValue
    (paramvalues.get_Element(7));

if (distVal.Value <= 0)
{
    Messages.ReplaceError(7, 2, 
        "Zero or a negative distance is invalid when using a fixed distance band. Use a positive value greater than zero.");
}
[VB.NET]
' Check if the distance is greater than zero.
Dim distVal As IGPLinearUnit=CType(pGPUtilities.UnpackGPValue(paramvalues.Element(7)), IGPLinearUnit)

If distVal.Value <= 0 Then
    Messages.ReplaceError(7, 2, "Zero or a negative distance is invalid when using a fixed distance band. Use a positive value greater than zero.")
End If

Validate()

The Validate() method no longer needs to be implemented.
Validate() is used to perform a lightweight verification that a given set of parameter values were of the appropriate number, data type, and value. At ArcGIS 9.3, this method was replaced by UpdateParameters() and UpdateMessages() and no longer needs to be implemented. It must be stubbed out in the function class, but no coding is required, and it can be set as shown in the following code:
[C#]
public IGPMessages Validate(IArray paramvalues, bool updateValues,
    IGPEnvironmentManager envMgr)
{
    return null;
}
[VB.NET]
Public Function Validate(ByVal paramvalues As IArray, ByVal updateValues As Boolean, ByVal envMgr As IGPEnvironmentManager) As IGPMessages Implements IGPFunction2.Validate
    Return Nothing
End Function

Execute()

Internally, the geoprocessing framework calls the internal validate process before performing Execute(). If the validation passes, only then is Execute() called.
The arguments to the Execute() method include an array of parameter values, a GPMessages object, a TrackCancel object, and GPEnviromentManager. The GPMessages object is used for returned messages that indicate if the function failed. The TrackCancel object is used to allow the functions to cancel the operation and track its progress. The GPEnvironmentManager provides access to current environments and geoprocessing settings.
Execute() has the following roles:
  • Opens datasets and verifies all inputs are valid—Opening the input datasets means creating objects from the inputs. For example, if the input value is a path to a feature class, create an IFeatureClass object. This ensures that this data still exists and is not locked by another application. The same is true for other inputs, such as Fields.
  • Checks if the Overwrite Output setting is true or false—If your tool creates new output data, you must check if the OverwriteOutput setting is true of false. If the setting is true, then it is necessary to delete the existing output before performing the operation. The following code example shows how to check for the OverwriteOutput setting:
[C#]
// Check the overwrite output option.
IGeoProcessorSettings gpSettings=(IGeoProcessorSettings)envMgr;
if (gpSettings.OverwriteOutput == true)
{
    // Check if the output exists.
    if (m_GPUtilities.Exists(outputValue))
    {
        m_GPUtilities.Delete(outputValue);
    }
}

else
{
    if (m_GPUtilities.Exists(outputValue))
    {
        message.AddError(2, "Output already exists: " + outputValue.GetAsText());
    }
}
[VB.NET]
' Check the overwrite output option.
Dim gpSettings As IGeoProcessorSettings=CType(envMgr, IGeoProcessorSettings)
If gpSettings.OverwriteOutput=True Then
    ' Check if the output exists.
    If m_GPUtilities.Exists(outputValue)=True Then
        m_GPUtilities.Delete(outputValue)
    End If
Else
    If m_GPUtilities.Exists(outputValue)=True Then
        message.AddError(2, "Output already exists: " + outputValue.GetAsText())
    End If
End If
  • Executes the function—Executes the code to perform the operation.

Objects

This section describes a number of geoprocessing objects.

GPEnvironmentManager

GPEnvironmentManager is the managing object for environments and settings used by the geoprocessing tools. GPEnvironmentManager is passed to each tool for use during UpdateParameters(), UpdateMessages(), and Execute(). The tool then has access to current environments and settings of the current application. The following code shows how to get the extent environment by name for a list of environment names:
[C#]
IGPEnvironment gpExtent=pEnvMgr.FindEnvironment("extent");
[VB.NET]
Dim gpExtent As IGPEnvironment=envMgr.FindEnvironment("extent")

GPMessages

The GPMessages object manages an array of GPMessage objects. This object contains methods to generate and replace message objects. The UpdateMessags() method is passed an existing GPMessages object and replaces or updates messages as needed. The Execute() method is passed an existing GPMessages object and adds new messages as needed.

GPMessage

The GPMessage object is composed of a message type, error code, and description. The message type can be an error, a warning, or informative.

GPUtilities

The GPUtilities object contains many useful helper methods for the function writer. For a complete list of helper methods, see IGPUtilities and IGPUtilites2. In the sample tool provided, many helper methods are used including the following:
  • UnPackGPValue()—Gets the value from the parameter and creates a GPValue object.
  • PackGPValue()—Places the GPValue object into the parameter.
  • Exists()—Returns whether or not the input value exists.
  • Delete()—Deletes the data.
  • Open()—Opens the data source associated with the value.
  • DecodeFeatureLayer—Returns the feature class and query filter specified by the given geoprocessing value object. This should be used when the input is a GPFeatureLayerType. This ensures you open the feature class and retrieve any existing query filter.
  • DecodeTableView—Returns the table and query filter specified by the given geoprocessing value object. This ensures you open the table and retrieve any existing query filter.

Implementing IGPFunctionFactory

Once the GPFunction tool is created, it must be made accessible. This is accomplished by creating a GPFunctionFactory. The factory is responsible for handing out the function name objects for each function. This factory is registered to the component category CATID_GPFunctionFactories. In most cases, a function factory is a logical grouping of tools. Thus, a single Dynamic Link Library (DLL) can contain one factory with multiple functions. The IGPFunctionFactory properties and methods are as follows:
  • CLSID property—The class ID of the factory.
  • Name property—Name of the function factory. This is used when generating the toolbox containing the factory function. This can be internationalized.
  • Alias property—Alias name of the factory. This is used when specifying the functions contained in the factory from the command line or scripting.
  • GetFunction() method—Creates and returns a function object based on the input name.
  • GetFunctionName() method—Creates and returns a function name object based on the input name.
  • GetFunctionNames() method—Creates and returns an enumeration of function names that the factory supports.
  • GetFunctionEnvironments() method (optional)—Creates and returns an enumeration of GPEnvironment objects. If tools published by this function factory require new environment settings, define additional environment settings here. This is similar to how parameters are defined.


See Also:

Samples:




Development licensing Deployment licensing
ArcGIS Desktop Basic ArcGIS Desktop Basic
ArcGIS Desktop Standard ArcGIS Desktop Standard
ArcGIS Desktop Advanced ArcGIS Desktop Advanced
Engine Developer Kit Engine