Author Topic: Error HRESULT E_FAIL has been returned from a call to a COM component  (Read 15317 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Hi All!
I get error in row of 15 (message's copy in row's comment).

AutoCAD 2009 x64 SP3. If use AutoCAD 2009 x86 - then look comment of 14 row's.

Code: [Select]
  1:  //Test code
   2:  Document dwg = acadApp.DocumentManager.MdiActiveDocument;
   3:  Database db = dwg.Database;
   4:  TableStyle ts = new TableStyle();
   5:  TableStyle ts1;
   6:  ObjectId id = ts.PostTableStyleToDatabase(dwg.Database, tableStyleName);
   7:  using (Transaction t = dwg.TransactionManager.StartTransaction())
   8:  {
   9:      ts1 = (TableStyle)t.GetObject(id, OpenMode.ForRead);
  10:  }            
  11:  AcadApplication app = (AcadApplication)acadApp.AcadApplication;
  12:  if (ts == ts1)[color=green]//additional check on searching of error[/color]
  13:  {
  14:      long i = (long)id.OldIdPtr;// [color=green]if AutoCAD x86, then write this: int i = (int)id.OldIdPtr;[/color]
  15:      object x = app.ActiveDocument.ObjectIdToObject(i);//[color=red]Error HRESULT E_FAIL has been returned from a call to a COM component.[/color]
  16:      IAcadTableStyle2 ts2 = (IAcadTableStyle2)x;
  17:  }
Where my mistake?
« Last Edit: July 27, 2010, 01:47:38 PM by Hwd »

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
hmmm ...

Just from looking at the code, it appears as though ts is a new TableStyle and it appears as though you are putting it in the current document, but from the code it doesn't appear as though you are giving it a name ... tableStyleName isn't set in this code (although it may be set elsewhere).

Perhaps you need to verify whether or not i actually contains a value, and whether that value is valid.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Andrey Bushman

  • Swamp Rat
  • Posts: 864
hmmm ...

Just from looking at the code, it appears as though ts is a new TableStyle and it appears as though you are putting it in the current document, but from the code it doesn't appear as though you are giving it a name ... tableStyleName isn't set in this code (although it may be set elsewhere).

Perhaps you need to verify whether or not i actually contains a value, and whether that value is valid.

i actually contains a value.

Glenn R

  • Guest
Hi All!
I get error in row of 15 (message's copy in row's comment).

AutoCAD 2009 x64 SP3. If use AutoCAD 2009 x86 - then look comment of 14 row's.

Code: [Select]
   1:  //Test code
   2:  Document dwg = acadApp.DocumentManager.MdiActiveDocument;
   3:  Database db = dwg.Database;
   4:  TableStyle ts = new TableStyle();
   5:  TableStyle ts1;
   6:  ObjectId id = ts.PostTableStyleToDatabase(dwg.Database, tableStyleName);
   7:  using (Transaction t = dwg.TransactionManager.StartTransaction())
   8:  {
   9:      ts1 = (TableStyle)t.GetObject(id, OpenMode.ForRead);
  10:  }           
  11:  AcadApplication app = (AcadApplication)acadApp.AcadApplication;
  12:  if (ts == ts1)[color=green]//additional check on searching of error[/color]
  13:  {
  14:      long i = (long)id.OldIdPtr;// [color=green]if AutoCAD x86, then write this: int i = (int)id.OldIdPtr;[/color]
  15:      object x = app.ActiveDocument.ObjectIdToObject(i);//[color=red]Error HRESULT E_FAIL has been returned from a call to a COM component.[/color]
  16:      IAcadTableStyle2 ts2 = (IAcadTableStyle2)x;
  17:  }
Where my mistake?

Where's your mistake? Apart from still using COM when I showed you in your other thread how to use PInvoke, it's your use of long's and trying to convert them to objectid's when you don't have to.

Ponder the following, which is an update to the code I previously provided in your other cellstyles thread:
Code: [Select]

using System;
using System.Runtime.InteropServices;

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(CellStyles.MyCommands))]

namespace CellStyles
{
    public class MyCommands
    {
        [CommandMethod("q1", CommandFlags.Modal)]
        public void TestMethod()
        {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                DBDictionary tsd = (DBDictionary) tr.GetObject(db.TableStyleDictionaryId, OpenMode.ForRead);
                foreach (DBDictionaryEntry item in tsd)
                {
                    TableStyle ts = (TableStyle)tr.GetObject(item.Value, OpenMode.ForRead);

                    // CODE Added - Start
                    IAcadTableStyle comTableStyle = ts.AcadObject as IAcadTableStyle;
                    if (comTableStyle == null)
                    {
                        ed.WriteMessage("{0}Ooooops!", Environment.NewLine);
                    }
                    else
                    {
                        ed.WriteMessage("{0}COM TableStyle name: {1}", Environment.NewLine, comTableStyle.Name);
                    }

                    // this is for demonstration purposes and not necessarily required...
                    Marshal.FinalReleaseComObject(comTableStyle);
                    // CODE Added - End

                    ed.WriteMessage(string.Format("{0}Table style name: '{1}'", Environment.NewLine, ts.Name));
                    ed.WriteMessage(string.Format("{0}(TableStyle.CellStyles.IsReadOnly ='{1}')",
                        Environment.NewLine, ts.CellStyles.IsReadOnly));

                    //Print all cell style names of table style
                    PrintCellStylesInfo(ts);
                    string stName = "MyStyle";// name for my new cell style

                    ed.WriteMessage(string.Format("{0}Before modify: Cell Styles Count: {1}",
                        Environment.NewLine, ts.CellStyles.Count));

                    ts.UpgradeOpen();

                    AcDbTable.createCellStyle(ts.UnmanagedObject, stName);

                    ed.WriteMessage(string.Format("{0}After modify: Cell Styles Count: {1}{0}",
                                    Environment.NewLine, ts.CellStyles.Count));

                    ts.SetCellClass(CellClass.Label, stName);

                    ed.WriteMessage(string.Format("{0}{1}{0}", "\nAfter modify:", new string('*', 30)));
                    //Print all cell style names of table style
                    PrintCellStylesInfo(ts);
                }

                tr.Commit();
            }         
        }
 
