Run a geoprocessing task and python script

This tutorial demonstrates how to build an add-in that runs a geoprocessing tool with input parameters. You will then use a Python script to process the output of your new add-in.

With ArcGIS Pro SDK for .NET, you can extend ArcGIS Pro with your own unique tools and workflows. Using Microsoft Visual Studio and the Pro SDK, developers can build Pro add-ins and solution configurations that provide users with custom functionality specific to their organization or industry. The Pro SDK provides the ability to execute geoprocessing tools as add-ins, with the option to return the output of geoprocessing tasks.

In this tutorial, you will create two buttons for a new add-in group. The first button will execute the Buffer_analysis geoprocessing tool and buffer a selected feature. The second button runs a Python script and buffer a set of points to create multiple feature classes.

Prerequisites

Steps

Create a new ArcGIS Pro Add-In solution

  1. Start Visual Studio.

  2. Choose File > New > Project and then from the ArcGIS templates group, select ArcGIS Pro Module Add-in. Name the add-in project "RunGPTool". Click OK to proceed.

    By default, the Config.daml file opens in Visual Studio. The Module1.cs file contains add-in module code.

    Note also in the Config.daml file that the id attribute of the insertModule tag matches the ID within the Module1.cs file and the className attribute also matches the class name of the module.

    To find the ArcGIS templates group, see Templates > Visual C# > ArcGIS. Also confirm that the latest .NET Framework is selected.

Add a button control to your add-in

  1. From the Solution Explorer, right-click the project and choose Add > New Item. From the ArcGIS Pro Add-ins group select ArcGIS Pro Button.

  2. Name the new class file RunGP.cs and click Add to close the dialog box. The button template provides the contents of the class file as well as the corresponding code in the Config.daml file for ArcGIS Pro UI.

  3. Update the OnClick method of RunGP.cs so that it is async:

     
    1
    protected override async void OnClick()
  4. Add the following code to the OnClick method of RunGP.cs:

                                                  
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
                await QueuedTask.Run(async () =>
                {
                    // Check for an active mapview, if not, then prompt and exit.
                    if (MapView.Active == null)
                    {
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("No MapView currently active. Exiting...", "Info");
                        return;
                    }
                    // Get the layer(s) selected in the Contents pane, if there is not just one, then prompt then exit.
                    if (MapView.Active.GetSelectedLayers().Count != 1)
                    {
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("One feature layer must be selected in the Contents pane. Exiting...", "Info");
                        return;
                    }
                    // Check to see if the selected layer is a feature layer, if not, then prompt and exit.
                    var featLayer = MapView.Active.GetSelectedLayers().First() as FeatureLayer;
                    if (featLayer == null)
                    {
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("A feature layer must be selected in the Contents pane. Exiting...", "Info");
                        return;
                    }
    
                    try
                    {
                        // Get the path to the layer's feature class and path to a new 200-foot buffer feature class
                        string FLPath = featLayer.GetFeatureClass().GetDatastore().GetPath().AbsolutePath;
                        var FLPathCombine = System.IO.Path.GetFullPath(FLPath);
                        string infc = System.IO.Path.Combine(FLPathCombine, featLayer.Name);
                        string outfc = System.IO.Path.Combine(FLPathCombine, "Buffer_" + featLayer.Name);
                        // Place parameters into an array
                        var parameters = Geoprocessing.MakeValueArray(infc, outfc, "200 Feet");
                        // Place environment settings in an array, in this case, OK to over-write
                        var environments = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
                        // Execute the GP tool with parameters
                        var gpResult = await Geoprocessing.ExecuteToolAsync("Buffer_analysis", parameters, environments);
                        // Show a messagebox with the results
                        Geoprocessing.ShowMessageBox(gpResult.Messages, "GP Messages", gpResult.IsFailed ? GPMessageBoxStyle.Error : GPMessageBoxStyle.Default);
    
                    }
                    catch (Exception exc)
                    {
                        // Catch any exception found and display in a message box
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Exception caught while trying to run GP tool: " + exc.Message);
                        return;
                    }
                });
    

