Author Topic: eWasOpenForWrite  (Read 10202 times)

0 Members and 1 Guest are viewing this topic.

cadpro

  • Guest
eWasOpenForWrite
« on: April 07, 2008, 01:29:17 AM »
Hi,

I have some code that works fine. But after I run an AutoCAD command, the code will not work. I get the error 'eWasOpenForWrite'. The reason could be, that AutoCAD has opened the drawing database for write, but did not close. What can be done in my code to tackle this problem?

Thanks

sinc

  • Guest
Re: eWasOpenForWrite
« Reply #1 on: April 07, 2008, 01:50:55 AM »
It's difficult to offer any advice, based on the information you've given.

However, the issue is most-likely caused by something in your code, and not Autodesk's, although it could go either way.  The best bet is to track it down in the debugger.  Or post some code here, and someone might be able to tell you what's causing the error.

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #2 on: April 07, 2008, 03:13:22 AM »
I cannot debug as I'm using the Express Edition of VS 2008. I'd rather post the code.

Public Sub BX()
        Dim bTransMan As DatabaseServices.TransactionManager
        Dim bTrans As DatabaseServices.Transaction
        Dim bDwg As Document
        Dim bBT As BlockTable

        Dim bBTR As SymbolTableRecord
        Dim bBTE As SymbolTableEnumerator
        Dim bBTRr As BlockTableRecord

        'Current Document
        bDwg = Application.DocumentManager.MdiActiveDocument
        bTransMan = bDwg.TransactionManager

        bTrans = bTransMan.StartTransaction
        Try
            'Open the database for Read
            bBT = bDwg.Database.BlockTableId.GetObject(OpenMode.ForRead)
            bBTE = bBT.GetEnumerator

            Dim XrefIds As New ObjectIdCollection
            Dim DetXIds As New ObjectIdCollection
            Dim DetXId As New ObjectId
            Dim ReXIds As New ObjectIdCollection
            Dim graphXref As XrefGraph
            Dim nodeXref As XrefGraphNode
            Dim btrId As Object

            graphXref = bDwg.Database.GetHostDwgXrefGraph(True)
            For idx As Integer = 1 To graphXref.NumNodes - 1
                nodeXref = graphXref.GetXrefNode(idx)
                If nodeXref.IsNested Then
                    Select Case nodeXref.XrefStatus
                        Case XrefStatus.FileNotFound
                            btrId = nodeXref.BlockTableRecordId
                            Dim BTR As BlockTableRecord = bTrans.GetObject(btrId, OpenMode.ForWrite)
                            BTR.PathName = "C:\1.dwg"
                            ReXIds.Add(BTR.Id)
                        Case XrefStatus.Unreferenced
                            btrId = nodeXref.BlockTableRecordId
                            Dim BTR As BlockTableRecord = bTrans.GetObject(btrId, OpenMode.ForWrite)
                            BTR.PathName = "C:\1.dwg"
                            ReXIds.Add(BTR.Id)
                        Case XrefStatus.Unloaded
                            btrId = nodeXref.BlockTableRecordId
                            Dim BTR As BlockTableRecord = bTrans.GetObject(btrId, OpenMode.ForWrite)
                            BTR.PathName = "C:\1.dwg"
                            ReXIds.Add(BTR.Id)
                        Case XrefStatus.Unresolved
                            btrId = nodeXref.BlockTableRecordId
                            Dim BTR As BlockTableRecord = bTrans.GetObject(btrId, OpenMode.ForWrite)
                            BTR.PathName = "C:\1.dwg"
                            ReXIds.Add(BTR.Id)
                    End Select
                End If
            Next

            If ReXIds.Count > 0 Then
                bDwg.Database.ReloadXrefs(ReXIds)
            End If

            While bBTE.MoveNext = True
                bBTR = bBTE.Current.GetObject(OpenMode.ForRead)
                bBTRr = CType(bBTR, BlockTableRecord)

                'Check if block is xref and also resolved and then add its ID to the ObjectIdCollection
                If bBTRr.IsFromExternalReference Then
                    Select Case bBTRr.XrefStatus
                        Case XrefStatus.Resolved
                            XrefIds.Add(bBTRr.Id)
                        Case XrefStatus.Unloaded
                            DetXIds.Add(bBTRr.Id)
                        Case XrefStatus.FileNotFound
                            DetXIds.Add(bBTRr.Id)
                        Case XrefStatus.Unreferenced
                            DetXIds.Add(bBTRr.Id)
                        Case XrefStatus.Unresolved
                            DetXIds.Add(bBTRr.Id)
                    End Select
                End If

            End While

            'Bind xref of collection
            Try
                'We bind all xrefs of drawing
                If XrefIds.Count > 0 Then
                    bDwg.Database.BindXrefs(XrefIds, False)
                End If

                For Each DetXId In DetXIds
                    bDwg.Database.DetachXref(DetXId)
                Next

            Catch ex As Exception
                MsgBox("Error2: " & ex.Message)  <-----------------The error displayed is from here.
            End Try

            bTrans.Commit()

        Catch ex As Exception
            MsgBox("Error1: " & ex.Message)
        Finally
            If Not bTrans.IsDisposed Then
                bTrans.Dispose()
                bTransMan.Dispose()
            End If
        End Try

    End Sub

