Plugin bundle load fails and AutoCAD Crashes at startup

Plugin bundle load fails and AutoCAD Crashes at startup

Anonymous
Not applicable
1,666 Views
6 Replies
Message 1 of 7

Plugin bundle load fails and AutoCAD Crashes at startup

Anonymous
Not applicable

Good day All,

I have developed a plugin for AutoCAD and it works fine when i do netload.

But when i put the bundle folder  in one of  the below locations, AutoCAD crashes at startup with

"Fatal Error: Unhandled access violation Reading 0x0000 Exception at DEAAF94Dh".

-  %APPDATA%/Autodesk/ApplicationPlugins.

- %ProgramFiles%/Autodesk/ApplicationPlugins.

- %ProgramData%/Autodesk/ApplicationPlugins.

I followed the instructions  <here>  to build the bundle folder and i also have a good working project build by myself.

I don't understand why it is crashing and will appreciate your assistance.

Thank you.

Accepted solutions (2)
1,667 Views
6 Replies
Replies (6)
Message 2 of 7

norman.yuan
Mentor
Mentor

Without knowing what your plugin does, seeing code, seeing the plugin bundle's configuration, it is really difficult to suggest anything.

 

With that said, however, since you say AutoCAD crashes at startup, it sounds like at least one of the classes in the assembly or assemblies autoloaded into AutoCAD is ExtensionApplication (i.e. implemented IExenstionApplication interface and you have code does something in the Initialize() method, which runs the the assembly is loaded. 

 

Because you also say the plugin works fine when loaded with command "NETLOAD", so the question is: what your code des in the Initialize()? Is it possible the code there requires some AutoCAD resources, which may not be available when the assembly is loaded on AutoCAD startup, but available after AutoCAD fully started (when you manually "NETLOAD"). Is the code in Initialize() wrapped with try{...} catch{...} block?

 

Again, it is just a guess without knowing any details of your situation other than it crashes AutoCAD on startup.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 7

Anonymous
Not applicable

Hi Norman,

Thank you for your prompt reply.

Sorry if was not that clear. This plugin is designed to do takeoff  and estimation in AutoCAD. 

Here is the Initialize() code:

public void Initialize()

{

    Overrule = new PolylineOverrule();

    OverruleArea = new PolyAreaOverrule();

     OverrulePerimeter = new PolyPerimeterOverrule();

    ForEdit = false;

     docMgr.DocumentCreated += DocumentCreated;

    docMgr.DocumentActivated += DocumentActivated;

   doubleObjectId =new ObjectId();

     if (ComdEndedHandled)

           AcCoreAp.DocumentManager.MdiActiveDocument.CommandEnded -= CommandEnded;

         else

          AcCoreAp.DocumentManager.MdiActiveDocument.CommandEnded += CommandEnded;

       ComdEndedHandled = !ComdEndedHandled;

     if (obModiHandled)

            AcCoreAp.DocumentManager.MdiActiveDocument.Database.ObjectModified -= ObjectModified;

      else

           AcCoreAp.DocumentManager.MdiActiveDocument.Database.ObjectModified += ObjectModified;                        obModiHandled = !obModiHandled;

if (ObjErasedHandled)

       AcCoreAp.DocumentManager.MdiActiveDocument.Database.ObjectErased -= ObjectErased;

   else

       AcCoreAp.DocumentManager.MdiActiveDocument.Database.ObjectErased += ObjectErased;

    ObjErasedHandled = !ObjErasedHandled;

  foreach (Document doc in docMgr)

      {

        if (ObjSelectedHandled)

             doc.ImpliedSelectionChanged -= ObjectSelected;

             else

             doc.ImpliedSelectionChanged += ObjectSelected;

        ObjSelectedHandled = !ObjSelectedHandled;

   }

DoubleClickObject.ChangeMacroCUI();

CustomizationSection cs = new CustomizationSection(DoubleClickObject.getMainCuiFile());

PartialCuiFileCollection pcfc = cs.PartialCuiFiles;

if (!pcfc.Contains(myCuiFile))

{

    if (System.IO.File.Exists(myCuiFile))

          MyUtilities.LoadMyCui(myCuiFile);

}

ids = new List();

ids2 = new List();

Commands.ActivateOverrule();

Objectgroupname = "";

takeOffSummary = new TakeOffSummary();

 

}

 

0 Likes
Message 4 of 7

Alexander.Rivilis
Mentor
Mentor

@Anonymous 

First of all AcCoreAp.DocumentManager.MdiActiveDocument can be null while loading from BUNDLE

So you have to check it.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 5 of 7

norman.yuan
Mentor
Mentor
Accepted solution

Firstly, please post your code using the button "</>" on top of the window, so that the code is readable.

 

Then, as I expected, you MUST wrap your code in Initialize() with try...catch... block, if the code does ANYTHING more than simple Editor.WriteMessage("\nHello World.");

 

However, usually AutoCAD is quite forgive-able to the code in Initialize(), that is, it usually silently swallows exceptions in Initialize() and carries on (with the loaded assembly being useless/failed loading). 

 

In your code, besides hooking up all sorts of event handler, the code also calls some actions, such as ActivateOverrule(),  checing main/partial cui and then possibly LoadMyCui(), ...

 

Any of these actions could causes the crash when your assembly is loaded, but I suspect checking CUI and loading custom CUI could be the offending source. You can verify by commenting out all these actions, or one by one and then try the autoloading on startup.

 

If it is indeed because of one of the actions in Initialize() that causes the crash, then you sure postpone the/these action/actions in the Initialize() by handling Application.Idle(). That is, do the/these action/actions in Idle event handle, meaning Initialize() tells AutoCAD: run the actions(s) when AutoCAD startup finishes and becomes idle. To user, it still feels the extra work done in the Idle handle is part of startup.

 

Also, You massive event handler hooking/removing code ONLY adds event handlers to the MdiActiveDocument when the assembly is loaded. Any document that opened after AutoCAD startup will not have these event handlers hooked up. How do make sure on AutoCAD startup, your target drawing (you want to takeoff work) is ALREADY OPEN when your assembly is to be loaded? Obviously, when in your testing/debugging with manually "NETLOAD", you likely always has your target drawing open, thus your plugin worked. But with autoloading plugin, when user double click AutoCAD icon to start it up, the target drawing is very possibly not the one opens on AutoCAD startup. Usually, you need to hook/removed the event handlers to all existing open drawings and all possible drawing to be opened later.

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 6 of 7

Anonymous
Not applicable

Thank you Alexander, will investigate it.

0 Likes
Message 7 of 7

Anonymous
Not applicable
Accepted solution

Hi Norman,

 

Thank you very much. it worked!.

I moved the document event handlers and methods to Application.idle() and everything is working fine.

Thank you again for your assistance.

I'm a beginner in programming and i learn day by day.

Here is the revised Initialize() code:

 public void Initialize()
        {


            try
            {

                Overrule = new PolylineOverrule();

                OverruleArea = new PolyAreaOverrule();

                OverrulePerimeter = new PolyPerimeterOverrule();
                ForEdit = false;
               
                 doubleObjectId = new ObjectId();
               
                Application.Idle += OnIdle;

                ids = new List<ObjectId>();
                ids2 = new List<ObjectId>();
               
                Objectgroupname = "";
                takeOffSummary = new TakeOffSummary();
            }
            catch(Autodesk.AutoCAD.Runtime.Exception ex)
            {
   
AcCoreAp.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.Message);
            }


        }

 and here is the OnIdle():