Add a second button control to your add-in

  1. From the Solution Explorer, right-click the project and choose Add > New Item. From the ArcGIS Pro Add-ins group select ArcGIS Pro Button.

  2. Name the class "RunPython.cs" and then click Add to close the dialog box. This button template provides the contents of the class file as well as corresponding code in the Config.daml file for ArcGIS Pro UI.

  3. Add the following code to the OnClick method in RunPython.cs:

                                                 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
                QueuedTask.Run(() =>
                {
                    try
                    {
                        // Inform user that add-in is about to call Python script.
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Click OK to start script, and wait for completion messagebox.", "Info");
                        // Create and format path to Pro
                        var pathProExe = System.IO.Path.GetDirectoryName((new System.Uri(Assembly.GetEntryAssembly().CodeBase)).AbsolutePath);
                        if (pathProExe == null) return;
                        pathProExe = Uri.UnescapeDataString(pathProExe);
                        pathProExe = System.IO.Path.Combine(pathProExe, @"Python\envs\arcgispro-py3");
                        // Create and format path to Python
                        var pathPython = System.IO.Path.GetDirectoryName((new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath);
                        if (pathPython == null) return;
                        pathPython = Uri.UnescapeDataString(pathPython);
                        // Create and format process command string.
                        // NOTE:  Path to Python script is below, "C:\temp\RunPython.py", which can be kept or updated based on the location you place it.
                        var myCommand = string.Format(@"/c """"{0}"" ""{1}""""",
                            System.IO.Path.Combine(pathProExe, "python.exe"),
                            System.IO.Path.Combine(pathPython, @"C:\temp\RunPython.py"));
                        // Create process start info, with instruction settings
                        var procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", myCommand);
                        procStartInfo.RedirectStandardOutput = true;
                        procStartInfo.RedirectStandardError = true;
                        procStartInfo.UseShellExecute = false;
                        procStartInfo.CreateNoWindow = true;
                        // Create process and start it
                        System.Diagnostics.Process proc = new System.Diagnostics.Process();
                        proc.StartInfo = procStartInfo;
                        proc.Start();
                        // Create and format result string
                        string result = proc.StandardOutput.ReadToEnd();
                        string error = proc.StandardError.ReadToEnd();
                        if (!string.IsNullOrEmpty(error)) result += string.Format("{0} Error: {1}", result, error);
                        // Show result string
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(result, "Info");
                    }
    
                    catch (Exception exc)
                    {
                        // Catch any exception found and display in a message box
                        ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Exception caught while trying to run Python tool: " + exc.Message);
                        return;
                    }
                });
    

Update the Config.daml file

  1. Update the Config.daml file AddInInfo section so that the DAML appears as follows:

                       
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    </AddInInfo>
    <modules>
        <insertModule id="RunGPTool_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <group id="RunGPTool_Group1" caption="Run GP and Python" appearsOnAddInTab="true">
            <button refID="RunGPTool_RunGP" size="large" />
            <button refID="RunGPTool_RunPython" size="large" />
            </group>
        </groups>
        <controls>
            <button id="RunGPTool_RunGP" caption="Run GP Tool" className="RunGP" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlue16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlue32.png">
            <tooltip heading="Run a GP Tool">Runs the Buffer GP Tool on the selected feature layer.<disabledText /></tooltip>
            </button>
            <button id="RunGPTool_RunPython" caption="Run Python Script" className="RunPython" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlue16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlue32.png">
            <tooltip heading="Run a Python Script">Run a Python script to buffer features in the FeatureTest sample dataset.<disabledText /></tooltip>
            </button>
        </controls>
        </insertModule>
    </modules>

The above updates the captions and tooltips for each of the buttons, and the control group, which will appear on the Add-In tab.

Create a Python script file

The RunPython.cs OnClick method you created will run a Python script which you will now create.

  1. Create a new text file named RunPython.py in the folder C:\temp on your machine. Place the following code in this script file and save.
                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import arcpy
arcpy.env.overwriteOutput = True

# Note: Script assumes data from Pro SDK community samples are installed under C:\Data, as follows:
inFC = "C:\Data\FeatureTest\FeatureTest.gdb\TestPoints"
outFCBuffer300 = "C:\Data\FeatureTest\FeatureTest.gdb\TestPoints_Buffer_300ft"
outFCBuffer400 = "C:\Data\FeatureTest\FeatureTest.gdb\TestPoints_Buffer_400ft"
outFCBuffer500 = "C:\Data\FeatureTest\FeatureTest.gdb\TestPoints_Buffer_500ft"

# Buffer the input features creating three buffer distance feature classes
arcpy.Buffer_analysis(inFC, outFCBuffer300, "300 feet")
arcpy.Buffer_analysis(inFC, outFCBuffer400, "400 feet")
arcpy.Buffer_analysis(inFC, outFCBuffer500, "500 feet")

# The following message will be included in the message box from the calling button's OnClick routine
print("Buffer routine from Python script complete. \r\n View and add 300-, 400- and 500-foot buffer feature classes from the Catalog pane.")

Test your add-in

  1. Build your project and debug any issues. Start your Visual Studio project which will launch ArcGIS Pro. Open the FeatureTest.aprx project from C:\Data\FeatureTest\ (see Prerequisites). Once the project opens, click the Add-In tab and locate your new control group with your two new buttons.

  2. To test the Run GP Tool button, select the TestPoints feature layer from the project. Click on the Run GP Tool button, and wait for the GP message box to open with results.

  3. Press the Run Python Script button to test it. When the process is completed, confirm that the new buffer feature classes were created in the file geodatabase. You can view and add these to your project using the Catalog pane. You might need to refresh the view of the file geodatabase to see the new feature classes.

What's Next?

Learn how to use additional ArcGIS Pro for .NET SDK features in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.