Thanks

sinc

  • Guest
Re: eWasOpenForWrite
« Reply #3 on: April 07, 2008, 12:28:14 PM »
You can debug using VS Express, you just need to setup your csproj.user file manually.

I'm including mine as a sample.  It's in a .zip file, because the Swamp will not allow me to post a .csproj.user file.

Glenn R

  • Guest
Re: eWasOpenForWrite
« Reply #4 on: April 07, 2008, 03:52:40 PM »
Still trying to bind xrefs huh?  :evil:

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #5 on: April 08, 2008, 12:50:10 AM »
Still trying to bind xrefs huh?  :evil:

 :-D Had a break.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: eWasOpenForWrite
« Reply #6 on: April 08, 2008, 02:12:58 AM »
You can debug using VS Express, you just need to setup your csproj.user file manually.

< .. >

I thought there was a thread about it here at TheSwamp ...

aside .. just for interest
why do (some of) the variables start with b.. ?
and does VB have a foreach keyword ? .. in place of using the SymbolTableEnumerator  .. or is the enumerator more efficient ?
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.

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #7 on: April 08, 2008, 04:20:33 AM »
Kerry,

I did get the debug thing to work. It's fantastic!

I got the code from Autodesk discussion group posted by bertyboy. I did some modifications and that's what it is. Thanks to bertyboy.

I added the foreach section. Yes, VB does have foreach and that has no issues so far. The problem is only with BindXrefs() function, that too after the scalelist command is executed.

Thanks

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: eWasOpenForWrite
« Reply #8 on: April 08, 2008, 04:30:17 AM »
yes, I just noticed the thread in the autodesk.autocad.customization.dotnet newsgroup.
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.

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #9 on: April 08, 2008, 06:29:06 AM »
I know there is some trick to close any open object. But don't know where and how it applies to this code. I'm not an expert, but looking into the behaviour of the working, I think the xref is opened to scalelistedit and Autocad is not closing it. That could be the reason why it all happens. What can be done to close any open object before doing any changes to it?

Draftek

  • Guest
Re: eWasOpenForWrite
« Reply #10 on: April 08, 2008, 08:13:22 AM »
I just noticed this, we batch thru all our drawings and bind all xrefs before burning to dvd's.

Here is the method in C# which has worked for us:

Code: [Select]
static public void bindAllXrefs()
        {
            try
            {
                Document pCurDoc = AcadApp.DocumentManager.MdiActiveDocument;
                Database pCurDb = pCurDoc.Database;

                Editor pEd = pCurDoc.Editor;

                //**********
                Document curDoc = AcadApp.DocumentManager.MdiActiveDocument;
                curDoc.LockDocument();
                //**********

                XrefGraph pXrefGraph = pCurDb.GetHostDwgXrefGraph(true);
                if (pXrefGraph.IsEmpty || pXrefGraph.NumNodes == 1)
                {
                    pEd.WriteMessage("\nNo Xrefs found. ");
                    return;
                }
                using (Transaction pTr = pCurDoc.TransactionManager.StartTransaction())
                {
                    BlockTable pBlkTbl = (BlockTable)pTr.GetObject(pCurDb.BlockTableId, OpenMode.ForWrite);
                   
                    for (int i = 0; i < pXrefGraph.NumNodes; i++)
                    {
                        XrefGraphNode pXrefGraphNode = (XrefGraphNode)pXrefGraph.GetXrefNode(i);
                        if (pXrefGraphNode.NumIn == 0)
                            continue;
                        if (pXrefGraphNode.IsNested)
                            continue;
                        if (pXrefGraphNode.NumIn > 1)
                            continue;

                        pEd.WriteMessage("\nXrefname: " + pXrefGraphNode.Name);
                        pEd.WriteMessage("\nNested Status: " + pXrefGraphNode.IsNested.ToString());
                        pEd.WriteMessage("\nIncoming Nodes: " + pXrefGraphNode.NumIn.ToString());
                        pEd.WriteMessage("\nOutgoing Nodes: " + pXrefGraphNode.NumOut.ToString());

                        EFCO.Util.XrefLib.Wrapper.acedXrefBind(pXrefGraphNode.Name, true, true, pCurDb);
                    }
                    pTr.Commit();
                    pEd.WriteMessage("\nEFCO BIND PROCESS COMPLETE. ");
                }
            }
            catch { }
        }

