Select to view content in your preferred language

Create a Custom Add-In Button that link to Tools in Toolbox

3654
6
Jump to solution
06-23-2022 01:10 PM
ManalSiddiqui
Emerging Contributor

So I am currently trying to link to create an Add-In and link it to the tool located in the toolbox. So the add-in button would work like a shortcut in a way instead of trying to dig out the tools from the geoprocessing pane.

 

I am aware of creating a customized ribbon which links to the tools (see video below) however this would only be specific to one project. I need to make the add-ins more versatile, so they can be used in any project whereas this ribbon would be specific to just one project. 

I would like to make the buttons to look exactly like this but within the Add-In ribbon. I have looked at resources where they execute the tool with commands similar to the one in this website. The main execution is done by :

Geoprocessing.ExecuteToolAsync(ToolPath, Parameters, Environments);

Where the toolpath is linked to the tool I am trying to open in the geoprocessing pane, however it does not work as there is something going wrong with the path (what I suspect). When I try to run that code, it seems to be giving me an error similar to the last post in this forum.

There should be some way to link the add-in to the feature but I am not sure where it is going wrong. Any help would be great!

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
CharlesMacleod
Esri Regular Contributor

For System toolbox tools, either specifying the full path to the Toolbox or using the convention "ToolboxName.ToolName" are equivalent.

so, for example, these are both equivalent:

var path = @"C:\<ArcGIS Pro Install Path>\Resources\ArcToolBox\Toolboxes\Analysis Tools.tbx";
var long_tool_name = System.IO.Path.Combine(path, "Buffer");

var short_tool_name = "analysis.Buffer";

With a custom tool, as it is _not_ a System toolbox tool, then u will always default to the fully qualified path to the toolbox - i.e. what I show as "long_tool_name" above (only the path to the toolbox will be whatever is the relevant full path to your custom toolbox in question).

Geoprocessing.OpenToolDialog(...) can then be invoked with the relevant toolbox name and parameters - the parameters will be used to prepopulate the corresponding fields on the tool dialog.

One last point, it is always best to call Geoprocessing.OpenToolDialog(...) on the UI thread and _not_ on the QueuedTask. If the Geoprocessing Dockpane has not been opened at least once before during the current session then Geoprocessing.OpenToolDialog(...) must create the dockpane before showing the tool page (hosted in the GP dockpane).

If Geoprocessing.OpenToolDialog(...) is called on the QueuedTask then creation of the GP dockpane fails (if the GP dialog has not been created for the session) and nothing will be shown.  

internal class ShowGPDialogButton : Button {

  protected async override void OnClick()
  {
    var map = MapView.Active.Map;

    var extent = MapView.Active.Extent;
    var path = @"C:\ArcGIS\Resources\ArcToolBox\Toolboxes\Analysis Tools.tbx";
    //these are equivalent for a System tool
    var long_tool_name = System.IO.Path.Combine(path, "Buffer");
    var short_tool_name = "analysis.Buffer";

    var tool_name = long_tool_name;//or can use short_tool_name for System tools

    var val_array = await QueuedTask.Run(() => {
      //make a geometry for the buffer
      var center_pt = MapPointBuilderEx.CreateMapPoint(
                               MapView.Active.Camera.X, 
                               MapView.Active.Camera.Y,
                               MapView.Active.Camera.SpatialReference);

      var geom = new List<object>() { center_pt };
      //set up some params for Buffer
      return Geoprocessing.MakeValueArray(new object[] { geom, null, @"1000 Meters" });
    });
    //Show the tool page - call OpenToolDialog on the UI
    Geoprocessing.OpenToolDialog(tool_name, val_array, null, false);
  }
}

 

 

 

 

View solution in original post

6 Replies
CharlesMacleod
Esri Regular Contributor

For System toolbox tools, either specifying the full path to the Toolbox or using the convention "ToolboxName.ToolName" are equivalent.

so, for example, these are both equivalent:

var path = @"C:\<ArcGIS Pro Install Path>\Resources\ArcToolBox\Toolboxes\Analysis Tools.tbx";
var long_tool_name = System.IO.Path.Combine(path, "Buffer");

var short_tool_name = "analysis.Buffer";

With a custom tool, as it is _not_ a System toolbox tool, then u will always default to the fully qualified path to the toolbox - i.e. what I show as "long_tool_name" above (only the path to the toolbox will be whatever is the relevant full path to your custom toolbox in question).

