Author Topic: Wblock and saveas version  (Read 7680 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
Wblock and saveas version
« on: September 10, 2009, 11:47:24 AM »
I'm trying to force a wblock to saveas to 2004 as we have some software (cnc) that will not read a newer version.
The doc_CommandEnded event allows me to access the wblock end but gives no useful info as the database and doc are still those of the begin command.
Any ideas? (There is no commandline text showing the path of the wblock)

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #1 on: September 10, 2009, 04:54:02 PM »
Code: [Select]
static void db_WblockNotice(object sender, WblockNoticeEventArgs e)
        {
            Database wblockDb = e.To;
            doc.Editor.WriteMessage(wblockDb.Filename);
            doc.Editor.WriteMessage(wblockDb.OriginalFileName);
        }

The help for .To = Gets the database being written to.
however it prints the original dwg name.  So not getting any closer.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #2 on: September 14, 2009, 05:40:53 PM »
Just found out the above fires for copyclip.

Chumplybum

  • Newt
  • Posts: 97
Re: Wblock and saveas version
« Reply #3 on: September 14, 2009, 07:43:38 PM »
are you wblocking from the wblock command or via code???


Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #4 on: September 14, 2009, 07:48:44 PM »
I'm trying to the event db_WblockNotice to trap any wblock command with the intention of saving the drawing to an older version.
So the answer is wblock command.

Chumplybum

  • Newt
  • Posts: 97
Re: Wblock and saveas version
« Reply #5 on: September 14, 2009, 08:22:14 PM »
give this a go, it'll return the path to the newly created drawing file (it grabs the info from the registry, instead of the database)

Code: [Select]
        Private Sub db_WblockNotice(ByVal sender As Object, ByVal e As WblockNoticeEventArgs)

            Dim regkey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(Autodesk.AutoCAD.Runtime.SystemObjects.DynamicLinker.ProductKey)
            Dim wblockreg As Microsoft.Win32.RegistryKey = regkey.OpenSubKey("Profiles\Mark\Dialogs\write_block_dialog")

            MsgBox(wblockreg.GetValue("MRUPathListItem0"))

        End Sub

EDIT: sorry Bryco, i just notice that you'll need to put the name of the current profile in instead of my name under the opensubkey function

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #6 on: September 15, 2009, 05:02:11 PM »
That is exactly what I want Mark, thanks.

Still crashing trying to save it, however
Code: [Select]
       static void db_WblockNotice(object sender, WblockNoticeEventArgs e)
        {      
            Microsoft.Win32.RegistryKey regkey=Microsoft.Win32.Registry.CurrentUser.OpenSubKey
                (Autodesk.AutoCAD.Runtime.SystemObjects.DynamicLinker.ProductKey);
            Microsoft.Win32.RegistryKey  wblockreg=regkey.OpenSubKey
                (@"Profiles\" +acadApp.GetSystemVariable("Cprofile").ToString()+@"\Dialogs\write_block_dialog");        
            string sFile=wblockreg.GetValue("MRUPathListItem0").ToString();
           // MessageBox.Show(wblockreg.GetValue("MRUPathListItem0").ToString());
            Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
            using(Database wblockDatabase = new Database(false, true))
            {
                try
                {
                    wblockDatabase.ReadDwgFile(sFile, System.IO.FileShare.ReadWrite, true, null);

                    if (wblockDatabase != HostApplicationServices.WorkingDatabase)  
                        HostApplicationServices.WorkingDatabase = wblockDatabase;
                    wblockDatabase.SaveAs(sFile, DwgVersion.AC1800a);   //2004 final
                    //wblockDatabase.SaveAs(sFile, DwgVersion.AC1500);
                }
                catch (Autodesk.AutoCAD.Runtime.Exception acEx)
                {
                    ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, acEx.Message);
                    return;
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
                    return;
                }
                finally
                {
                }

            }          
        }

The error is eInvaliddrawingversion , however when I use "wblockDatabase.SaveAs(sFile, DwgVersion.Current);" there is no error reported and it crashes
« Last Edit: September 15, 2009, 05:06:35 PM by Bryco »

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #7 on: September 15, 2009, 06:07:40 PM »
These 2 lines cause the crash
if (wblockDatabase != HostApplicationServices.WorkingDatabase) 
           HostApplicationServices.WorkingDatabase = wblockDatabase;
but after commenting them out I still get the error.

I only just noticed that if you don't use the file selection box when  wblocking the new "wrote" dwg will be saved in the version that you have chosen in your saveas options, as soon as you browse it saves it to the same version of cad you are using. Bloody confusing when you are testing the code.

Chumplybum

  • Newt
  • Posts: 97
Re: Wblock and saveas version
« Reply #8 on: September 15, 2009, 07:00:32 PM »
i can see a few problems, unfortunately i don't have a solution at this stage....

there's no need to set the working database to the wblockdatabase, once you have a database object you can use the save/saveas function without setting it to the working database.... unless you've got another reason to set it to the working database?

the wblocknotice event gets fired during the 'wblocking', which at this point the new dwg file has not been created. put a stop on the readdwgfile line and then browse to the location of the newly created drawing and you'll see that its not there yet.


i've been trying to use the wblockended event but haven't been able to get the sub to run, here is the code so far:
Code: [Select]
        <CommandMethod("Test")> _
        Public Sub Test()

            AddHandler Application.DocumentManager.MdiActiveDocument.Database.WblockEnded, AddressOf db_WblockEnded

        End Sub

        Public Sub db_WblockEnded(ByVal sender As Object, ByVal e As System.EventArgs)

            Dim regkey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(Autodesk.AutoCAD.Runtime.SystemObjects.DynamicLinker.ProductKey)
            Dim wblockreg As Microsoft.Win32.RegistryKey = regkey.OpenSubKey("Profiles\Mark\Dialogs\write_block_dialog")
            Dim filename As String = wblockreg.GetValue("MRUPathListItem0")

            Using wblockdb As Database = New Database(False, True)
                Try
                    wblockdb.ReadDwgFile(filename, IO.FileShare.ReadWrite, False, Nothing)

                    If wblockdb.OriginalFileVersion <> DwgVersion.AC1800a Then wblockdb.SaveAs(filename, DwgVersion.AC1800a)

                Catch ex As Exception

                End Try
            End Using

        End Sub

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #9 on: September 15, 2009, 07:05:59 PM »
I couldn't get wblockended to do anything.
However I've been adding  the WblockNotice event  "doc.Database.WblockNotice +=new WblockNoticeEventHandler(db_WblockNotice);" from the begincommand which fires after the browsing has been done so timing wise seems ok.

Chumplybum

  • Newt
  • Posts: 97
Re: Wblock and saveas version
« Reply #10 on: September 15, 2009, 07:14:09 PM »
this seems to work now (using the command ended event), i have a feeling the problem is with the DwgVersion.AC1800a which i've changed to AC1800 and it seems to work

Code: [Select]
    Public Class Class1
        <CommandMethod("Test")> _
        Public Sub Test()

            AddHandler Application.DocumentManager.MdiActiveDocument.CommandEnded, AddressOf db_CommandEnded

        End Sub

        Public Sub db_CommandEnded(ByVal sender As Object, ByVal e As Autodesk.AutoCAD.ApplicationServices.CommandEventArgs)

            If String.Compare(e.GlobalCommandName, "WBLOCK", False) = 0 Then
                Dim regkey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(Autodesk.AutoCAD.Runtime.SystemObjects.DynamicLinker.ProductKey)
                Dim wblockreg As Microsoft.Win32.RegistryKey = regkey.OpenSubKey("Profiles\Mark\Dialogs\write_block_dialog")
                Dim filename As String = wblockreg.GetValue("MRUPathListItem0")

                Using wblockdb As Database = New Database(False, True)
                    Try
                        wblockdb.ReadDwgFile(filename, IO.FileShare.ReadWrite, False, Nothing)

                        If wblockdb.OriginalFileVersion <> DwgVersion.AC1800 Then wblockdb.SaveAs(filename, DwgVersion.AC1800)

                    Catch ex As Exception

                    End Try
                End Using
            End If

        End Sub
    End Class

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #11 on: September 15, 2009, 08:02:40 PM »
well done chumplybum. I'm not quite sure why this worked and the other didn't though.
I have just noticed that when you hit the browse button in the "Write Block" gui, the browse for drawing gui has a "Files of type" option at the bottom.
I could conceivably set that option instead, by code. But I've spent a long time on this already so another time.

Thanks again Mark

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #12 on: September 17, 2009, 04:09:49 PM »
Bryco,

I have some ideas, but I won't get to this until this weekend. Having said that, I would like some more information.

1. What ACAD version
2. What OS and SP
3. What Framework version and SP if any.
4. What Vis Stud version and SP if any.

If you have a look in the ARX group here, I asked if anybody could supply the 2010 version of ARXDBG (I haven't touched ARX in 5 years or so and as a consequence I'm very rusty) and Owen was kind enough to supply it.

This tool is extremely handy in diagnosing problems (along with DBVIEW), especially reactors.

From my brief look tonight, I have some suspicions. I'll explain more on the weekend once I've done some more testing. It might not come to anything, but I have some theories to try.

Cheers,
Glenn.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #13 on: September 17, 2009, 04:23:28 PM »
1) acad2010  using vanilla from acad mechanical
2)  xp pro sp 3
3)Microsoft Visual C# 2008 ver 3.5 sp1