I don't have time to parse your code but maybe something will stick out for you.

visualassembly

  • Guest
Re: eWasOpenForWrite
« Reply #11 on: April 08, 2008, 08:51:11 AM »
Hmmm... that looks a little familiar. 

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #12 on: April 08, 2008, 09:07:01 AM »
Draftek,

Thanks for the code. But what is EFCO? I'm studying your code, but I didn't understand this line

EFCO.Util.XrefLib.Wrapper.acedXrefBind(pXrefGraphNode.Name, true, true, pCurDb).

Thanks

visualassembly

  • Guest
Re: eWasOpenForWrite
« Reply #13 on: April 08, 2008, 09:15:05 AM »
Draftek,

Thanks for the code. But what is EFCO? I'm studying your code, but I didn't understand this line

EFCO.Util.XrefLib.Wrapper.acedXrefBind(pXrefGraphNode.Name, true, true, pCurDb).

Thanks

EFCO is the company we worked for, so our namespaces were EFCO.Util.Whatever.  This particular class was a wrapper for the dll import call if I remember correctly.

Draftek

  • Guest
Re: eWasOpenForWrite
« Reply #14 on: April 08, 2008, 09:18:02 AM »
Good memory:
Change the call to this method. We did some version checking..

Code: [Select]
        // For AutoCAD 2007:
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode,
           EntryPoint = "?acedXrefBind@@YA?AW4ErrorStatus@Acad@@PB_W_N1PAVAcDbDatabase@@@Z")]

        extern public static Autodesk.AutoCAD.Runtime.ErrorStatus acedXrefBind17(string XrefBlockname, bool bInsertBind, bool bQuiet, IntPtr db);

Glenn R

  • Guest
Re: eWasOpenForWrite
« Reply #15 on: April 08, 2008, 02:16:34 PM »
I just noticed this, we batch thru all our drawings and bind all xrefs before burning to dvd's.

Here is the method in C# which has worked for us:

Code: [Select]
static public void bindAllXrefs()
        {
            try
            {
                Document pCurDoc = AcadApp.DocumentManager.MdiActiveDocument;
                Database pCurDb = pCurDoc.Database;

                Editor pEd = pCurDoc.Editor;

                //**********
                Document curDoc = AcadApp.DocumentManager.MdiActiveDocument;
                curDoc.LockDocument();
                //**********

                XrefGraph pXrefGraph = pCurDb.GetHostDwgXrefGraph(true);
                if (pXrefGraph.IsEmpty || pXrefGraph.NumNodes == 1)
                {
                    pEd.WriteMessage("\nNo Xrefs found. ");
                    return;
                }
                using (Transaction pTr = pCurDoc.TransactionManager.StartTransaction())
                {
                    BlockTable pBlkTbl = (BlockTable)pTr.GetObject(pCurDb.BlockTableId, OpenMode.ForWrite);
                   
                    for (int i = 0; i < pXrefGraph.NumNodes; i++)
                    {
                        XrefGraphNode pXrefGraphNode = (XrefGraphNode)pXrefGraph.GetXrefNode(i);
                        if (pXrefGraphNode.NumIn == 0)
                            continue;
                        if (pXrefGraphNode.IsNested)
                            continue;
                        if (pXrefGraphNode.NumIn > 1)
                            continue;

                        pEd.WriteMessage("\nXrefname: " + pXrefGraphNode.Name);
                        pEd.WriteMessage("\nNested Status: " + pXrefGraphNode.IsNested.ToString());
                        pEd.WriteMessage("\nIncoming Nodes: " + pXrefGraphNode.NumIn.ToString());
                        pEd.WriteMessage("\nOutgoing Nodes: " + pXrefGraphNode.NumOut.ToString());

                        EFCO.Util.XrefLib.Wrapper.acedXrefBind(pXrefGraphNode.Name, true, true, pCurDb);
                    }
                    pTr.Commit();
                    pEd.WriteMessage("\nEFCO BIND PROCESS COMPLETE. ");
                }
            }
            catch { }
        }