Geoprocessing.OpenToolDialog(...) can then be invoked with the relevant toolbox name and parameters - the parameters will be used to prepopulate the corresponding fields on the tool dialog.

One last point, it is always best to call Geoprocessing.OpenToolDialog(...) on the UI thread and _not_ on the QueuedTask. If the Geoprocessing Dockpane has not been opened at least once before during the current session then Geoprocessing.OpenToolDialog(...) must create the dockpane before showing the tool page (hosted in the GP dockpane).

If Geoprocessing.OpenToolDialog(...) is called on the QueuedTask then creation of the GP dockpane fails (if the GP dialog has not been created for the session) and nothing will be shown.  

internal class ShowGPDialogButton : Button {

  protected async override void OnClick()
  {
    var map = MapView.Active.Map;

    var extent = MapView.Active.Extent;
    var path = @"C:\ArcGIS\Resources\ArcToolBox\Toolboxes\Analysis Tools.tbx";
    //these are equivalent for a System tool
    var long_tool_name = System.IO.Path.Combine(path, "Buffer");
    var short_tool_name = "analysis.Buffer";

    var tool_name = long_tool_name;//or can use short_tool_name for System tools

    var val_array = await QueuedTask.Run(() => {
      //make a geometry for the buffer
      var center_pt = MapPointBuilderEx.CreateMapPoint(
                               MapView.Active.Camera.X, 
                               MapView.Active.Camera.Y,
                               MapView.Active.Camera.SpatialReference);

      var geom = new List<object>() { center_pt };
      //set up some params for Buffer
      return Geoprocessing.MakeValueArray(new object[] { geom, null, @"1000 Meters" });
    });
    //Show the tool page - call OpenToolDialog on the UI
    Geoprocessing.OpenToolDialog(tool_name, val_array, null, false);
  }
}

 

 

 

 

ManalSiddiqui
Emerging Contributor

Similar to the error I was getting before, it is unable to find the tool. 

ManalSiddiqui_0-1656093663085.png

 

This custom tool is a script so would that change anything as it does not really act as a "Buffer"? Also another thing is that the path to the tool within the toolbox is as it shows in ArcGIS but I am thinking something is going wrong with the path. 

Thanks for the response!

 

0 Kudos
CharlesMacleod
Esri Regular Contributor

 

 

Having a path separator in your toolname does not seem correct- "\Archive Imagery\ArchiveImagerySearch"?

Here is a Pro SDK sample: https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Geoprocessing/DeepThought 

It contains a python toolbox: "DeepThought.tbx". It has a tool "answer.py" with a toolname "Answer"

script-toolbox.pngscript-toolbox2.png

and so:

 

internal class ShowGPDialogButton : Button {
  protected override void OnClick()
  {
    var tool_path =
     @"E:\Data\SDK\Migration\DeepThought-ProAddin\Toolboxes\toolboxes\DeepThought.tbx";
    var tool_name = System.IO.Path.Combine(tool_path, "Answer");
    //map just so happens to be of Portland
    var wkid = MapView.Active.Map.SpatialReference.Wkid;
    var env_array = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: $"{wkid}");
    Geoprocessing.OpenToolDialog(tool_name, null, env_array);
 }
}

 

results in:

gp_tool.pngmap_sr.png

 

 

0 Kudos
ManalSiddiqui
Emerging Contributor


So as I suspected, the subfolder was the problem. I am only able to launch the tool if it is directly in the toolbox, however being in a subfolder within the toolbox makes it crash. Would you know the cause of this?

Screen Shot 2022-06-28 at 10.38.06 AM.png

Kristofer-Sentry
New Contributor

I am having the same issue. Calling OpenToolDialog with a path to a script within a toolset results in the same error as @ManalSiddiqui : "Tool has failed to open: Error HRESULT E_FAIL has been returned from a call to a COM component.". Moving the script to the top level of the toolbox fixes the issue, but that is a impractical solution for a toolbox that is neatly organized with dozens of tools.

0 Kudos
LuckyLuke84698
Emerging Contributor

I am trying to create an Add-in and link it to a system tool, as shown in your video. Can you please provide guidance on how to code it correctly? I am experiencing some issues with the implementation.

Tags (1)
0 Kudos