Author Topic: MdiActiveDocument is null  (Read 3701 times)

0 Members and 1 Guest are viewing this topic.

sling blade

  • Guest
MdiActiveDocument is null
« on: February 13, 2015, 09:49:42 PM »
With my code I access the MdiActiveDocument's database from the DocumentManager .
Using the database I start a transaction and use the GetObject method of the transaction to retrieve Entity objects.
 
Code: [Select]
Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
var obj = acTrans.GetObject(id, OpenMode.ForRead);
if (obj is Entity)
{
// do stuff
}
acTrans.Commit();
}

 
 
This works fine while I am in development and start AutoCAD from inside of Visual Studio. In development I set the "Start external program" switch in the Debug tab of the application properties so it starts AutoCAD for me and everything works great.
 
The issue I am having is that in production when the app is loaded by AutoCAD via registry settings (I use demand loading) the MdiActiveDocument is null so the code crashes. I have discovered there is a document in the Application.DocumentManager but when I assign the database from that document to acCurDb the TransactionManager throws an error with I try to use the StartTransaction method.
 
Code: [Select]
if (Application.DocumentManager.Count > 0)
{
foreach(Document doc in Application.DocumentManager)
{
acCurDb = doc.Database;
break;
}
}
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
}

 
Can someone help me understand why the MdiActiveDocument is null and/or direct me to the proper way to get a Transaction object in AutoCAD?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: MdiActiveDocument is null
« Reply #1 on: February 13, 2015, 10:18:40 PM »
I don't have time to play, but does this help ?
http://www.theswamp.org/index.php?topic=6358.0
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.

sling blade

  • Guest
Re: MdiActiveDocument is null
« Reply #2 on: February 13, 2015, 10:46:17 PM »
Hi,

Sorry didn't work.

I put the full namespace path in and I have the same results.

owenwengerd

  • Bull Frog
  • Posts: 451
Re: MdiActiveDocument is null
« Reply #3 on: February 13, 2015, 11:01:45 PM »
MdiActiveDocument will be null when there is no active document, which would be the case during startup, while the active document is changing, or when AutoCAD is in a zero-document state. Your code should handle that possibility gracefully, and not try to access a non-existent or not-yet-initialized document. I think it would be useful if you explain the context in which your code is executing and why you're trying to obtain a transaction in the first place. Perhaps someone can recommend a more robust solution.

sling blade

  • Guest
Re: MdiActiveDocument is null
« Reply #4 on: February 13, 2015, 11:27:13 PM »
What i am doing is I've create a class similar to the example DocManEvents class located in the “ObjectARX 2015\samples\dotNet\EventsWatcher” directory to hook to the drawing events I am interested in.  I call a command to turn the listeners on and a command to turn them off. Having the commands turn on and off works well in development and test. But for some reason in test where I open AutoCAD "by hand" and I have opened a drawing the MdiActiveDocument is null.

I can easily test for null in the MdiActiveDocument but at the moment all I am forced to do is quit, but as I am listening for Db events and I cannot afford to miss one this is not going to work in my case. Is there a way of dealing with this so I get the MdiActiveDocument loaded or maybe there is some other known way around this and get a Transaction object?
« Last Edit: February 14, 2015, 04:22:04 AM by sling blade »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: MdiActiveDocument is null
« Reply #5 on: February 14, 2015, 02:29:08 AM »
How (and when) are you netloading the application ?
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.

BlackBox

  • King Gator
  • Posts: 3770
Re: MdiActiveDocument is null
« Reply #6 on: February 14, 2015, 03:37:53 AM »
By definition, one cannot act on a given Document's Database, without a valid Document (or opening as a side database). Thus, to use code logic to test for:

Code - C#: [Select]
  1. // ...
  2. if (<MdiActiveDocument> == null)
  3.   Return;
  4.  
  5. // <-- do something useful
  6.  
  7. // ...
  8.  

Anytime MdiActiveDocument is not null, you will be able to query the Document's Database. Anytime it is null, there is no Document, nor any Database to query, precluding an Exception from being raised by your code.

Also, you may want to familiarize yourself with the new non-DWG Documents as well.

Cheers
"How we think determines what we do, and what we do determines what we get."

sling blade

  • Guest
Re: MdiActiveDocument is null
« Reply #7 on: February 14, 2015, 04:10:44 AM »
@Kerry I am demand loading the commands through the registry.

Key MyApp
    DESCRIPTION    MyApp Desription
    LOADCTRLS       000X00000000c(12)
    LOADER              Path\to\app.dll
    MANAGED           0X0000000001 (1)

     Key Commands
            WatchDbEvents         WatchDbEvents
            UnWatchDbEvents    UnWatchDbEvents

When I start typing at the command line my command appears in the list and I have a logger that lets me know that when I activate the command everything is acting just like it does when I am in development. Except of course when it tries to access the MdiActiveDocument.
« Last Edit: February 14, 2015, 04:15:34 AM by sling blade »

sling blade

  • Guest
Re: MdiActiveDocument is null
« Reply #8 on: February 14, 2015, 04:26:51 AM »
@Blackbox Cheers mate thanks for responding.

Where I am stumped is that I need a transaction object or some way of querying the database so I can retrieve entities via their object id. The way I am doing it works great when I use Visual Studio to open AutoCAD but when I test the same code by opening AutoCAD myself (i.e. I double click the icon on my desktop) the MdiActiveDocument is null. BTW using both methods to open AutoCAD (Visual Studio and manually) I always open the same test drawing. So I am at a loss at to why the MdiActiveDocument would be null.

I am not expert enough to know how to get around this problem or even guess what is actually causing this.

Thanks for your help.
« Last Edit: February 14, 2015, 04:50:03 AM by sling blade »

Jeff H

  • Needs a day job
  • Posts: 6144
Re: MdiActiveDocument is null
« Reply #9 on: February 14, 2015, 11:48:55 AM »
Are you trying to do this from Initialize() method

huiz

  • Swamp Rat
  • Posts: 913
  • Certified Prof C3D
Re: MdiActiveDocument is null
« Reply #10 on: February 14, 2015, 01:36:37 PM »
Probably this happens when users start AutoCAD and there is the new start screen.

This start screen is a Document but does not contain a database nor you can start a transaction. Actually it has a value of null.

When you debug, you probably start a drawing and then netload the application. So then there is a real document available.
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

BlackBox

  • King Gator
  • Posts: 3770
Re: MdiActiveDocument is null
« Reply #11 on: February 14, 2015, 03:04:23 PM »
Perhaps this will be of some use:

http://forums.autodesk.com/t5/net/startup-variable/m-p/5272971


[Edit] - Another thought, is to register a DocumentCreated event handler, if the intended goal is to query a Document's Database every time a Document becomes available. More information is needed.


Cheers
« Last Edit: February 14, 2015, 03:47:12 PM by BlackBox »
"How we think determines what we do, and what we do determines what we get."

sling blade

  • Guest
Re: MdiActiveDocument is null
« Reply #12 on: February 14, 2015, 05:57:08 PM »
@Jeff H - No I am running the command outside of the initialize method.
@huiz - The application is up and running and I have used the File>Open menu to open a dwg. Everything should be going by then and the start screen is long gone.

@Blackbox I have implemented the IExtensionApplication interface and I have wired-up the App.Idle event as suggested in your link. I set a flag to let me know that is has gone through the onIdle method. Unfortunately I am getting the same issue.

Code: [Select]

        void IExtensionApplication.Initialize()
        {
            acApp.Idle += onIdle;
        }
        void IExtensionApplication.Terminate()
        {
        }
        static bool isIdle = false;
        private static void onIdle(object sender, EventArgs e)
        {
            acApp.Idle -= onIdle;
            isIdle = true;
            // <-- do something useful here
        }
...

[CommandMethod("WatchDbEvents", CommandFlags.Session)]
        public void WatchDbEvents()
        {
            do
            {
                if (isIdle == false)
                {
                    Thread.Sleep(500);
                }
                     
            } while (isIdle == false);

           // do stuff here;

        }

BlackBox

  • King Gator
  • Posts: 3770
Re: MdiActiveDocument is null
« Reply #13 on: February 14, 2015, 07:00:17 PM »
You've not provided enough information for us to have resolved the issue through guessing thus far; perhaps it's time to post your code so we can actually see how and where the exception is being raised?

Cheers
"How we think determines what we do, and what we do determines what we get."

Soulaimane

  • Guest
Re: MdiActiveDocument is null
« Reply #14 on: February 16, 2015, 02:37:15 AM »
Perhaps this is related.