I don't have time to parse your code but maybe something will stick out for you.

That code looks more than just familiar...

Draftek

  • Guest
Re: eWasOpenForWrite
« Reply #16 on: April 08, 2008, 03:54:25 PM »
Oh Really!

Fill me in.

visualassembly 'wrote' this for me a while back when he worked for me.

Glenn R

  • Guest
Re: eWasOpenForWrite
« Reply #17 on: April 08, 2008, 04:02:19 PM »
Linkage

Notice the variable naming convention I was using at the time (habbit from my C++ days), prefixing object variables with 'p' for 'pointer'...

visualassembly

  • Guest
Re: eWasOpenForWrite
« Reply #18 on: April 08, 2008, 04:36:13 PM »
That's where I got that from!   :roll:

Now where did I get the dll import from......  I think I swiped that part from Acad's own forums.

Thanks for the help Glenn.  Even if it is really late.  This was part of the very first ACAD app I got to write.  It was (and I'm assuming, still is) used for batching through our 28,000+ dwg library to bind the xrefs, zoom extents the dwg's, toggle layers off and on, batch plot jpg's (in two sizes), pdf's, and made coffee all the same time.   Ahhh... memories.


Draftek

  • Guest
Re: eWasOpenForWrite
« Reply #19 on: April 09, 2008, 08:03:16 AM »
well, I see I even posted in that thread. I probably even directed visualassembly here to check it out.

I typically will not copy code of any kind (stubborn that way).

I'll have the new guy add you to the comments.

Glenn - I wonder how much other stuff you have written for me - Thanks :)


cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #20 on: April 10, 2008, 01:26:27 AM »
I do not have objectarx as I'm using VS Express 2008. So I got the arx function to work in .NET by reading Kean's website.

I get two of these for acedXrefBind. Which one would be correct to pick?

Dump of file acad.exe
        682  298 003FEFA0 ?acedXrefBind@@YA?AW4ErrorStatus@Acad@@PB_W_N1IPAVAcDbDatabase@@@Z
        683  299 003FF220 ?acedXrefBind@@YA?AW4ErrorStatus@Acad@@PB_W_N1PAVAcDbDatabase@@@Z

BTW, I have Autocad 2008.

Thanks

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: eWasOpenForWrite
« Reply #21 on: April 10, 2008, 04:32:19 AM »
        // For AutoCAD 2008, 2007:
    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode,
      EntryPoint = " ?acedXrefBind@@YA?AW4ErrorStatus@Acad@@PB_W_N1PAVAcDbDatabase@@@Z")]   
    extern public static ErrorStatus acedXrefBind17(string XrefBlockname, bool bInsertBind, bool bQuiet, IntPtr db);
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.

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #22 on: April 10, 2008, 07:37:21 AM »
Thanks Kerry. I got it to work.

After some digging and researching with different method of coding, I understand that after I run the scalelistedit command to reset the list, if there are any xxx_XREF scales from one particular dwg, ONLY that dwg won't bind with the code. This means that AutoCAD does not close the xref dwg database after it resets the scales. Correct me if I'm wrong.

Thanks 

cadpro

  • Guest
Re: eWasOpenForWrite
« Reply #23 on: April 10, 2008, 07:55:31 AM »
Oh! One more discovery! It doesn't even bind manually after resetting scalelist.  :-o

MickD

  • King Gator
  • Posts: 3647
  • (x-in)->[process]->(y-out) ... simples!
Re: eWasOpenForWrite
« Reply #24 on: November 02, 2009, 05:30:33 PM »
Anyone found a solution to the original problem yet?

I've only had it happen with 3d solids and it's because of the 'solidhist' variable that records any modifications and stores them for backtracking, this only came in in 2008/9 I think.

The way I get around it is to set SOLIDHIST to 0 (off) and run the BREP command selecting all which clears any history, once this is done the drg behaves as normal.

If you rely on the solid's history then you may need to check 'isOpenForWrite' and do some mojo to get around it.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien