Hi,
I'm creating an Add-in Application for ArcGIS Pro v2.9 using Visual Studio 2019 in C#.
How do I access the geoprocessing assemblies so I can execute them in my codes? I have the following code but I'm getting an error: "Unable to load DLL ArcGISVersion.dll. The specified module could not be found."
Here's my code snippet:
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.DataManagementTools;
private void ConnectToSQLServerDb()
{
//Declares variables here...
//Initialize a geoprocessing object
Geoprocessor GP = new Geoprocessor();
CreateDatabaseConnection dbCon = new CreateDatabaseConnection();
try
{
//Specify parameters
dbCon.out_folder_path = outFolder;
dbCon.out_name = outName;
dbCon.database_platform = dbPlatform;
dbCon.instance = sqlInstance;
dbCon.database = dbName;
dbCon.account_authentication = "OPERATING_SYSTEM_AUTH";
//Execute tool
GP.OverwriteOutput = true;
GP.Execute(dbCon, null);
}
catch (Exception ex)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Failed to reset table: " + ex.Message, "Error Message", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
GP = null;
dbCon = null;
}
}
Solved! Go to Solution.
This looks like code from ArcObjects to run Geoprocessing tools. It's much different in ArcGIS Pro, using different assemblies and supplying the parameters using a list of arguments rather than properties. Take a look at the documentation on how to run Geoprocessing tools.
Here's an example I use that runs the "Create Feature Class" tool.
using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Core.Geometry;
using System.Collections.Generic;
using System.Threading.Tasks;
public static async Task<IGPResult> CreateLayer(string path, string featureclassName, string featureclassType, int SR_wkid)
{
List<object> arguments = new List<object>
{
// store the results in the default geodatabase
//CoreModule.CurrentProject.DefaultGeodatabasePath,
path,
// name of the feature class
featureclassName,
// type of geometry
featureclassType,
// no template
"",
// no m values
"DISABLED",
// no z values
"DISABLED"
};
await QueuedTask.Run(() =>
{
// spatial reference
arguments.Add(SpatialReferenceBuilder.CreateSpatialReference(SR_wkid));
});
IGPResult result = await Geoprocessing.ExecuteToolAsync("CreateFeatureclass_management", Geoprocessing.MakeValueArray(arguments.ToArray()), null, null, null, GPExecuteToolFlags.None);
return result;
}
This looks like code from ArcObjects to run Geoprocessing tools. It's much different in ArcGIS Pro, using different assemblies and supplying the parameters using a list of arguments rather than properties. Take a look at the documentation on how to run Geoprocessing tools.
Here's an example I use that runs the "Create Feature Class" tool.
using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Core.Geometry;
using System.Collections.Generic;
using System.Threading.Tasks;
public static async Task<IGPResult> CreateLayer(string path, string featureclassName, string featureclassType, int SR_wkid)
{
List<object> arguments = new List<object>
{
// store the results in the default geodatabase
//CoreModule.CurrentProject.DefaultGeodatabasePath,
path,
// name of the feature class
featureclassName,
// type of geometry
featureclassType,
// no template
"",
// no m values
"DISABLED",
// no z values
"DISABLED"
};
await QueuedTask.Run(() =>
{
// spatial reference
arguments.Add(SpatialReferenceBuilder.CreateSpatialReference(SR_wkid));
});
IGPResult result = await Geoprocessing.ExecuteToolAsync("CreateFeatureclass_management", Geoprocessing.MakeValueArray(arguments.ToArray()), null, null, null, GPExecuteToolFlags.None);
return result;
}
Hi,
Got it. I changed the codes to:
//Namespaces used
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Core.Geoprocessing;
var args = Geoprocessing.MakeValueArray(outFolder, outName, server, sqlInstance, "OPERATING_SYSTEM_AUTH", dbName, "Transactional");
var gp_result = Geoprocessing.ExecuteToolAsync("CreateDatabaseConnection_management", Geoprocessing.MakeValueArray(args.ToArray()));
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Finished creating database connection: ", "Result", MessageBoxButton.OK, MessageBoxImage.Information);
How do I make a call to CreateLayer from Button_Click event?
Thanks
This is how I call it and use the result
var result = await CreateLayer(System.IO.Path.GetDirectoryName(output), System.IO.Path.GetFileName(output), "POINT", SR.Wkid);
using (var outputFC = GDBItemHelper.GetDatasetFromPath(result.ReturnValue) as FeatureClass) {}
Esri Support supplied the code for the GDBItemHelper class since this wasn't readily apparent in the Pro SDK documentation
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace xxxx //use your own namespace
{
internal static class GDBItemHelper
{
public const int lengthOfFileExtension = 4;
// Keywords
public const string FeatureClassKeyword = "Feature Class";
public const string FeatureDatasetKeyword = "Feature Dataset";
public const string TableKeyword = "Table";
public const string RelationshipClassKeyword = "Relationship Class";
//async flavors
public static Task<Dataset> GetDatasetFromItemAsync(Item item)
{
return QueuedTask.Run(() => GetDatasetFromItem(item));
}
public static Task<Dataset> GetDatasetFromPathAsync(string path)
{
return QueuedTask.Run(() => GetDatasetFromPath(path));
}
//Sync flavors - use the QueuedTask
public static Dataset GetDatasetFromItem(Item item)
{
if (!QueuedTask.OnWorker)
throw new ArcGIS.Core.CalledOnWrongThreadException();
if (item.TypeID.StartsWith("fgdb_") || item.TypeID.EndsWith("_fgdb"))
return OpenDatasetForExtension(".gdb", item);
if (item.TypeID.StartsWith("egdb_") || item.TypeID.EndsWith("_egdb"))
return OpenDatasetForExtension(".sde", item);
if (item.TypeID.StartsWith("shapefile_"))
return OpenDatasetForExtension(".shp", item);
return null;
}
public static Dataset GetDatasetFromPath(string path)
{
if (!QueuedTask.OnWorker)
throw new ArcGIS.Core.CalledOnWrongThreadException();
//check the path
int indexOfgdb = path.LastIndexOf(".gdb", StringComparison.InvariantCultureIgnoreCase);
if (indexOfgdb == -1)
indexOfgdb = path.LastIndexOf(".sde", StringComparison.InvariantCultureIgnoreCase);
if (indexOfgdb == -1)
indexOfgdb = path.LastIndexOf(".shp", StringComparison.InvariantCultureIgnoreCase);
if (indexOfgdb == -1)
return null;
//make the item
var item = ItemFactory.Instance.Create(path);
//retrieve the dataset
return GetDatasetFromItem(item);
}
private static Dataset OpenDatasetForExtension(string extension, Item item)
{
int indexOfgdb = item.Path.LastIndexOf(extension, StringComparison.InvariantCultureIgnoreCase);
if (indexOfgdb == -1)
return null;
string gdbPath = item.Path.Substring(0, indexOfgdb + lengthOfFileExtension);
if (extension == ".sde")
{
using (ArcGIS.Core.Data.Geodatabase geodatabase = new ArcGIS.Core.Data.Geodatabase(new DatabaseConnectionFile(new Uri(gdbPath))))
{
if (item.TypeKeywords.Contains(FeatureClassKeyword))
return geodatabase.OpenDataset<FeatureClass>(item.Name);
if (item.TypeKeywords.Contains(FeatureDatasetKeyword))
return geodatabase.OpenDataset<FeatureDataset>(item.Name);
if (item.TypeKeywords.Contains(TableKeyword))
return geodatabase.OpenDataset<Table>(item.Name);
if (item.TypeKeywords.Contains(RelationshipClassKeyword))
return geodatabase.OpenDataset<RelationshipClass>(item.Name);
}
}
else if (extension == ".gdb")
{
using (ArcGIS.Core.Data.Geodatabase geodatabase = new ArcGIS.Core.Data.Geodatabase(new FileGeodatabaseConnectionPath(new Uri(gdbPath))))
{
if (item.TypeKeywords.Contains(FeatureClassKeyword))
return geodatabase.OpenDataset<FeatureClass>(item.Name);
if (item.TypeKeywords.Contains(FeatureDatasetKeyword))
return geodatabase.OpenDataset<FeatureDataset>(item.Name);
if (item.TypeKeywords.Contains(TableKeyword))
return geodatabase.OpenDataset<Table>(item.Name);
if (item.TypeKeywords.Contains(RelationshipClassKeyword))
return geodatabase.OpenDataset<RelationshipClass>(item.Name);
}
}
else if (extension == ".shp")
{
var shapePath = System.IO.Path.GetDirectoryName(gdbPath);
using (ArcGIS.Core.Data.FileSystemDatastore shape = new FileSystemDatastore(new FileSystemConnectionPath(new Uri(shapePath), FileSystemDatastoreType.Shapefile)))
{
return shape.OpenDataset<FeatureClass>(item.Name);
}
}
return null;
}
}
}