Author Topic: eDwgObjectImproperlyRead when reading PlotSettings from a Template  (Read 6251 times)

0 Members and 1 Guest are viewing this topic.

mjrenaud

  • Guest
eDwgObjectImproperlyRead when reading PlotSettings from a Template
« on: September 26, 2013, 02:36:31 PM »
I'm really hoping someone has an idea of what I'm doing wrong here.
I'm reading a template for it's PlotSetttings, to display the properties of any of these PlotSettings in a WindowsForm. The reading of the dictionary value works fine. I can retrieve each PlotSetting's name, but opening that dictionary value to read causes the eDwgObjectImproperlyRead error. Here is the pertinent code that I'm working with:

            using (Transaction acTrans = db.TransactionManager.StartTransaction())
            {
                DBDictionary plSettings = acTrans.GetObject(db.PlotSettingsDictionaryId,
                                                            OpenMode.ForRead) as DBDictionary;
                if (plSettings != null)
                {
                    ListViewItem row;

                    // List each named page setup
                    foreach (DBDictionaryEntry item in plSettings)
                    {
                        plotSetting = item.Key;

                        PlotSettings settings = null;
                        settings = acTrans.GetObject(item.Value, OpenMode.ForRead) as PlotSettings;

    This last GetObject() call causes the error... I've hunted all over for all samples I could find that do anything similar, and this is basically the same as those samples. Of course, I don't know for certain that ANY of those sample actually work.
    Any ideas?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8718
  • AKA Daniel
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #1 on: September 26, 2013, 08:13:32 PM »
drawing may be bad, try doing an audit

mjrenaud

  • Guest
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #2 on: September 27, 2013, 12:37:40 PM »
Thanks for the suggestion, but the template file appears to be fine.
I suppose the fact that I can open the PlotSettingsDictionary and see the name of each PlotSetting, should have told me that. It's only when I try to open a PlotSetting in that dictionary that I get the error message.
« Last Edit: September 27, 2013, 12:42:04 PM by mjrenaud »

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #3 on: September 27, 2013, 02:09:00 PM »
Are you checking the PlotSetting ObjectId to make sure its actually pointing at something before trying to open it?

Code: [Select]
  item.Value.IsValid
Revit 2019, AMEP 2019 64bit Win 10

mjrenaud

  • Guest
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #4 on: September 27, 2013, 02:29:48 PM »
I just added that (thanks for the suggestion), but it made no difference.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #5 on: September 27, 2013, 03:08:54 PM »
Load a file up with plotsettings and someone could inspect it and maybe figure it out.

mjrenaud

  • Guest
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #6 on: September 27, 2013, 03:21:39 PM »
Here is one of the templates that I'm using.

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #7 on: September 27, 2013, 08:37:28 PM »
Took a moment to play with this, wrote some code and it works fine with your drawing file... vanilla autocad 2013

Code - C#: [Select]
  1.         [CommandMethod("TestPlotSettings")]
  2.         public void listPlotSettings()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             using (Transaction tr = doc.TransactionManager.StartTransaction())
  8.             {
  9.                 DBDictionary Settings = (DBDictionary)tr.GetObject(db.PlotSettingsDictionaryId, OpenMode.ForRead);
  10.                 foreach (DBDictionaryEntry PlotSetting in Settings)
  11.                 {
  12.                     try
  13.                     {
  14.                         ed.WriteMessage("\nPlot Style: {0}", PlotSetting.Key);
  15.                         PlotSettings ps = (PlotSettings)tr.GetObject(PlotSetting.Value, OpenMode.ForRead);
  16.                         ed.WriteMessage("\nDevice Name: {0}", ps.CanonicalMediaName);
  17.                     }
  18.                     catch (System.Exception e)
  19.                     {
  20.                         ed.WriteMessage("\n{0}", e.ToString());
  21.                     }
  22.                 }
  23.             }
  24.         }

Quote
Plot Style: Hp1055  (50%Di)
Device Name: User1637
Plot Style: Hp1055  (Ai)
Device Name: User612
Plot Style: Hp1055  (Bi)
Device Name: User1637
Plot Style: Hp1055  (Di)
Device Name: User1289
Plot Style: Hp1055  50%Di
Device Name: User1637
Plot Style: Hp1055  Ai
Device Name: User612
Plot Style: Hp1055  Bi
Device Name: User1637
Plot Style: Hp1055  Di
Device Name: User1289
Plot Style: Hp1055 (34in X 96in)
Device Name: User257
Plot Style: Hp1055 (Pipe Template)
Device Name: User257
Plot Style: Hp1055 34in X 96in
Device Name: User257
Plot Style: Hp5100 50%Di
Device Name: 11x17
Plot Style: Hp5100 Ai
Device Name: Letter
Plot Style: Hp5100 Bi
Device Name: 11x17
Plot Style: Hp5200 (50%Di)
Device Name: 11x17
Plot Style: Hp5200 (Ai)
Device Name: Letter
Plot Style: Hp5200 (Bi)
Device Name: 11x17
Plot Style: Hp5200 50%Di
Device Name: 11x17
Plot Style: Hp5200 Ai
Device Name: Letter
Plot Style: Hp5200 Bi
Device Name: 11x17
Plot Style: Hp5dn  50%Di  North
Device Name: 11x17
Plot Style: Hp5dn  Ai  North
Device Name: Letter
Plot Style: Hp5dn  Bi  North
Device Name: 11x17
Plot Style: LXM-W812  50%Di  South
Device Name: Tabloid
Plot Style: LXM-W812  Ai  South
Device Name: Letter
Plot Style: LXM-W812  Bi  South
Device Name: Tabloid
Plot Style: LXM-W812 (50%Di) South
Device Name: Tabloid
Plot Style: LXM-W812 (Ai) South
Device Name: Letter
Plot Style: LXM-W812 (Bi) South
Device Name: Tabloid
Plot Style: Oce (34in X 96in)
Device Name: UserDefinedImperial (34.00 x 96.00Inches)
Plot Style: Oce (50%Di)
Device Name: ANSI_expand_B__(17.00_x_11.00_Inches)
Plot Style: Oce (Ai)
Device Name: ANSI_expand_A_(11.00_x_8.50_Inches)
Plot Style: Oce (Bi)
Device Name: ANSI_expand_B__(17.00_x_11.00_Inches)
Plot Style: Oce (Di)
Device Name: ANSI_expand_D_(34.00_x_22.00_Inches)
Plot Style: Oce 34in X 96in
Device Name: UserDefinedImperial (34.00 x 96.00Inches)
Plot Style: Oce 50%Di
Device Name: ANSI_expand_D_(34.00_x_22.00_Inches)
Plot Style: Oce Ai
Device Name: ANSI_expand_A_(11.00_x_8.50_Inches)
Plot Style: Oce Bi
Device Name: ANSI_expand_B__(17.00_x_11.00_Inches)
Plot Style: Oce Di
Device Name: ANSI_expand_D_(34.00_x_22.00_Inches)

mjrenaud

  • Guest
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #8 on: September 28, 2013, 12:12:34 PM »
Thanks for this piece of code. It works very well, when you're in that dwg. I guess I wasn't very clear at the beginning... when I said that I was trying to read a Template file, I meant that I was trying to read a Template file from within another dwg. Sorry for the confusion on this.

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #9 on: September 28, 2013, 02:57:00 PM »
Strange, I'm having no issues doing what you're after.  Does this work on your machine?

Code - C#: [Select]
  1.         [CommandMethod("TestPlotSettings")]
  2.         public void listPlotSettings()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             using (Database db = new Database(false, false))
  7.             {
  8.                 db.ReadDwgFile(@"C:\Layouts Imperial.dwt", FileShare.Read, false, null);
  9.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  10.                 {
  11.                     DBDictionary Settings = (DBDictionary)tr.GetObject(db.PlotSettingsDictionaryId, OpenMode.ForRead);
  12.                     foreach (DBDictionaryEntry PlotSetting in Settings)
  13.                     {
  14.                         try
  15.                         {
  16.                             ed.WriteMessage("\nPlot Style: {0}", PlotSetting.Key);
  17.                             PlotSettings ps = (PlotSettings)tr.GetObject(PlotSetting.Value, OpenMode.ForRead);
  18.                             ed.WriteMessage("\nDevice Name: {0}", ps.CanonicalMediaName);
  19.                         }
  20.                         catch (System.Exception e)
  21.                         {
  22.                             ed.WriteMessage("\n{0}", e.ToString());
  23.                         }
  24.                     }
  25.                 }
  26.             }
  27.         }

mjrenaud

  • Guest
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #10 on: September 28, 2013, 03:23:05 PM »
Well, that did it! The only significant different was that I was using GetSourceDatabase() instead of ReadDwgFile().
Thanks very much for your help.

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #11 on: September 28, 2013, 07:07:14 PM »
There is no GetSourceDatabase function within the autocad API... are you referring to the method posted in this thread?

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #12 on: September 28, 2013, 07:45:54 PM »
Just because I can see some good use for this type of function I've done some playing, I'd love for somebody to critic this:

Code - C#: [Select]
  1.         [CommandMethod("TestPlotSettings")]
  2.         public void listPlotSettings()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             using (Transaction tr = db.TransactionManager.StartTransaction())
  8.             using (Database ndb = NewDatabase(@"C:\Layouts Imperial.dwt"))
  9.             {
  10.                 DBDictionary plotSettings = (DBDictionary)tr.GetObject(db.PlotSettingsDictionaryId, OpenMode.ForWrite);
  11.                 DBDictionary newPlotSettings = (DBDictionary)tr.GetObject(ndb.PlotSettingsDictionaryId, OpenMode.ForRead);
  12.                 foreach (DBDictionaryEntry newPlotSetting in newPlotSettings)
  13.                 {
  14.                     try
  15.                     {
  16.                         PlotSettings nps = (PlotSettings)tr.GetObject(newPlotSetting.Value, OpenMode.ForRead);
  17.                         PlotSettings ps;
  18.                         if (!plotSettings.Contains(newPlotSetting.Key))
  19.                         {
  20.                             ed.WriteMessage("\nImporting Plot Style: {0}", newPlotSetting.Key);
  21.                             ps = new PlotSettings(nps.ModelType);
  22.                             db.AddDBObject(ps);
  23.                             tr.AddNewlyCreatedDBObject(ps, true);
  24.                             plotSettings.SetAt(newPlotSetting.Key, ps);
  25.                         }
  26.                         else
  27.                         {
  28.                             ed.WriteMessage("\nUpdating Plot Style: {0}", newPlotSetting.Key);
  29.                             ps = (PlotSettings)tr.GetObject(plotSettings.GetAt(newPlotSetting.Key), OpenMode.ForWrite);
  30.                         }
  31.                         ps.CopyFrom(nps);
  32.                     }
  33.                     catch (System.Exception e)
  34.                     {
  35.                         ed.WriteMessage("\n{0}", e.ToString());
  36.                     }
  37.                 }
  38.                 tr.Commit();
  39.             }
  40.         }
  41.         private Database NewDatabase(string path)
  42.         {
  43.             Database db = new Database(false, false);
  44.             db.ReadDwgFile(path, FileShare.Read, false, null);
  45.             return db;
  46.         }

