Another "IFeatureWorkspace::CreateFeatureClass()" error

513
6
03-09-2011 06:05 AM
GaryBroyd
New Contributor
Hi everybody,

We have been integrating our VB6 app with ArcMap for quite a few versions of ArcGIS now and have decided to move over to .Net due to VB6 no longer being supported (and we are going to have to do it for the next ArcGIS release anyway!)

We are encountering a number of problems while porting our code.  At the moment we have basically translated the code (which worked fine under VB6 up to ArcGIS 9.3) as is with a few tweaks here and there based on other problems we have found (like having to create classes via factories instead of using "new" keyword)

The one I'm stuck on now is one that seems to have plagued a few people but I can't seem to find any solutions which fix our problem.

You'll have to forgive me, I'm not really familiar with ArcGIS and have been given the job of getting it working with ArcGIS 10 so I'm not really up to speed on the object model of ArcGIS.

The error is bascially to do with calling CreateFeatureClass() in that it throws the error:

Error: Error HRESULT E_FAIL has been returned from a call to a COM component.

Now we have made sure we have the acquired the correct licence (it's an ArcEditor licence which we are using for in-house development purposes) as we have had other problems with this sort of thing while doing our port.

Below is some of the code for a routine which is creating a Shape File.  At the bottom of the code snippet there is a try catch which is where the error occurs.  What is odd is when running from the IDE, if I put a break point in the catch, and upon getting the exception, drag it back up and re-run the line that errored again, it then works.  Also sometimes waiting long enough before running the CreateFeatureClass() line will mean it runs ok which makes me wonder if it's some sort of timing issue.  We aren't doing anything fnacy other than starting ArcMap (via IMxDocument object), loading a document (and waiting for the "OpenDocument" event to trigger) and then creating the Shape File (a few bits inbetween but these all work fine)

Any way to the code:

Type type = Type.GetTypeFromProgID( "esriDataSourcesFile.ShapefileWorkspaceFactory" );
ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactory shapefileWorkspaceFactory = Activator.CreateInstance( type ) as ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactory;
ESRI.ArcGIS.Geodatabase.IFeatureWorkspace featureWorkspace;

featureWorkspace = shapefileWorkspaceFactory.OpenFromFile( System.IO.Path.GetDirectoryName( mapDataFilePath ), 0 ) as IFeatureWorkspace;

ESRI.ArcGIS.Geodatabase.IFields fields = new ESRI.ArcGIS.Geodatabase.Fields();
ESRI.ArcGIS.Geodatabase.IFieldsEdit fieldsEdit = fields as ESRI.ArcGIS.Geodatabase.IFieldsEdit;
IField shapeField = new ESRI.ArcGIS.Geodatabase.Field();
IFieldEdit fieldEdit = shapeField as IFieldEdit;
string filenameOnly = System.IO.Path.GetFileNameWithoutExtension(mapDataFilePath);

fieldEdit.Name_2 = "Shape";
fieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;

IGeometryDef geometryDef = new GeometryDefClass();
IGeometryDefEdit geometryDefEdit = geometryDef as IGeometryDefEdit;

geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
geometryDefEdit.SpatialReference_2 = new UnknownCoordinateSystemClass();

fieldEdit.GeometryDef_2 = geometryDef;

fieldsEdit.AddField( shapeField );

IFeatureClass featureClass;

//*********************************************************
//THIS IS WHERE THE EXCEPTION OCCURS
//*********************************************************
try
{
 featureClass = featureWorkspace.CreateFeatureClass( "Data1", fields, null, null, esriFeatureType.esriFTSimple, "Shape", "" );
}
catch ( Exception ex )
{
 Debug.Print( "Error: " + ex.Message );
}   


Thanks,

Gary
0 Kudos
6 Replies
LukeBadgerow
New Contributor
Could it be that you're missing a CLSID?

var CLSID = new UIDClass();
CLSID.Value = "esriGeodatabase.Feature";


which would make your Create Statement look like this:

IFeatureWorkspace.CreateFeatureClass("test", outfields, CLSID, null, esriFeatureType.esriFTSimple, "SHAPE", "");


You mention timing, which to me screams that you're waiting on a schema lock to clear, but if you're working with a shapefile workspacefactory that shouldn't be your issue. 

I'm actually running into what to me looks like a definite issue with schema locks.  I can create a feature dataset using the same method listed above, but I can't create the feature classes I need I'm getting the following error, which is different from your COMException:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
ESRI.ArcGIS.Geodatabase
   at ESRI.ArcGIS.Geodatabase.IFeatureDataset.CreateFeatureClass(String Name, IFields Fields, UID CLSID, UID EXTCLSID, esriFeatureType FeatureType, String ShapeFieldName, String ConfigKeyword)
   at WaterEditorExtension.Model.SurveyUtilities.StreamWriting(String pointtype, String outfile, String[] record, IWorkspace workspace) in C:\Documents and Settings\lbadgerow\My Documents\Visual Studio 2008\Projects\WaterEditorExtension\WaterEditorExtension\Model\SurveyUtilities.cs:line 206.

I hope my little bit helps, and sorry for piggybacking your thread.

good luck
0 Kudos
GaryBroyd
New Contributor
Hi Luke,

No worries - all discussions help don't they.

I must admit I'm not sure if the CLSID is needed or not - it didn't when used from the VB6 code on 9.3 - all I have done is ported the code as closely as possible.

Just checking the documentation and it seems to suggest that in most cases it can be passed through as null

The CLSID parameter is used to specify what type of feature will be contained by the class. If a null value is passed in for the CLSID, the geodatabase will return Feature instances from the class. In most cases, this is the desired behavior.


I'll gave it a try and first time it worked (thinking hooray it worked) but running it a second time failed - so again it just seems to be random.  I even tried a crude technique of catching the exception and trying again which claimed to work but then when ArcMap finally displays, I get the "This app has crashed" type dialog and it all shuts down.  So back to the drawing board!!

Thanks though,

Gary
0 Kudos
NeilClemmons
Regular Contributor III
You mention checking out a license.  If you're running your code inside ArcMap you don't need to do this.  In fact, you shouldn't be doing that.  You only need to check out a license if you're building a standalone application (*.exe).  The CLSID should not be necessary but I always specify one.  It used to be required and it's an old habit (probably a good one).  You also said it worked the first time then not the second time.  The CreateFeatureClass method will not overwrite an existing feature class.  If the feature class already exists, it will throw an exception.  You should have code somewhere that makes sure the feature class does not already exist.  I don't see it in what you posted so if you have it somewhere else then you should be good to go.  If not, you'll want to add that.  Also, I don't see where you're creating the ObjectId field for your fields collection.  It may be the case that it will create one automatically but I always create it myself.  ESRI has changed how this method works several times over the years so I'm not sure what is done now by default.  These are just a few things off the top of my head.
0 Kudos
GaryBroyd
New Contributor
Hi Neil,

Thanks for your reply.

Just to reclarify, we have a standalone app which starts ArcMap and sends location information to it (e.g. addresses)

If CreateFeatureClass() throws an error if there is already an existing item, is there anyway to find out if it exists already (bar doing something horrid like calling OpenFeatureClass and trapping the error if it doesn't exist).  Sorry but it's difficult to tell what with there being so many interfaces across all objects - never know what I can cast to what - again I'm pretty new to all this ArcGIS stuff.

Also, I don't see where you're creating the ObjectId field for your fields collection. It may be the case that it will create one automatically but I always create it myself. ESRI has changed how this method works several times over the years so I'm not sure what is done now by default. These are just a few things off the top of my head.


Erm - you got me - not sure about this one (again this is basically code converted from VB6 which worked)

But it appears to be this part which is setting up the field:

   IField shapeField = new ESRI.ArcGIS.Geodatabase.Field();
   IFieldEdit fieldEdit = shapeField as IFieldEdit;
   string filenameOnly = System.IO.Path.GetFileNameWithoutExtension(mapDataFilePath);

   fieldEdit.Name_2 = "Shape";
   fieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;

   IGeometryDef geometryDef = new GeometryDefClass();
   IGeometryDefEdit geometryDefEdit = geometryDef as IGeometryDefEdit;

   geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
   geometryDefEdit.SpatialReference_2 = new UnknownCoordinateSystemClass();

   fieldEdit.GeometryDef_2 = geometryDef;

   fieldsEdit.AddField( shapeField );


Is there something specific I should be doing - just in case it's that that is resulting in the error?
0 Kudos
LukeBadgerow
New Contributor
Hi Neil,

Thanks for your reply.

Just to reclarify, we have a standalone app which starts ArcMap and sends location information to it (e.g. addresses)

If CreateFeatureClass() throws an error if there is already an existing item, is there anyway to find out if it exists already (bar doing something horrid like calling OpenFeatureClass and trapping the error if it doesn't exist).  Sorry but it's difficult to tell what with there being so many interfaces across all objects - never know what I can cast to what - again I'm pretty new to all this ArcGIS stuff.


You should be able to loop through the contents of your Workspace with the .get_Datasets(...)/ or .get_DatasetNames(...) method without opening the feature class up.  You'll just need to pass in the esriDTType for the feature class.
0 Kudos
GaryBroyd
New Contributor
You should be able to loop through the contents of your Workspace with the .get_Datasets(...)/ or .get_DatasetNames(...) method without opening the feature class up.  You'll just need to pass in the esriDTType for the feature class.


Hi Luke,

Thanks for that - that made a difference I think.  I have been making lots of changes all over the place - usually replacing any instantiations of specific classes with calls to the ObjectFactory.

But now I'm onto lots of other problems - namely trying to use a UniqueValueRenderer to create symbols - all seems ok except my bitmaps don't appear and I can't set the image in ArcMap until I change the type to something else and back again - all very odd - I'll keep chugging away at it.

Thanks,

Gary
0 Kudos