I did play w/ below
Code: [Select]
//Microsoft.Win32.RegistryKey wblockreg = regkey.OpenSubKey
                                //(@"Profiles\" + acadApp.GetSystemVariable("Cprofile").ToString() + @"\Dialogs\BrowseforDrawingFileBlkDlg");
                                //This key set to 2 sets the dialogue box to saveas 2004  but cant get it to work
Perhaps if I did this once at every startup I wouldn't have to do it again. As I said above it's the file selection box that causes the problem.

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #14 on: September 17, 2009, 05:00:56 PM »
What I have in mind won't give a rats about the dialog selection, which is not a good way to go IMHO.

More on the weekend when I have time.

Have a good one.

Cheers,
Glenn.

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #15 on: September 23, 2009, 10:25:58 AM »
Give this a whirl. Proof of concept only. Usual warnings apply - add error traps etc. Will only work on current document, so you will have to plant events for all documents that are open and opened.

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace WblockTests
{
    public class Entrypoint : IExtensionApplication
    {
        #region Class vars

        Document currentDoc;
        Database currentDb, wblockedDb;
        Editor ed;

        bool wblockCommandStarted;

        #endregion

        #region IExtensionApplication Members

        public void Initialize()
        {
            // grab standarad things of interest
            currentDoc = acadApp.DocumentManager.MdiActiveDocument;
            currentDb = currentDoc.Database;
            ed = currentDoc.Editor;

            // plant doc events
            currentDoc.CommandWillStart += new CommandEventHandler(currentDoc_CommandWillStart);
            currentDoc.CommandCancelled += new CommandEventHandler(currentDoc_CommandCancelled);
            currentDoc.CommandEnded += new CommandEventHandler(currentDoc_CommandEnded);
            currentDoc.CommandFailed += new CommandEventHandler(currentDoc_CommandFailed);

            // plant database events
            Database.DatabaseConstructed += new EventHandler(Database_DatabaseConstructed);
        }

        void currentDoc_CommandFailed(object sender, CommandEventArgs e)
        {
            if (wblockCommandStarted)
                wblockCommandStarted = false;
        }

        void currentDoc_CommandEnded(object sender, CommandEventArgs e)
        {
            if (wblockCommandStarted)
                wblockCommandStarted = false;
        }

        void currentDoc_CommandCancelled(object sender, CommandEventArgs e)
        {
            if (wblockCommandStarted)
                wblockCommandStarted = false;
        }

        void Database_DatabaseConstructed(object sender, EventArgs e)
        {
            if (wblockCommandStarted)
            {
                wblockedDb = sender as Database;
                // plant some events for this wblocked dbase
                wblockedDb.SaveComplete += new DatabaseIOEventHandler(wblockedDb_SaveComplete);
            }
        }

        void wblockedDb_SaveComplete(object sender, DatabaseIOEventArgs e)
        {
            if (wblockCommandStarted)
            {
                if (wblockedDb.LastSavedAsVersion != DwgVersion.AC1800)
                {
                    wblockedDb.SaveAs(e.FileName, DwgVersion.AC1800);
                }
            }
        }

        void currentDoc_CommandWillStart(object sender, CommandEventArgs e)
        {
            if (e.GlobalCommandName == "WBLOCK")
            {
                wblockCommandStarted = true;
            }
        }

        public void Terminate()
        {
            // Nothing to see here - move along...
        }

        #endregion
    }
}

I think you will get the idea.

Cheers,
Glenn.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #16 on: September 23, 2009, 09:28:09 PM »
Glenn this looks pretty trick, I haven't had time to check it out yet but will do tomorrow. I like the way you made the new event handler.

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #17 on: September 24, 2009, 03:44:44 AM »
Thanks Bryco.

You could shorten what I previously posted, to this:

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace WblockTests
{
    public class Entrypoint : IExtensionApplication
    {
        #region Class vars

        Document currentDoc;
        Database currentDb, wblockedDb;
        Editor ed;

        bool wblockCommandStarted;

        #endregion

        #region IExtensionApplication Members

        public void Initialize()
        {
            // grab standarad things of interest
            currentDoc = acadApp.DocumentManager.MdiActiveDocument;
            currentDb = currentDoc.Database;
            ed = currentDoc.Editor;

            // plant doc events
            currentDoc.CommandWillStart += CommandStartedHandler;
            currentDoc.CommandCancelled += CommandTerminatedHandler;
            currentDoc.CommandEnded += CommandTerminatedHandler;
            currentDoc.CommandFailed += CommandTerminatedHandler;

            // plant database events
            Database.DatabaseConstructed += new EventHandler(Database_DatabaseConstructed);
        }

        void CommandTerminatedHandler(object sender, CommandEventArgs e)
        {
            if (wblockCommandStarted)
                wblockCommandStarted = false;
        }

        void Database_DatabaseConstructed(object sender, EventArgs e)
        {
            if (wblockCommandStarted)
            {
                wblockedDb = sender as Database;
                // plant some events for this wblocked dbase
                wblockedDb.SaveComplete += new DatabaseIOEventHandler(wblockedDb_SaveComplete);
            }
        }

        void wblockedDb_SaveComplete(object sender, DatabaseIOEventArgs e)
        {
            if (wblockCommandStarted)
            {
                if (wblockedDb.LastSavedAsVersion != DwgVersion.AC1800)
                {
                    wblockedDb.SaveAs(e.FileName, DwgVersion.AC1800);
                }
            }
        }

        void CommandStartedHandler(object sender, CommandEventArgs e)
        {
            if (e.GlobalCommandName == "WBLOCK")
            {
                wblockCommandStarted = true;
            }
        }

        public void Terminate()
        {
            // Nothing to see here - move along...
        }

        #endregion
    }
}

