Select to view content in your preferred language

Append layer in standalone C# application outside of ArcMap

1108
2
07-18-2011 05:27 AM
CarlosPiccirillo
Emerging Contributor
Hi everyone,

I am writing a standalone C# application and have hit a snag using the Append command. The code below works fine if I first start ArcMap and then run the code. The problem with doing it this way is that the append command takes four or five times the amount of time to run from inside ArcMap than doing it manually in ArcToolBox and performance is of the upmost importance. If I try to run this code from outside of ArcMap, I hit a snag at line: IObjectFactory pObjectFactory = m_application as IObjectFactory because m_application is null. In the original code, I was getting a reference to it from the start up routine. Any idea how I can get a reference to m_applicaiton from outside ArcMap?

Thanks,
Carlos

        public static void AppendFeatureClasses()
        {
            try
            {
                IObjectFactory pObjectFactory = m_application as IObjectFactory;

                //Delete connection file if it exists.
                if (File.Exists(Scratch_Local + "gerrpsde.sde"))
                    File.Delete(Scratch_Local + "gerrpsde.sde");

                //Create connection file.
                //IPropertySet pPropertySet = new PropertySetClass();
                Type propertySetType = typeof(PropertySetClass);
                string typeClsID1 = propertySetType.GUID.ToString("B");
                IPropertySet pPropertySet = (IPropertySet)pObjectFactory.Create(typeClsID1);
                pPropertySet = GetSdePropertySet("gerrpsde", null);
                
                Type SdeWorkspaceFactoryType = typeof(SdeWorkspaceFactoryClass);
                string typeClsID2 = SdeWorkspaceFactoryType.GUID.ToString("B");
                IWorkspaceFactory pWorkspaceFactory = (IWorkspaceFactory)pObjectFactory.Create(typeClsID2); 
                pWorkspaceFactory.Create(Scratch_Local, "gerrpsde.sde", pPropertySet, 0);

                //Create App_Merge layer.
                object[,] fieldsValuesArray = new object[1, 5];
                fieldsValuesArray[0, 0] = "APP_NO";
                fieldsValuesArray[0, 1] = esriFieldType.esriFieldTypeString;
                fieldsValuesArray[0, 2] = true;
                fieldsValuesArray[0, 3] = true;
                fieldsValuesArray[0, 4] = 20;

                IFields pFields = CreateFieldsCollection(fieldsValuesArray);

                Type FileGDBWorkspaceFactoryType = typeof(FileGDBWorkspaceFactoryClass);
                string typeFileGdbClsID = FileGDBWorkspaceFactoryType.GUID.ToString("B");
                IWorkspaceFactory pFileGDBWorkspaceFactory = (IWorkspaceFactory)pObjectFactory.Create(typeFileGdbClsID); 
                IFeatureWorkspace pFeatureWorkspace = pFileGDBWorkspaceFactory.OpenFromFile(Scratch_Local + "temp.gdb", 0) as IFeatureWorkspace;
                IFeatureClass pOutFeatureClass = CreateFeatureClass(pFeatureWorkspace, "App_Merge", esriFeatureType.esriFTSimple, esriGeometryType.esriGeometryPolygon, pFields, null, null, null);

                // Create the layer.
                Type featureLayerType = typeof(FeatureLayerClass);
                string typeClsID3 = featureLayerType.GUID.ToString("B");
                IFeatureLayer pFeatureLayer = (IFeatureLayer)pObjectFactory.Create(typeClsID3);
                pFeatureLayer.FeatureClass = pOutFeatureClass;

                // Do Append.
                //UIDClass uid = new UIDClass();
                Type uidType = typeof(UIDClass);
                string typeClsID4 = uidType.GUID.ToString("B");
                UID uid = (UID)pObjectFactory.Create(typeClsID4);
                uid.Value = "esriGeoprocessingUI.ArcToolBoxExtension";
                IArcToolboxExtension tbExtension = (IArcToolboxExtension)m_application.FindExtensionByCLSID(uid);
                IArcToolbox toolbox = tbExtension.ArcToolbox;
                IGPTool appendTool = toolbox.GetToolbyNameString("Append_management");
                IArray parametersArray = appendTool.ParameterInfo;

                // GP Parameter
                IGPParameter parameter;
                IGPParameterEdit parameterEdit;
                IGPDataType dataType;
                string parameterValue;

                // Set first parameter (input layers).
                parameter = (IGPParameter)parametersArray.get_Element(0);
                dataType = parameter.DataType;
                parameterEdit = (IGPParameterEdit)parameter;
                parameterValue = Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_SWM_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_ERP_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_PWS_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DEW_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DIV_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_APP_AREA";
                
                parameterEdit.Value = dataType.CreateValue(parameterValue);

                // Set up second parameter (output file).
                parameter = (IGPParameter)parametersArray.get_Element(1);
                dataType = parameter.DataType;
                parameterEdit = (IGPParameterEdit)parameter;
                parameterValue = Scratch_Local + "temp.gdb" + "\\" + "App_Merge";
                parameterEdit.Value = dataType.CreateValue(parameterValue);

                parameter = (IGPParameter)parametersArray.get_Element(2);
                dataType = parameter.DataType;
                parameterEdit = (IGPParameterEdit)parameter;
                parameterValue = "NO_TEST";
                parameterEdit.Value = dataType.CreateValue(parameterValue);

                //ITrackCancel pTrackCancel = new CancelTrackerClass();
                Type CancelTrackerType = typeof(CancelTrackerClass);
                string typeClsID5 = CancelTrackerType.GUID.ToString("B");
                ITrackCancel pTrackCancel = (ITrackCancel)pObjectFactory.Create(typeClsID5); 
                pTrackCancel.CancelOnClick = false;
                pTrackCancel.CancelOnKeyPress = true;

                Type GPEnvironmentManagerType = typeof(GPEnvironmentManagerClass);
                string typeClsID6 = GPEnvironmentManagerType.GUID.ToString("B");
                IGPEnvironmentManager pGPEnvironmentManager = (IGPEnvironmentManager)pObjectFactory.Create(typeClsID6); 

                Type IGPMessagesType = typeof(GPMessagesClass);
                string typeClsID7 = IGPMessagesType.GUID.ToString("B");
                IGPMessages pGPMessages = (IGPMessages)pObjectFactory.Create(typeClsID7); 

                // Execute the tool. 
                appendTool.Execute(parametersArray, pTrackCancel, pGPEnvironmentManager, pGPMessages);
            }
            catch (Exception ex)
            {
                LogError(ex.StackTrace, ex.Message, "AppendFeatureClasses", null);
            }
        }
