I have a C# app that was developed, compiled and successfully deployed in the AutoCAD 2008 and 2009 environments. I am trying to get this app to work in AutoCAD 2010 but am getting this error:
InvalidCastException: Unable to cast COM object of type System._ComObject to Autodesk.AutoCAD.Iterop.Common.AcaBlockReference. No such interface supported.
The code is:
if (thisDevice != null && !thisDevice.IsErased)
{
//Create a reference to the block and open it for reading
BlockReference myBR = (BlockReference)tm.GetObject(thisDevice, OpenMode.ForRead);
//In order to get the hidden/constant attribute values off of the object
//have to recast from an AcadObject to an AcadBlockReference
//////Error thrown here///////////
AcadBlockReference acadBlockRef = (AcadBlockReference)myBR.AcadObject;
//Get the array of Objects that make up the constant attributes
Object[] Objs = (Object[])acadBlockRef.GetConstantAttributes();
//Need an array of AcadAttributes to hold the constants
AcadAttribute[] Atts = new AcadAttribute[Objs.Length];
//Copy the constant attribute values from the Object array into
//the attribute array
Objs.CopyTo(Atts, 0);
//Concatenate the two values together
deviceDescription = Atts[0].TextString + " " + Atts[1].TextString;
} //End If thisDevice
I have downloaded the ARX 2010 SDK and tried pointing to the inc directory files from it, but all that does is render the app inoperable in the 2008 and 2009 environments. I still get the no such interface error.
What am I missing here?
First, I have no answer as to why your cast is not working. As long as myBR is a BlockReference, you should be able to cast myBR.AcadObject to AcadBlockReference.
That said, you do not have to use the COM object to get constant attributes. You just pull them from the BlockTableRecord that your BlockReference points to. This is what the .GetConstantAttributes function does also. Quoting the help file, "The attributes returned are the constant attribute definitions, not attribute references."
BlockReference bref = Trans.GetObject(selobj, OpenMode.ForRead, false, true);
BlockTableRecord btr = Trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead, false, true);
if (btr.HasAttributeDefinitions) {
foreach (ObjectId subid in btr) {
if (subid.ObjectClass.Name == "AcDbAttributeDefinition") {
AttributeDefinition atdef = Trans.GetObject(subid, OpenMode.ForRead, false, true);
if (atdef.Constant) {
\\ do whatever you need to do with the textstrings here
}
}
}
}
The code you have here does not indicate this, but if you happen to need to get other attribute values that are not constant, you get the ObjectID's of the AttributeReference's with myBR.AttributeCollection.
Did you type or copy that Exception message ?
InvalidCastException: Unable to cast COM object of type System._ComObject to Autodesk.AutoCAD.Iterop.Common.AcaBlockReference. No such interface supported.
Seems to be some mis-spelling there ....
[edit]
I really hate that this editor does not honor what is written !!!
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
ChiefBrainCloud:
The code example you gave works like a charm! Many thanks.
I got the original code from Tony T. awhile back and it worked fine until Acad 2010 came along.
KerryBrown:
I fat-fingered the error message in. There were some extraneous references to method names and line numbers in the code which I elected to leave out.
Thanks to both of you for your time.
Lial