I'm having issues add a custom GP tool to my toolbox programmatically using c#. The tool gets added to my toolbox OK but then when I try to open it it fails adding a red cross to the tool and specifiying a message "Invalid Tool" - "Unable to execute selected tool". Can anyone help? See code below:
Factory class
#region Imports
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.esriSystem;
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
#endregion
namespace GPTools
{
[Guid("1a590719-bf03-4de6-ad17-ef1f70e676bb")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("GPTools.gpToolboxFactory")]
public class gpMonsToolboxFactory : ESRI.ArcGIS.Geoprocessing.IGPFunctionFactory
{
#region "IGPFunctionFactory Implementations"
public string Alias
{
get
{
return "Imports";
}
}
public ESRI.ArcGIS.esriSystem.UID CLSID
{
get
{
return default(ESRI.ArcGIS.esriSystem.UID);
}
}
public ESRI.ArcGIS.Geoprocessing.IGPFunction GetFunction(string Name)
{
IGPFunction gpFunction = null;
switch (Name)
{
case "gpImportFile":
gpFunction = new gpImportFile();
break;
}
return gpFunction;
}
public ESRI.ArcGIS.Geoprocessing.IEnumGPEnvironment GetFunctionEnvironments()
{
return null;
}
public ESRI.ArcGIS.Geodatabase.IGPName GetFunctionName(string Name)
{
IGPFunctionName gpFuncName = new GPFunctionNameClass();
gpFuncName.MinimumProduct = esriProductCode.esriProductCodeViewer;
IGPName gpName = gpFuncName as IGPName;
switch (Name)
{
case "gpImportFile":
gpName.Category = "Data\\Import\\Raster";
gpName.Description = "Import File";
gpName.DisplayName = "Raster ZXY";
gpName.Name = "gpImportFile";
break;
}
gpName.Factory = this as IGPFunctionFactory;
return gpName;
}
public ESRI.ArcGIS.Geodatabase.IEnumGPName GetFunctionNames()
{
IArray nameArr = new EnumGPNameClass();
nameArr.Add(GetFunctionName("gpImportFile"));
return (IEnumGPName)nameArr;
}
public string Name
{
get
{
return "Imports";
}
}
#endregion
}
}
IGPFunction:
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.esriSystem;
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace GPTools
{
[Guid("5f28c9a8-0998-4dc4-959c-5d32bb442910")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("GPTools.gpImportFile")]
public class gpMonsImportZMapGrid : ESRI.ArcGIS.Geoprocessing.IGPFunction2
{
#region Variables
private IGPUtilities2 _utils;
#endregion
#region Constructor
public gpImportFile()
{
_utils = new GPUtilitiesClass();
}
#endregion
#region "IGPFunction2 Implementations"
public ESRI.ArcGIS.esriSystem.UID DialogCLSID
{
get
{
return null;
}
}
public string DisplayName
{
get
{
return "Raster ZXY";
}
}
public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message)
{
// Input File Path
IGPParameter3 gpParam = (IGPParameter3)paramvalues.get_Element(0);
string inputFile = gpParam.Value.GetAsText();
// spatial reference
gpParam = (IGPParameter3)paramvalues.get_Element(1);
string spatRefPath = gpParam.Value.GetAsText();
ESRI.ArcGIS.Geometry.ISpatialReference3 spatRef = Maersk.Functions.SpatialReference.LoadSpatRefFromPrj(spatRefPath);
// output Grid
gpParam = (IGPParameter3)paramvalues.get_Element(2);
string outputGridFullPath = gpParam.Value.GetAsText();
string outputDir = System.IO.Path.GetDirectoryName(outputGridFullPath);
string outputGridName = System.IO.Path.GetFileName(outputGridFullPath);
// Rest of process code...
}
public ESRI.ArcGIS.esriSystem.IName FullName
{
get
{
IGPFunctionFactory funcFact = new gpToolboxFactory();
return (IName)funcFact.GetFunctionName(Name);
}
}
public object GetRenderer(ESRI.ArcGIS.Geoprocessing.IGPParameter pParam)
{
//TODO: specify renderer
return null;
}
public int HelpContext
{
get
{
return 0;
}
}
public string HelpFile
{
get
{
return "";
}
}
public bool IsLicensed()
{
// requires any version of ArcGIS
return true;
}
public string MetadataFile
{
get
{
return "";
}
}
public string Name
{
get
{
return "gpImportFile";
}
}
public ESRI.ArcGIS.esriSystem.IArray ParameterInfo
{
get
{
IArray paramsArr = new ArrayClass();
// input grid file
IGPParameterEdit3 param = new GPParameterClass();
param.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
param.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
param.DataType = new GPDataFileTypeClass();
param.DisplayName = "Input file";
param.Name = "inp_File";
paramsArr.Add(param);
// spatial reference
param = new GPParameterClass();
param.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
param.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
param.DisplayName = "Spatial Reference";
param.DataType = new GPSpatialReferenceTypeClass();
param.Name = "out_sr";
paramsArr.Add(param);
// etc...
return paramsArr;
}
}
string _inputFile = "";
string _outputGrid = "";
public void UpdateMessages(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr, ESRI.ArcGIS.Geodatabase.IGPMessages Messages)
{
}
public void UpdateParameters(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager pEnvMgr)
{
}
#endregion
public IGPMessages Validate(IArray paramvalues, bool updateValues, IGPEnvironmentManager envMgr)
{
return null;
}
}
}
Arctoolbox code:
// Load toolbox into ArcToolbox
IArcToolboxExtension arcTbxExt;
try
{
arcTbxExt = (IArcToolboxExtension)ArcMap.Application.FindExtensionByName("ESRI ArcToolbox");
if (arcTbxExt == null) { throw new Exception("ArcToolbox extension could not be found."); }
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Error finding ArcToolbox extension." + Environment.NewLine + " - " + ex.Message);
return;
}
// open main toolbox
IGPToolbox2 toolbox;
try
{
if (System.IO.File.Exists(_settings.MainClass.MainToolBoxPath) == false) { throw new Exception("Toolbox does not exist." + Environment.NewLine + _settings.MainClass.MainToolBoxPath); }
toolbox = Functions.Toolbox.OpenToolbox(_settings.MainClass.MainToolBoxPath);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Error launching toolbox." + Environment.NewLine + " - " + ex.Message);
return;
}
// Add toolbox
try
{
arcTbxExt.ArcToolbox.AddToolbox((IGPToolbox)toolbox);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Error adding toolbox." + Environment.NewLine + " - " + ex.Message);
return;
}
#region Add .NET tools to tool
//
try
{
IGPFunctionFactory gpFuncFact = new GPTools.gpMonsToolboxFactory();
IGPFunction gpFunction = gpFuncFact.GetFunction("gpImportFile");
IGPTool gpTool = toolbox.CreateTool(esriGPToolType.esriGPFunctionTool, "gpImportFile", "Raster ZXY", "Imports a Raster file", "Import", null);
IGPFunctionTool gpFuncTool = (IGPFunctionTool)gpTool;
gpFuncTool.Function = gpFunction;
gpTool.Store();
}
catch (Exception ex)
{
throw;
}
EDIT: Thanks again too Petr Krebs who spotted the issue. For those who need it here's the answer in the factory class (alter the CLSID method):
public ESRI.ArcGIS.esriSystem.UID CLSID
{
get
{
ESRI.ArcGIS.esriSystem.UID uid = new ESRI.ArcGIS.esriSystem.UID();
// change uid here from the GUID specified at the class header
uid.Value = "{1a590719-bf03-4de6-ad17-ef1f70e676bb}";
return uid;
}
}