Author Topic: Pre-audit audit  (Read 4237 times)

0 Members and 1 Guest are viewing this topic.

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Pre-audit audit
« on: February 15, 2007, 12:08:40 PM »
I am processing a number of drawings.
I know there is a way in .NET to Audit a database once it is open.
However, with a corrupt drawing I can't open it in order to audit it. The code causes AutoCAD to crash with a message like:
INTERNAL ERROR: !dbobji.cpp@6601: eNotOpenForWrite

Makes sense to me, database didn't open because the drawing was bad.

Does anyone know of a quick, low-overhead way to validate a drawing before trying to work with it?
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Pre-audit audit
« Reply #1 on: June 04, 2008, 06:04:50 PM »
I never did find a solution.
Opendwg (DWGDirectX) now has a recoverfile method but I still don't see a pre-open audit solution.

Any new thoughts?
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8790
  • AKA Daniel
Re: Pre-audit audit
« Reply #2 on: June 05, 2008, 02:06:23 PM »
How about something like

Code: [Select]
public class Commands
  {
    [CommandMethod("doit")]
    public static void doit()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      string path = "c:\\LP04795.dwg";
      ed.WriteMessage(TestDb(path).ToString());
    }


    public static bool TestDb(string path)
    {
      Database db = new Database();
      bool returnFlag = false;
      try
      {
        db.ReadDwgFile(path, FileShare.ReadWrite, false, string.Empty);
        returnFlag = true;
      }
      catch
      {
        returnFlag = false;
      }
      finally
      {
        db.CloseInput(true);
        db.Dispose();
      }
      return returnFlag;
    }
  }

Glenn R

  • Guest
Re: Pre-audit audit
« Reply #3 on: June 05, 2008, 04:45:38 PM »
I never did find a solution.
Opendwg (DWGDirectX) now has a recoverfile method but I still don't see a pre-open audit solution.

Any new thoughts?

Nor will you - cart before horse springs to mind.

Dan's example is probably the best you can hope for, but still requires a read, which any validation would do, including 'audit', so back to square one.

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Pre-audit audit
« Reply #4 on: June 05, 2008, 04:59:34 PM »
I never did find a solution.
Opendwg (DWGDirectX) now has a recoverfile method but I still don't see a pre-open audit solution.

Any new thoughts?

Nor will you - cart before horse springs to mind.

Dan's example is probably the best you can hope for, but still requires a read, which any validation would do, including 'audit', so back to square one.

And yet, AutoCAD has the ability to begin reading, detect a problem, present us an option (Cancel or Ignore), and continue on. In fact if we answer Yes to the "Would you like to cancel the open?" dialog AutoCAD exits gracefully without "opening" the drawing or hitting us with a fatal error.

Daniel, Thanks for the suggestion. Tried it but readdwgfile does not throw an error on my bad file. Documents.Open does.

Opendwg, (OpenDesign Alliance) used to have a "Drawing Sniffer" and a method called dwgSmellsBad.

I want something like:
if (Application.DwgIsCorrupt(myDrawingPath))
{
    Document myDoc = Application.RecoverDrawing(myDrawingPath);
    // do stuff to it
}
else
{
    // report bad drawing to user
}
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

Glenn R

  • Guest
Re: Pre-audit audit
« Reply #5 on: June 05, 2008, 05:03:57 PM »
Yeah, but I think the kicker here, is that, AutoCAD is opening the dbase in a 'Document' ie a valid window with graphics in the AutoCAD editor, whereas with ReadDwgFile, you typically pass false to NOT associate it with any document, as you're just reading it into memory.

Glenn R

  • Guest
Re: Pre-audit audit
« Reply #6 on: June 05, 2008, 05:09:57 PM »
Sorry, scratch that last post - I was thinking of the second argument to the AcDbDatabase constructor to associate the dbase with the current document.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Pre-audit audit
« Reply #7 on: June 05, 2008, 05:51:59 PM »
Have you tried the Audit method on the database that is opened by ReadDwgFile?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Pre-audit audit
« Reply #8 on: June 05, 2008, 07:10:27 PM »
Have you tried the Audit method on the database that is opened by ReadDwgFile?

I tried to figure out how to do that but got lost.
Problem 1. Audit returns void. I need to get a result to examine. I need an AuditInfo object.
Problem 2. You have to pass the Audit method an AuditInfo object which has no constructor so I can't make one to pass.

Has anyone been able to get information from Audit? Point me in the right direction.
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Pre-audit audit
« Reply #9 on: June 05, 2008, 07:20:33 PM »
Ah....  The Arx docs for '06 says it's not implemented yet, so I'm not sure if it is in other releases....

wait I got the docs for '08.. let me check.


Nope, still a no go in '08.  Not sure how to do it then... sorry.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8790
  • AKA Daniel
Re: Pre-audit audit
« Reply #10 on: June 05, 2008, 08:57:39 PM »
The only thing I can think of is try opening stuff up,
i.e

 
Code: [Select]
public static bool TestDb(string path)
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      Database db = new Database();
      bool returnFlag = false;
      try
      {
        db.ReadDwgFile(path, FileShare.ReadWrite, false, string.Empty);
        AcDb.TransactionManager Tm = db.TransactionManager;

        using (Transaction tr = Tm.StartTransaction())
        {
         
          BlockTable tb = (BlockTable)tr.GetObject
                       (db.BlockTableId, OpenMode.ForRead, false);

          BlockTableRecord btr = (BlockTableRecord)tr.GetObject
                       (tb[BlockTableRecord.ModelSpace], OpenMode.ForRead, false);

          BlockTableRecord btrp = (BlockTableRecord)tr.GetObject
                       (tb[BlockTableRecord.PaperSpace], OpenMode.ForRead, false);

          tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead, false);
          tr.GetObject(db.LayerTableId, OpenMode.ForRead, false);
          tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead, false);
          tr.GetObject(db.ViewportTableId, OpenMode.ForRead, false);
          tr.GetObject(db.ViewTableId, OpenMode.ForRead, false);
        }

        returnFlag = true;
      }
      catch(SystemException ex)
      {
        ed.WriteMessage(ex.Message);
        returnFlag = false;
      }
      finally
      {
        db.CloseInput(true);
        db.Dispose();
      }
      return returnFlag;
    }