« Last Edit: September 24, 2009, 04:06:39 AM by Glenn R »

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #18 on: September 24, 2009, 03:49:18 AM »
Or...you could use anonymous methods... :evil:

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace WblockTests
{
    public class Entrypoint : IExtensionApplication
    {
        #region Class vars

        Document currentDoc;
        Database currentDb, wblockedDb;
        Editor ed;

        bool wblockCommandStarted;

        #endregion

        #region IExtensionApplication Members

        public void Initialize()
        {
            // grab standarad things of interest
            currentDoc = acadApp.DocumentManager.MdiActiveDocument;
            currentDb = currentDoc.Database;
            ed = currentDoc.Editor;

            // plant doc events
            currentDoc.CommandWillStart +=new CommandEventHandler(currentDoc_CommandWillStart);

            currentDoc.CommandCancelled += delegate(object sender, CommandEventArgs e)
            {
                if (wblockCommandStarted)
                    wblockCommandStarted = false;
            };

            currentDoc.CommandEnded += delegate(object sender, CommandEventArgs e)
            {
                if (wblockCommandStarted)
                    wblockCommandStarted = false;
            };

            currentDoc.CommandFailed += delegate(object sender, CommandEventArgs e)
            {
                if (wblockCommandStarted)
                    wblockCommandStarted = false;
            };

            // plant database events
            Database.DatabaseConstructed += new EventHandler(Database_DatabaseConstructed);
        }

        void Database_DatabaseConstructed(object sender, EventArgs e)
        {
            if (wblockCommandStarted)
            {
                wblockedDb = sender as Database;
                // plant some events for this wblocked dbase
                wblockedDb.SaveComplete += new DatabaseIOEventHandler(wblockedDb_SaveComplete);
            }
        }

        void wblockedDb_SaveComplete(object sender, DatabaseIOEventArgs e)
        {
            if (wblockCommandStarted)
            {
                if (wblockedDb.LastSavedAsVersion != DwgVersion.AC1800)
                {
                    wblockedDb.SaveAs(e.FileName, DwgVersion.AC1800);
                }
            }
        }

        void currentDoc_CommandWillStart(object sender, CommandEventArgs e)
        {
            if (e.GlobalCommandName == "WBLOCK")
            {
                wblockCommandStarted = true;
            }
        }

        public void Terminate()
        {
            // Nothing to see here - move along...
        }

        #endregion
    }
}
« Last Edit: September 24, 2009, 04:05:17 AM by Glenn R »

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #19 on: September 24, 2009, 04:18:20 AM »
Or...a combination of the 2  :lmao:  :evil:

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace WblockTests
{
    public class Entrypoint : IExtensionApplication
    {
        #region Class vars

        Document currentDoc;
        Database currentDb, wblockedDb;
        Editor ed;

        bool wblockCommandStarted;

        #endregion

        #region IExtensionApplication Members

        public void Initialize()
        {
            // grab standarad things of interest
            currentDoc = acadApp.DocumentManager.MdiActiveDocument;
            currentDb = currentDoc.Database;
            ed = currentDoc.Editor;

            // plant doc events
            currentDoc.CommandCancelled += CommandTerminatedHandler;
            currentDoc.CommandEnded += CommandTerminatedHandler;
            currentDoc.CommandFailed += CommandTerminatedHandler;

            currentDoc.CommandWillStart += delegate(object sender, CommandEventArgs e)
            {
                if (e.GlobalCommandName.TrimStart('+', '-') == "WBLOCK")
                {
                    wblockCommandStarted = true;
                }
            };

            // plant database events
            Database.DatabaseConstructed += delegate(object sender, EventArgs e)
            {
                if (wblockCommandStarted)
                {
                    wblockedDb = sender as Database;
                    wblockedDb.SaveComplete += delegate(object senderDb, DatabaseIOEventArgs eDb)
                    {
                        if (wblockCommandStarted)
                        {
                            if (wblockedDb.LastSavedAsVersion != DwgVersion.AC1800)
                            {
                                wblockedDb.SaveAs(eDb.FileName, DwgVersion.AC1800);
                            }
                        }
                    };
                }
            };
        }

        void CommandTerminatedHandler(object sender, CommandEventArgs e)
        {
            if (wblockCommandStarted)
                wblockCommandStarted = false;
        }

        public void Terminate()
        {
            // Nothing to see here - move along...
        }

        #endregion
    }
}

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #20 on: September 24, 2009, 09:30:49 AM »
Glenn it works great but I noticed you dont have a
wblockedDb.SaveComplete -= new DatabaseIOEventHandler(wblockedDb_SaveComplete);
Do you need one?
Also it runs wblockedDb.SaveAs(e.FileName, DwgVersion.AC1800); Perhaps changing the version refires the event, I see no problem with this, just trying to get a better understanding.

Glenn R

  • Guest
Re: Wblock and saveas version
« Reply #21 on: September 24, 2009, 09:38:16 AM »
Glenn it works great but I noticed you dont have a
wblockedDb.SaveComplete -= new DatabaseIOEventHandler(wblockedDb_SaveComplete);
Do you need one?

I used to put those in, especially when Acad was shutting down (docs closing etc.) but I found it can cause troubles, which TonyT confirmed, so now I generally don't. As the Dbase that you're attaching the event to is temporary anyway, it gets destroyed very quickly and I don't see the harm in it for this.

If you want to put one in, you will need to remove it BEFORE the dbase is destroyed.

Also it runs wblockedDb.SaveAs(e.FileName, DwgVersion.AC1800); Perhaps changing the version refires the event, I see no problem with this, just trying to get a better understanding.

You're correct - the SaveAs definitely re-fires the event. Normally, you would stop event re-entry by using some sort of flag - right? In this case, the 'flag' is the 'if' statement testing for the version.

If you've detected and re-saved the dbase already, it's already in the correct format, so the conditional test will fail. Does that explain it?

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Wblock and saveas version
« Reply #22 on: September 24, 2009, 10:55:58 AM »
Yes,good reply.