Chumplybum

  • Newt
  • Posts: 97
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #13 on: September 29, 2013, 06:41:21 PM »
Hi Will,

One thing I would add is db.CloseInput() after the db.readdwgfile in your NewDatabase function... see note 2, http://adndevblog.typepad.com/autocad/2012/07/using-readdwgfile-with-net-attachxref-or-objectarx-acdbattachxref.html


cheers, Mark

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #14 on: September 30, 2013, 01:58:14 PM »
I initially had, and usually do when I'm going to modify the side loaded database, but in this case where I was only grabbing a couple things out of the database it was much faster to do a lazy load by not asserting CloseInput. I had read that Fenton post long ago and my interpretation was that it's only important when you plan to modify the database. Do you know if this is actually setting up for any issues? 

Chumplybum

  • Newt
  • Posts: 97
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #15 on: September 30, 2013, 07:11:59 PM »
the only issue I can think of (although fairly remote) would be someone else trying to access the database at the same time either via code or the editor... this would cause a read access exception

Jeff H

  • Needs a day job
  • Posts: 6150
Re: eDwgObjectImproperlyRead when reading PlotSettings from a Template
« Reply #16 on: September 30, 2013, 08:58:18 PM »
Also take a look at Autodesk.AutoCAD.DatabaseServices.FileOpenMode Enumeration   
If OpenForReadAndAllShare is used   
the docs say
Quote
   Open for read and allow read and write sharing (same as _SH_DENYNO). Using this value withDatabase.ReadDwgFile() allows other applications full access to the file when the file is opened by this call. This call will open a file for reading when the same file is already opened for writing.
Using this mode with Database.ReadDwgFile() does not lock out other applications from writing to the file. It is not safe to do a lazy load in such circumstances. Performing a lazy load means that pieces of the drawing are read-in only as needed. This feature, combined with the possibility of other applications updating the drawing file under this mode, can cause inconsistent reads and other errors. So, when Database.ReadDwgFile()> is used with this mode, ReadDwgFile will call Database.CloseInput() in order to fully read in the file and release the file handle (i.e. no lazy load). without the call to CloseInput().