0 Kudos
2 Replies
NeilClemmons
Honored Contributor
You can only have an IApplication reference if ArcMap is running.  If it's not running then you'll need to modify the code to work without an application reference.  The first thing to do will be to get rid of the code that uses IObjectFactory.  Another thing I see is the way you're running the geoprocessing tool.  To run a geoprocessing tool, create an instance of the Geoprocessor class as well as an instance of the tool class you want to run.  Set the parameters on the tool class then pass it into IGeoprocessor.Execute.
0 Kudos
CarlosPiccirillo
Emerging Contributor
Neil,

Thanks for the reply!

As you suggested, I changed the code and got it to work. The new code is below. Do you see any potential pitfalls in doing it this way?

Thanks again,
Carlos

      
public static void AppendFeatureClasses()
        {
            try
            {
                //Delete connection file if it exists.
                if (File.Exists(Scratch_Local + "gerrpsde.sde"))
                    File.Delete(Scratch_Local + "gerrpsde.sde");

                //Create connection file.
                IPropertySet pPropertySet = new PropertySetClass();
                pPropertySet = GetSdePropertySet("gerrpsde", null);

                IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();
                pWorkspaceFactory.Create(Scratch_Local, "gerrpsde.sde", pPropertySet, 0);

                //Create App_Merge layer.
                object[,] fieldsValuesArray = new object[1, 5];
                fieldsValuesArray[0, 0] = "APP_NO";
                fieldsValuesArray[0, 1] = esriFieldType.esriFieldTypeString;
                fieldsValuesArray[0, 2] = true;
                fieldsValuesArray[0, 3] = true;
                fieldsValuesArray[0, 4] = 20;

                IFields pFields = CreateFieldsCollection(fieldsValuesArray);

                IWorkspaceFactory pFileGDBWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
                IFeatureWorkspace pFeatureWorkspace = pFileGDBWorkspaceFactory.OpenFromFile(Scratch_Local + "temp.gdb", 0) as IFeatureWorkspace;
                IFeatureClass pOutFeatureClass = CreateFeatureClass(pFeatureWorkspace, "App_Merge", esriFeatureType.esriFTSimple, esriGeometryType.esriGeometryPolygon, pFields, null, null, null);

                // Create the layer.
                IFeatureLayer pFeatureLayer = new FeatureLayerClass();
                pFeatureLayer.FeatureClass = pOutFeatureClass;

                // Do Append.
                ESRI.ArcGIS.DataManagementTools.Append pAppend = new ESRI.ArcGIS.DataManagementTools.Append();

                pAppend.inputs = Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_SWM_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_ERP_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_PWS_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DEW_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DIV_APP_AREA;" +
                                 Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_APP_AREA";

                pAppend.target = Scratch_Local + "temp.gdb" + "\\" + "App_Merge";
                pAppend.schema_type = "NO_TEST";

                ESRI.ArcGIS.Geoprocessor.Geoprocessor pGeoProcessor = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();

                ITrackCancel pTrackCancel = new CancelTrackerClass();
                pTrackCancel.CancelOnClick = false;
                pTrackCancel.CancelOnKeyPress = true;

                pGeoProcessor.Execute(pAppend, pTrackCancel);
            }
            catch (Exception ex)
            {
                LogError(ex.StackTrace, ex.Message, "AppendFeatureClasses", null);
            }
        }
You can only have an IApplication reference if ArcMap is running.  If it's not running then you'll need to modify the code to work without an application reference.  The first thing to do will be to get rid of the code that uses IObjectFactory.  Another thing I see is the way you're running the geoprocessing tool.  To run a geoprocessing tool, create an instance of the Geoprocessor class as well as an instance of the tool class you want to run.  Set the parameters on the tool class then pass it into IGeoprocessor.Execute.
0 Kudos