private void OnIdle(object sender, EventArgs e)
        {
            var doc = AcCoreAp.DocumentManager.MdiActiveDocument;
            if (doc != null)
            {
                AcCoreAp.Idle -= OnIdle;
                docMgr.DocumentCreated += DocumentCreated;
                docMgr.DocumentActivated += DocumentActivated;
                Commands.ActivateOverrule();
                if (ComdEndedHandled)
                    doc.CommandEnded -= CommandEnded;
                else
                    doc.CommandEnded += CommandEnded;
                ComdEndedHandled = !ComdEndedHandled;

                if (obModiHandled)
                    doc.Database.ObjectModified -= ObjectModified;
                else
                    doc.Database.ObjectModified += ObjectModified;

                obModiHandled = !obModiHandled;

                if (ObjErasedHandled)
                    doc.Database.ObjectErased -= ObjectErased;
                else
                   doc.Database.ObjectErased += ObjectErased;

                ObjErasedHandled = !ObjErasedHandled;

                //foreach (Document doc in docMgr)
                //{
                    if (ObjSelectedHandled)
                        doc.ImpliedSelectionChanged -= ObjectSelected;
                    else
                        doc.ImpliedSelectionChanged += ObjectSelected;

                    ObjSelectedHandled = !ObjSelectedHandled;
                
                DoubleClickObject.ChangeMacroCUI();

                CustomizationSection cs = new CustomizationSection(DoubleClickObject.getMainCuiFile());

                PartialCuiFileCollection pcfc = cs.PartialCuiFiles;


                if (!pcfc.Contains(myCuiFile))
                {
                    if (System.IO.File.Exists(myCuiFile))
                        MyUtilities.LoadMyCui(myCuiFile);
                }

                doc.Editor.WriteMessage("\nTakeOff tools Loaded\n");
            }
        }
0 Likes