ArcGIS Pro 3.4 API Reference Guide
ArcGIS.Desktop.Core.Geoprocessing Namespace / Geoprocessing Class / ExecuteToolAsync Method / ExecuteToolAsync(String,IEnumerable<String>,IEnumerable<KeyValuePair<String,String>>,Nullable<CancellationToken>,GPToolExecuteEventHandler,GPExecuteToolFlags) Method
Use toolboxalias.toolname or toolname_toolboxalias for system tools, a path to a custom tool in a toolbox like @"C:\CustomTools\Toolbox.atbx\MyTool", or a relative path to a tool in a project toolbox like @"ProjectToolbox.atbx\MyTool"
Array of parameter values. Use MakeValueArray to pack all parameter values first.
Array of environment settings - each setting is a key-value pair of environment name and its value). Use MakeEnvironmentArray first to pack all environments.
A CancellationToken object.
Execute event delegateGPToolExecuteEventHandler(optional)
flags = GPExecuteToolFlags.Default (AddOutputsToMap | RefreshProjectItems) GPExecuteToolFlags
Example

In This Topic
    ExecuteToolAsync(String,IEnumerable<String>,IEnumerable<KeyValuePair<String,String>>,Nullable<CancellationToken>,GPToolExecuteEventHandler,GPExecuteToolFlags) Method
    In This Topic
    Executes a geoprocessing tool.
    Syntax

    Parameters

    toolPath
    Use toolboxalias.toolname or toolname_toolboxalias for system tools, a path to a custom tool in a toolbox like @"C:\CustomTools\Toolbox.atbx\MyTool", or a relative path to a tool in a project toolbox like @"ProjectToolbox.atbx\MyTool"
    values
    Array of parameter values. Use MakeValueArray to pack all parameter values first.
    environments
    Array of environment settings - each setting is a key-value pair of environment name and its value). Use MakeEnvironmentArray first to pack all environments.
    cancelToken
    A CancellationToken object.
    callback
    Execute event delegateGPToolExecuteEventHandler(optional)
    flags
    flags = GPExecuteToolFlags.Default (AddOutputsToMap | RefreshProjectItems) GPExecuteToolFlags

    Return Value

    A Task of type IGPResult. See IGPResult for more information.
    Remarks
    This method is used to execute a geoprocessing tool. Additionally, you can also use the optional parameters to handle geoprocessing events.
    Example
    FieldMappings
    var environment = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
    
    var prj = Project.Current;
    var map = MapView.Active;
    
    var defaultGDB = Project.Current.DefaultGeodatabasePath;
    
    var featLayers = map.Map.Layers.OfType<FeatureLayer>();
    
    var targetLayer = featLayers.ElementAt(0);  // First layer in TOC
    var joinLayer = featLayers.ElementAt(1);    // Second layer in TOC
    
    var outputFeatureClass = @"C:/temp/outputFC3.shp";
    
    // Specify the field map in Spatial Join with target and join feature class/layers in the App
    // Run Spatial Join manually - then Copy the fieldmap string from the result in Geoprocessing history and paste it for the fieldmap parameter. 
    // in this example of fieldmap, FireStations is the name of join layer
    // FireStations layer has two numeric fileds (used in Fieldmap): TYPE and NUMBER - these two fields are used in the FiedlMap
    //
    var joinLayerName = joinLayer.Name;
    var fieldMap = "TYPE 'TYPE' true true false 4 Long 0 0,Count,#,{joinLayerName},TYPE,-1,-1;NUMBER 'NUMBER' true true false 4 Long 0 0,Max,#,{joinLayerName},NUMBER,-1,-1";
    
    var toolParameters = Geoprocessing.MakeValueArray(targetLayer, joinLayer, outputFeatureClass, "JOIN_ONE_TO_ONE", "KEEP_COMMON", fieldMap, "INTERSECT");
    
    GPExecuteToolFlags executeFlags = GPExecuteToolFlags.AddOutputsToMap | GPExecuteToolFlags.GPThread | GPExecuteToolFlags.AddToHistory | GPExecuteToolFlags.RefreshProjectItems;
    
    IGPResult gpResult = await Geoprocessing.ExecuteToolAsync("analysis.SpatialJoin", toolParameters, environment, null, null, executeFlags);
    
    Geoprocessing.ShowMessageBox(gpResult.Messages, "GP Messages", gpResult.IsFailed ? GPMessageBoxStyle.Error : GPMessageBoxStyle.Default);
    FieldMappings
    var environment = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
    
    var prj = Project.Current;
    var map = MapView.Active;
    
    var defaultGDB = Project.Current.DefaultGeodatabasePath;
    
    var featLayers = map.Map.Layers.OfType<FeatureLayer>();
    
    var targetLayer = featLayers.ElementAt(0);  // First layer in TOC
    var joinLayer = featLayers.ElementAt(1);    // Second layer in TOC
    
    var outputFeatureClass = @"C:/temp/outputFC3.shp";
    
    // Specify the field map in Spatial Join with target and join feature class/layers in the App
    // Run Spatial Join manually - then Copy the fieldmap string from the result in Geoprocessing history and paste it for the fieldmap parameter. 
    // in this example of fieldmap, FireStations is the name of join layer
    // FireStations layer has two numeric fileds (used in Fieldmap): TYPE and NUMBER - these two fields are used in the FiedlMap
    //
    var joinLayerName = joinLayer.Name;
    var fieldMap = "TYPE 'TYPE' true true false 4 Long 0 0,Count,#,{joinLayerName},TYPE,-1,-1;NUMBER 'NUMBER' true true false 4 Long 0 0,Max,#,{joinLayerName},NUMBER,-1,-1";
    
    var toolParameters = Geoprocessing.MakeValueArray(targetLayer, joinLayer, outputFeatureClass, "JOIN_ONE_TO_ONE", "KEEP_COMMON", fieldMap, "INTERSECT");
    
    GPExecuteToolFlags executeFlags = GPExecuteToolFlags.AddOutputsToMap | GPExecuteToolFlags.GPThread | GPExecuteToolFlags.AddToHistory | GPExecuteToolFlags.RefreshProjectItems;
    
    IGPResult gpResult = await Geoprocessing.ExecuteToolAsync("analysis.SpatialJoin", toolParameters, environment, null, null, executeFlags);
    
    Geoprocessing.ShowMessageBox(gpResult.Messages, "GP Messages", gpResult.IsFailed ? GPMessageBoxStyle.Error : GPMessageBoxStyle.Default);
    Setting environments, MakeEnvironmentArray
    // get the syntax of the tool from Python window or from tool help page
    string in_features = @"C:\data\data.gdb\HighwaysWeb84";
    string out_features = @"C:\data\data.gdb\HighwaysUTM";
    var param_values = Geoprocessing.MakeValueArray(in_features, out_features);
    
    // crate the spatial reference object to pass as an argument to management.CopyFeatures tool
    var sp_ref = await QueuedTask.Run(() =>
    {
      return SpatialReferenceBuilder.CreateSpatialReference(26911);    // UTM 83 11N: 26911
    });
    
    // set output coordinate system environment           
    var environments = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: sp_ref);
    // set environments in the 3rd parameter
    var gp_result = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", param_values, environments, null, null, GPExecuteToolFlags.AddOutputsToMap);
    
    Geoprocessing.ShowMessageBox(gp_result.Messages, "Contents", GPMessageBoxStyle.Default, "Window Title");
    
    //return gp_result;
    
    Setting environments, MakeEnvironmentArray
    // get the syntax of the tool from Python window or from tool help page
    string in_features = @"C:\data\data.gdb\HighwaysWeb84";
    string out_features = @"C:\data\data.gdb\HighwaysUTM";
    var param_values = Geoprocessing.MakeValueArray(in_features, out_features);
    
    // crate the spatial reference object to pass as an argument to management.CopyFeatures tool
    var sp_ref = await QueuedTask.Run(() =>
    {
      return SpatialReferenceBuilder.CreateSpatialReference(26911);    // UTM 83 11N: 26911
    });
    
    // set output coordinate system environment           
    var environments = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: sp_ref);
    // set environments in the 3rd parameter
    var gp_result = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", param_values, environments, null, null, GPExecuteToolFlags.AddOutputsToMap);
    
    Geoprocessing.ShowMessageBox(gp_result.Messages, "Contents", GPMessageBoxStyle.Default, "Window Title");
    
    //return gp_result;
    
    Running Geoprocessing Tool with ProgressDialog
    var progDlg = new ProgressDialog("Running Geoprocessing Tool", "Cancel", 100, true);
    progDlg.Show();
    
    var progSrc = new CancelableProgressorSource(progDlg);
    
    // prepare input parameter values to CopyFeatures tool
    string input_data = @"C:\data\california.gdb\ca_highways";
    string out_workspace = ArcGIS.Desktop.Core.Project.Current.DefaultGeodatabasePath;
    string out_data = System.IO.Path.Combine(out_workspace, "ca_highways2");
    
    // make a value array of strings to be passed to ExecuteToolAsync
    var parameters = Geoprocessing.MakeValueArray(input_data, out_data);
    
    // execute the tool
    await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", parameters,
        null, new CancelableProgressorSource(progDlg).Progressor, GPExecuteToolFlags.Default);
    
    // dialog hides itself once the execution is complete
    progDlg.Hide();
    
    Running Geoprocessing Tool with ProgressDialog
    var progDlg = new ProgressDialog("Running Geoprocessing Tool", "Cancel", 100, true);
    progDlg.Show();
    
    var progSrc = new CancelableProgressorSource(progDlg);
    
    // prepare input parameter values to CopyFeatures tool
    string input_data = @"C:\data\california.gdb\ca_highways";
    string out_workspace = ArcGIS.Desktop.Core.Project.Current.DefaultGeodatabasePath;
    string out_data = System.IO.Path.Combine(out_workspace, "ca_highways2");
    
    // make a value array of strings to be passed to ExecuteToolAsync
    var parameters = Geoprocessing.MakeValueArray(input_data, out_data);
    
    // execute the tool
    await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", parameters,
        null, new CancelableProgressorSource(progDlg).Progressor, GPExecuteToolFlags.Default);
    
    // dialog hides itself once the execution is complete
    progDlg.Hide();
    
    GPTool Execute Event Handler
    System.Threading.CancellationTokenSource _cts;
    
    string ozone_points = @"C:\data\ca_ozone.gdb\O3_Sep06_3pm";
    
    string[] args = { ozone_points, "OZONE", "", "in_memory\\raster", "300",
                              "EMPIRICAL", "300", "5", "5000",
                              "NBRTYPE=StandardCircular RADIUS=310833.272442914 ANGLE=0 NBR_MAX=10 SECTOR_TYPE=ONE_SECTOR",
                              "PREDICTION", "0.5", "EXCEED", "", "K_BESSEL" };
    
    string tool_path = "ga.EmpiricalBayesianKriging";
    
    _cts = new System.Threading.CancellationTokenSource();
    
    var result = await Geoprocessing.ExecuteToolAsync(tool_path, args, null, _cts.Token,
        (event_name, o) =>  // implement delegate and handle events
        {
          switch (event_name)
          {
            case "OnValidate": // stop execute if any warnings
              if ((o as IGPMessage[]).Any(it => it.Type == GPMessageType.Warning))
                _cts.Cancel();
              break;
    
            case "OnProgressMessage":
              string msg = string.Format("{0}: {1}", new object[] { event_name, (string)o });
              System.Windows.MessageBox.Show(msg);
              _cts.Cancel();
              break;
    
            case "OnProgressPos":
              string msg2 = string.Format("{0}: {1} %", new object[] { event_name, (int)o });
              System.Windows.MessageBox.Show(msg2);
              _cts.Cancel();
              break;
          }
        });
    
    var ret = result;
    _cts = null;
    
    Geoprocessing specialized MessageBox
    var gp_result = await Geoprocessing.ExecuteToolAsync("management.GetCount", Geoprocessing.MakeValueArray(@"C:\data\f.gdb\hello"));
    // this icon shows up left of content_header
    string icon_src = @"C:\data\Icons\ModifyLink32.png";
    Geoprocessing.ShowMessageBox(gp_result.Messages, "Content Header", GPMessageBoxStyle.Error, "Window Title", icon_src);
    Geoprocessing specialized MessageBox
    var gp_result = await Geoprocessing.ExecuteToolAsync("management.GetCount", Geoprocessing.MakeValueArray(@"C:\data\f.gdb\hello"));
    // this icon shows up left of content_header
    string icon_src = @"C:\data\Icons\ModifyLink32.png";
    Geoprocessing.ShowMessageBox(gp_result.Messages, "Content Header", GPMessageBoxStyle.Error, "Window Title", icon_src);
    How to execute a Model tool
    // get the model tool's parameter syntax from the model's help
    string input_roads = @"C:\data\Input.gdb\PlanA_Roads";
    string buff_dist_field = "Distance";   // use values from a field
    string input_vegetation = @"C:\data\Input.gdb\vegetation";
    string output_data = @"C:\data\Output.gdb\ClippedFC2";
    
    // the model name is ExtractVegetation
    string tool_path = @"C:\data\MB\Models.tbx\ExtractVegetation";
    
    var args = Geoprocessing.MakeValueArray(input_roads, buff_dist_field, input_vegetation, output_data);
    
    var result = await Geoprocessing.ExecuteToolAsync(tool_path, args);
    How to execute a Model tool
    // get the model tool's parameter syntax from the model's help
    string input_roads = @"C:\data\Input.gdb\PlanA_Roads";
    string buff_dist_field = "Distance";   // use values from a field
    string input_vegetation = @"C:\data\Input.gdb\vegetation";
    string output_data = @"C:\data\Output.gdb\ClippedFC2";
    
    // the model name is ExtractVegetation
    string tool_path = @"C:\data\MB\Models.tbx\ExtractVegetation";
    
    var args = Geoprocessing.MakeValueArray(input_roads, buff_dist_field, input_vegetation, output_data);
    
    var result = await Geoprocessing.ExecuteToolAsync(tool_path, args);
    Set Geoprocessing extent environment
    var parameters = Geoprocessing.MakeValueArray(@"C:\data\data.gdb\HighwaysUTM11", @"C:\data\data.gdb\Highways_extent");
    var ext = Geoprocessing.MakeEnvironmentArray(extent: "460532 3773964 525111 3827494");
    var gp_result = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", parameters, ext);
    Set Geoprocessing extent environment
    var parameters = Geoprocessing.MakeValueArray(@"C:\data\data.gdb\HighwaysUTM11", @"C:\data\data.gdb\Highways_extent");
    var ext = Geoprocessing.MakeEnvironmentArray(extent: "460532 3773964 525111 3827494");
    var gp_result = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", parameters, ext);
    Stop a feature class created with GP from automatically adding to the map
    // However, settings in Pro App's Geoprocessing Options will override option set in code
    // for example, in Pro App's Options > Geoprocessing dialog, if you check 'Add output datasets to an open map'
    // then the output WILL BE added to history overriding settings in code
    var CopyfeaturesParams = Geoprocessing.MakeValueArray("C:\\data\\Input.gdb\\PlanA_Roads", "C:\\data\\Input.gdb\\Roads_copy");
    IGPResult gpResult = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", CopyfeaturesParams, null, null, null, GPExecuteToolFlags.None);
    Stop a feature class created with GP from automatically adding to the map
    // However, settings in Pro App's Geoprocessing Options will override option set in code
    // for example, in Pro App's Options > Geoprocessing dialog, if you check 'Add output datasets to an open map'
    // then the output WILL BE added to history overriding settings in code
    var CopyfeaturesParams = Geoprocessing.MakeValueArray("C:\\data\\Input.gdb\\PlanA_Roads", "C:\\data\\Input.gdb\\Roads_copy");
    IGPResult gpResult = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", CopyfeaturesParams, null, null, null, GPExecuteToolFlags.None);
    GPExecuteToolFlags.AddToHistory will add the execution messages to History
    // However, settings in Pro App's Geoprocessing Options will override option set in code
    // for example, if in Options > Geoprocessing dialog, if you uncheck 'Write geoprocessing operations to Geoprocessing History'
    // then the output will not be added to history.
    var args2 = Geoprocessing.MakeValueArray("C:\\data\\Vegetation.shp", "NewField", "TEXT");
    var result2 = await Geoprocessing.ExecuteToolAsync("management.AddField", args2, null, null, null, GPExecuteToolFlags.AddToHistory);
    GPExecuteToolFlags.AddToHistory will add the execution messages to History
    // However, settings in Pro App's Geoprocessing Options will override option set in code
    // for example, if in Options > Geoprocessing dialog, if you uncheck 'Write geoprocessing operations to Geoprocessing History'
    // then the output will not be added to history.
    var args2 = Geoprocessing.MakeValueArray("C:\\data\\Vegetation.shp", "NewField", "TEXT");
    var result2 = await Geoprocessing.ExecuteToolAsync("management.AddField", args2, null, null, null, GPExecuteToolFlags.AddToHistory);
    Multi Ring Buffer
    //The data referenced in this snippet can be downloaded from the arcgis-pro-sdk-community-samples repo
    //https://github.com/Esri/arcgis-pro-sdk-community-samples
    async Task<IGPResult> CreateRings(EditingTemplate currentTemplate)
    {
      var paramsArray = Geoprocessing.MakeValueArray(currentTemplate.MapMember.Name,
                  @"C:\Data\FeatureTest\FeatureTest.gdb\Points_MultipleRingBuffer",
                  new List<string> { "1000", "2000" }, "Meters", "Distance",
                  "ALL", "FULL");
    
      IGPResult ringsResult = await Geoprocessing.ExecuteToolAsync("Analysis.MultipleRingBuffer", paramsArray);
      var messages = string.IsNullOrEmpty(gpResult.ReturnValue)
              ? $@"Error in gp tool: {gpResult.ErrorMessages}"
              : $@"Ok: {gpResult.ReturnValue}";
    
      return ringsResult;
    }
    Multi Ring Buffer
    //The data referenced in this snippet can be downloaded from the arcgis-pro-sdk-community-samples repo
    //https://github.com/Esri/arcgis-pro-sdk-community-samples
    async Task<IGPResult> CreateRings(EditingTemplate currentTemplate)
    {
      var paramsArray = Geoprocessing.MakeValueArray(currentTemplate.MapMember.Name,
                  @"C:\Data\FeatureTest\FeatureTest.gdb\Points_MultipleRingBuffer",
                  new List<string> { "1000", "2000" }, "Meters", "Distance",
                  "ALL", "FULL");
    
      IGPResult ringsResult = await Geoprocessing.ExecuteToolAsync("Analysis.MultipleRingBuffer", paramsArray);
      var messages = string.IsNullOrEmpty(gpResult.ReturnValue)
              ? $@"Error in gp tool: {gpResult.ErrorMessages}"
              : $@"Ok: {gpResult.ReturnValue}";
    
      return ringsResult;
    }
    Non-blocking execution of a Geoprocessing tool
    //The data referenced in this snippet can be downloaded from the arcgis-pro-sdk-community-samples repo
    //https://github.com/Esri/arcgis-pro-sdk-community-samples
    string in_data = @"C:\tools\data.gdb\cities";
    string cities_buff = @"E:\data\data.gdb\cities_2km";
    
    var valueArray = Geoprocessing.MakeValueArray(in_data, cities_buff, "2000 Meters");
    
    // to let the GP tool run asynchronously without blocking the main thread
    // use the GPThread option of GPExecuteToolFlasgs
    //
    GPExecuteToolFlags flags = GPExecuteToolFlags.GPThread;  // instruct the tool run non-blocking GPThread
    IGPResult bufferResult = await Geoprocessing.ExecuteToolAsync("Analysis.Buffer", valueArray, null, null, null, flags);
    Non-blocking execution of a Geoprocessing tool
    //The data referenced in this snippet can be downloaded from the arcgis-pro-sdk-community-samples repo
    //https://github.com/Esri/arcgis-pro-sdk-community-samples
    string in_data = @"C:\tools\data.gdb\cities";
    string cities_buff = @"E:\data\data.gdb\cities_2km";
    
    var valueArray = Geoprocessing.MakeValueArray(in_data, cities_buff, "2000 Meters");
    
    // to let the GP tool run asynchronously without blocking the main thread
    // use the GPThread option of GPExecuteToolFlasgs
    //
    GPExecuteToolFlags flags = GPExecuteToolFlags.GPThread;  // instruct the tool run non-blocking GPThread
    IGPResult bufferResult = await Geoprocessing.ExecuteToolAsync("Analysis.Buffer", valueArray, null, null, null, flags);
    How to pass parameter with multiple or complex input values
    var environments = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
    
    string toolName = "Snap_edit";  // or use edit.Snap
    
    // Snap tool takes multiple inputs each of which has
    // Three (3) parts: a feature class or layer, a string value and a distance
    // Each part is separated by a semicolon - you can get example of sytax from the tool documentation page
    var snapEnv = @"'C:/SnapProject/fgdb.gdb/line_1' END '2 Meters';'C:/SnapProject/fgdb.gdb/points_1' VERTEX '1 Meters';'C:/SnapProject/fgdb.gdb/otherline_1' END '20 Meters'";
    
    var infc = @"C:/SnapProject/fgdb.gdb/poly_1";
    
    var snapParams = Geoprocessing.MakeValueArray(infc, snapEnv);
    
    GPExecuteToolFlags tokens = GPExecuteToolFlags.RefreshProjectItems | GPExecuteToolFlags.GPThread | GPExecuteToolFlags.AddToHistory;
    
    IGPResult snapResult = await Geoprocessing.ExecuteToolAsync(toolName, parameters, environments, null, null, tokens);
    
    //return gpResult;
    
    How to pass parameter with multiple or complex input values
    var environments = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
    
    string toolName = "Snap_edit";  // or use edit.Snap
    
    // Snap tool takes multiple inputs each of which has
    // Three (3) parts: a feature class or layer, a string value and a distance
    // Each part is separated by a semicolon - you can get example of sytax from the tool documentation page
    var snapEnv = @"'C:/SnapProject/fgdb.gdb/line_1' END '2 Meters';'C:/SnapProject/fgdb.gdb/points_1' VERTEX '1 Meters';'C:/SnapProject/fgdb.gdb/otherline_1' END '20 Meters'";
    
    var infc = @"C:/SnapProject/fgdb.gdb/poly_1";
    
    var snapParams = Geoprocessing.MakeValueArray(infc, snapEnv);
    
    GPExecuteToolFlags tokens = GPExecuteToolFlags.RefreshProjectItems | GPExecuteToolFlags.GPThread | GPExecuteToolFlags.AddToHistory;
    
    IGPResult snapResult = await Geoprocessing.ExecuteToolAsync(toolName, parameters, environments, null, null, tokens);
    
    //return gpResult;
    
    How to pass native objects as parameter values to run geoprocessing tool
    string tool2 = "analysis.Buffer";
    List<MapPoint> list = new List<MapPoint>();
    list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
    list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
    list.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
    list.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));
    
    Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(list);
    var spatial_ref = SpatialReferenceBuilder.CreateSpatialReference(3857);
    var args3 = await QueuedTask.Run(() =>
    {
      return Geoprocessing.MakeValueArray(multiPoint, "memory\\Buffers", "800 meters");
    });
    var env1 = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: spatial_ref);
    var messages = new List<string>(); // list to collect all output messages
    var cts = new CancellationTokenSource();
    await Geoprocessing.ExecuteToolAsync(tool2, args3, env1, cts.Token);
    
    How to pass native objects as parameter values to run geoprocessing tool
    string tool2 = "analysis.Buffer";
    List<MapPoint> list = new List<MapPoint>();
    list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
    list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
    list.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
    list.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));
    
    Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(list);
    var spatial_ref = SpatialReferenceBuilder.CreateSpatialReference(3857);
    var args3 = await QueuedTask.Run(() =>
    {
      return Geoprocessing.MakeValueArray(multiPoint, "memory\\Buffers", "800 meters");
    });
    var env1 = Geoprocessing.MakeEnvironmentArray(outputCoordinateSystem: spatial_ref);
    var messages = new List<string>(); // list to collect all output messages
    var cts = new CancellationTokenSource();
    await Geoprocessing.ExecuteToolAsync(tool2, args3, env1, cts.Token);
    
    How to access Geoprocessing History
    string openProjectPath = @"D\DATA\IGPHistoryItemTestProject\IGPHistoryItemTestProject.aprx";
    await Project.OpenAsync(openProjectPath);
    MapProjectItem mapProjItem = Project.Current.GetItems<MapProjectItem>().FirstOrDefault(item => item.Name.Equals("Map", StringComparison.CurrentCultureIgnoreCase));
    
    var map = await QueuedTask.Run(() => mapProjItem.GetMap());
    var ftrLayer = map.Layers[0] as FeatureLayer;
    string tool1 = "management.GetCount";
    var args1 = Geoprocessing.MakeValueArray(ftrLayer);
    var env = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
    GPExecuteToolFlags executeFlags = GPExecuteToolFlags.AddToHistory;
    var t = await Geoprocessing.ExecuteToolAsync(tool1, args1, env, null, null, executeFlags);
    
    IEnumerable<IGPHistoryItem> hisItems = Project.Current.GetProjectItemContainer(Geoprocessing.HistoryContainerKey) as IEnumerable<IGPHistoryItem>;
    
    String hitemID = "";
    String hitemToolPath = "";
    IGPResult hitemGPResult = null;
    DateTime hitemTimeStamp;
    
    foreach (var hitem in hisItems)
    {
      // common IGPHistoryItem and Item properties
      hitemID = (hitem as Item).ID;
      hitemToolPath = hitem.ToolPath;
      hitemGPResult = hitem.GPResult;
      hitemTimeStamp = hitem.TimeStamp;
    }
    
    
    How to access Geoprocessing History
    string openProjectPath = @"D\DATA\IGPHistoryItemTestProject\IGPHistoryItemTestProject.aprx";
    await Project.OpenAsync(openProjectPath);
    MapProjectItem mapProjItem = Project.Current.GetItems<MapProjectItem>().FirstOrDefault(item => item.Name.Equals("Map", StringComparison.CurrentCultureIgnoreCase));
    
    var map = await QueuedTask.Run(() => mapProjItem.GetMap());
    var ftrLayer = map.Layers[0] as FeatureLayer;
    string tool1 = "management.GetCount";
    var args1 = Geoprocessing.MakeValueArray(ftrLayer);
    var env = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true);
    GPExecuteToolFlags executeFlags = GPExecuteToolFlags.AddToHistory;
    var t = await Geoprocessing.ExecuteToolAsync(tool1, args1, env, null, null, executeFlags);
    
    IEnumerable<IGPHistoryItem> hisItems = Project.Current.GetProjectItemContainer(Geoprocessing.HistoryContainerKey) as IEnumerable<IGPHistoryItem>;
    
    String hitemID = "";
    String hitemToolPath = "";
    IGPResult hitemGPResult = null;
    DateTime hitemTimeStamp;
    
    foreach (var hitem in hisItems)
    {
      // common IGPHistoryItem and Item properties
      hitemID = (hitem as Item).ID;
      hitemToolPath = hitem.ToolPath;
      hitemGPResult = hitem.GPResult;
      hitemTimeStamp = hitem.TimeStamp;
    }
    
    
    How to use Geoprocessing public event
    ArcGIS.Desktop.Core.Events.GPExecuteToolEvent.Subscribe(e =>
          {
            string id = e.ID;                   // Same as history ID
            if (e.IsStarting == false)  // Execute completed
              _ = e.GPResult.ReturnValue;
            System.Windows.MessageBox.Show("event triggered.");
          });
    await Geoprocessing.ExecuteToolAsync("management.GetCount", Geoprocessing.MakeValueArray(@"c:\shape_file.shp"));
    
    How to use Geoprocessing public event
    ArcGIS.Desktop.Core.Events.GPExecuteToolEvent.Subscribe(e =>
          {
            string id = e.ID;                   // Same as history ID
            if (e.IsStarting == false)  // Execute completed
              _ = e.GPResult.ReturnValue;
            System.Windows.MessageBox.Show("event triggered.");
          });
    await Geoprocessing.ExecuteToolAsync("management.GetCount", Geoprocessing.MakeValueArray(@"c:\shape_file.shp"));
    
    Add Geometry via MakeValueArray to GP Tool parameter lists
    var tool_name = "analysis.Clip";
    var extent = MapView.Active.Extent;
    var sel_layer = MapView.Active.Map.GetLayersAsFlattenedList()
                      .OfType<FeatureLayer>().FirstOrDefault(l => l.Name == "GreatLakes");
    if (sel_layer == null) return;
    
    var gdb = Project.Current.DefaultGeodatabasePath;
    var out_fc = System.IO.Path.Combine(gdb, "clipped_lakes_out");
    
    var val_array = await QueuedTask.Run(() =>
    {
    
      var rect = GeometryEngine.Instance.Scale(extent, extent.Center, 0.5, 0.5) as Envelope;
      var clip_poly = PolygonBuilderEx.CreatePolygon(rect, rect.SpatialReference);
    
      //Add the geometry to a list before calling MakeValueArray
      //Envelope and Geometry types are supported
      var geom = new List<object>() { clip_poly };
      return Geoprocessing.MakeValueArray(new object[] { sel_layer, geom, out_fc });
    
    });
    Geoprocessing.ExecuteToolAsync(tool_name, val_array,
      null, null, null, GPExecuteToolFlags.InheritGPOptions);
    
    Requirements

    Target Platforms: Windows 11, Windows 10

    ArcGIS Pro version: 3 or higher.
    See Also