        private void PrintCellStylesInfo(TableStyle ts)
        {
            foreach (var cs in ts.CellStyles)
            {
                Document doc = acadApp.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage(string.Format("{0}CellStyle Type: '{1}'; CellStyle.ToString: {2}",
                                Environment.NewLine, cs.GetType(), cs.ToString()));
            }           
        }
    }

    public static class AcDbTable
    {
        // Acad::ErrorStatus createCellStyle(const ACHAR* pszCellStyle);

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("acdb18.dll", CallingConvention = CallingConvention.ThisCall, CharSet = CharSet.Unicode,
           EntryPoint = "?createCellStyle@AcDbTableStyle@@QEAA?AW4ErrorStatus@Acad@@PEB_W@Z")]
        public static extern ErrorStatus createCellStyle(IntPtr tableStyle, string name);
    }

}

Follow the Online AutoCAD .NET Developers Guide to add the required references. It will tell you to add files from 'Common Files' whereas as I added the same files from the ObjectARXSDK\inc-x64 directory.

Hope this helps.

Bryco

  • Water Moccasin
  • Posts: 1883
Glenn there are probably 3 or 4 entry points reqd.
How do you derive
Quote
EntryPoint = "?createCellStyle@AcDbTableStyle@@QEAA?AW4ErrorStatus@Acad@@PEB_W@Z")]

Glenn R

  • Guest
Bryco,

Trial and error, although you can see it has createcellstyle, acdbtablestyle acaderrorstatus in the mangled name.

I used dependencywalker for this as dumpbin is not available in express and there could be a very specific way to lookup the arx function call, but its the first time I've used it....<sheepish grin> hehe

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Glenn there are probably 3 or 4 entry points reqd.
How do you derive
Quote
EntryPoint = "?createCellStyle@AcDbTableStyle@@QEAA?AW4ErrorStatus@Acad@@PEB_W@Z")]

Bryco,

Trial and error, although you can see it has createcellstyle, acdbtablestyle acaderrorstatus in the mangled name.

I used dependencywalker for this as dumpbin is not available in express and there could be a very specific way to lookup the arx function call, but its the first time I've used it....<sheepish grin> hehe

I've just posted these. Perhaps someone will add the AC2009 dumps.
http://www.theswamp.org/index.php?topic=34278.msg395750#msg395750
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

sinc

  • Guest
I used dependencywalker for this as dumpbin is not available in express and there could be a very specific way to lookup the arx function call, but its the first time I've used it....<sheepish grin> hehe

dumpbin is available in the Express C++ Edition.

Bryco

  • Water Moccasin
  • Posts: 1883
Ripper Rita, that helps

pkohut

  • Guest
Ripper Rita, that helps

I added to Kerry's post a method to unmangle the names in the file dumpbin produces.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Error HRESULT E_FAIL has been returned from a call to a COM component
« Reply #10 on: July 28, 2010, 01:04:38 AM »
Quote
it's your use of long's and trying to convert them to objectid's when you don't have to.

I use long in my code for AutoCAD 2009 x64, because I get error when use int:



I use int in my code for AutoCAD 2009 x86, but I get it error again.
Quote
Ponder the following, which is an update to the code I previously provided in your other cellstyles thread:
Thank you for code, but I have not problem with iteration for existing table styles. I get my error after new table style add in drawing data base - when try get IAcadTableStyle for it.
Quote
Follow the Online AutoCAD .NET Developers Guide to add the required references. It will tell you to add files from 'Common Files' whereas as I added the same files from the ObjectARXSDK\inc-x64 directory.
But I use it references already (and I get it error).

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Error HRESULT E_FAIL has been returned from a call to a COM component
« Reply #11 on: July 28, 2010, 01:36:26 AM »

Quote from: Glenn in the UK in the middle of Summer
IAcadTableStyle comTableStyle = ts.AcadObject as IAcadTableStyle;

I thought I was the only one to name COM variable prefixed with com....   :wink:
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Error HRESULT E_FAIL has been returned from a call to a COM component
« Reply #12 on: July 28, 2010, 02:10:53 AM »
Quote
it's your use of long's and trying to convert them to objectid's when you don't have to.

I use long in my code for AutoCAD 2009 x64, because I get error when use int:


OldIdPtr returns an IntPtr, so try using ToIntXX  :-)

Code: [Select]
      ObjectId id = ObjectId.Null;
      IntPtr i = id.OldIdPtr;
      i.ToInt32();// 32
      i.ToInt64();// 64
     

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Error HRESULT E_FAIL has been returned from a call to a COM component
« Reply #13 on: July 28, 2010, 02:26:40 AM »
Interestingly, according to Microsoft, whenever you use managed code to make calls to COM objects, the interop object is supposed map the types required from managed to unmanaged and vice versa transparently. However, since int is available in both code structures, you don't need to do anything i.e. IntPtr probably isn't required.

Since C# doesn't (or isn't supposed to) return an HRESULT structure, the error isn't being generated from your code, and is instead being generated by the COM type library. So the value you are passing is obviously incorrect.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Error HRESULT E_FAIL has been returned from a call to a COM component
« Reply #14 on: July 28, 2010, 02:32:07 AM »

just a wild-assed thought ..
what does this produce when debugging
Code: [Select]

var  i = id.OldIdPtr;

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.