000

Index Labels

Moving to AutoCAD 2015/16 Issues: Quitting Application

.
I have been recently helping upgrading AutoCAD 2012 to AutoCAD 2015 in my office. During the process of moving up to AutoCAD 2015, I encountered a few interesting issues that actually break some of my existing AutoCAD .NET applications.

I have been quite busy these days and have no posted in my blog for quite a while. Hopefully I share some of my experiences with moving up to AutoCAD 2015/16 here.

The topic of this post is about calling Autodesk.AutoCAD.ApplicationServices.Application.Quit().

One of the add-in applications I developed is kind of like "auto-update" application. It has code to handle Application.Idle event.In the event handler, if certain condition is met, the code would call Application.Quit() to shut down AutoCAD. This application has been working well up to the last pre-2015 version of AutoCAD (actually, AutoCAD 2012. We never used AutoCAD 2013/14 in production).

However, this application stops working in AutoCAD 2015. To be exactly, it is the call to Application.Quit() in the event handler (handling Application.Idle event) hangs AutoCAD. When I say "hangs", it is literally "hangs", that is, AutoCAD freezes entirely and can only be shut down by going to Task Manager". I can also see in the Task Manager that AutoCAD spins quite some CPU cycles (30-50%) for nothing after Application.Quit() is called.

Below is the code to reproduce this behaviour.

    1 using System;
    2 using System.Windows.Forms;
    3 
    4 using Autodesk.AutoCAD.ApplicationServices;
    5 using Autodesk.AutoCAD.EditorInput;
    6 using Autodesk.AutoCAD.Runtime;
    7 using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
    8 
    9 [assembly: CommandClass(typeof(QuitAppInEvent.MyCommands))]
   10 [assembly: ExtensionApplication(typeof(QuitAppInEvent.MyCommands))]
   11 
   12 namespace QuitAppInEvent
   13 {
   14     public class MyCommands : IExtensionApplication
   15     {
   16         private static bool _quit = false;
   17 
   18         public void Initialize()
   19         {
   20             CadApp.Idle += CadApp_Idle;
   21         }
   22 
   23         public void Terminate()
   24         {
   25 
   26         }
   27 
   28         [CommandMethod("DoQuit")]
   29         public void RunMyCommand()
   30         {
   31             _quit = false;
   32 
   33             Document dwg = CadApp.DocumentManager.MdiActiveDocument;
   34             Editor ed = dwg.Editor;
   35 
   36             PromptKeywordOptions opt = new PromptKeywordOptions(
   37                 "Do you want to quit AutoCAD?");
   38             opt.Keywords.Add("Yes");
   39             opt.Keywords.Add("No");
   40             opt.Keywords.Default = "Yes";
   41             opt.AppendKeywordsToMessage = true;
   42 
   43             PromptResult res = ed.GetKeywords(opt);
   44             if (res.Status == PromptStatus.OK)
   45             {
   46                 if (res.StringResult == "Yes")
   47                 {
   48                     _quit = true;
   49                 }
   50             }
   51         }
   52 
   53         private void CadApp_Idle(object sender, EventArgs e)
   54         {
   55             if (_quit)
   56             {
   57                 DialogResult res = MessageBox.Show(
   58                     "Do you really want to quit AutoCAD?", "My Quit App",
   59                     MessageBoxButtons.YesNo, MessageBoxIcon.Question,
   60                     MessageBoxDefaultButton.Button2);
   61 
   62                 //Once "Yes" button is clicked AutoCAD freezes!
   63                 if (res == DialogResult.Yes)
   64                 {
   65                     CadApp.Idle -= CadApp_Idle;
   66                     CadApp.Quit();
   67                 }
   68                 else
   69                 {
   70                     _quit = false;
   71                 }
   72             }
   73         }
   74     }
   75 }

I also tried to call Application.Quit() in a normal CommandMethod like this:

   75         [CommandMethod("MyQuitCmd", CommandFlags.Session)]
   76         public static void MyQuitCommand()
   77         {
   78             Document dwg = CadApp.DocumentManager.MdiActiveDocument;
   79             Editor ed = dwg.Editor;
   80 
   81             PromptKeywordOptions opt = new PromptKeywordOptions(
   82                 "Do you want to quit AutoCAD?");
   83             opt.Keywords.Add("Yes");
   84             opt.Keywords.Add("No");
   85             opt.Keywords.Default = "Yes";
   86             opt.AppendKeywordsToMessage = true;
   87 
   88             PromptResult res = ed.GetKeywords(opt);
   89             if (res.Status == PromptStatus.OK)
   90             {
   91                 if (res.StringResult == "Yes")
   92                 {
   93                     CadApp.Quit();
   94                 }
   95             }
   96         }


This, of course, works as expected in AutoCAD 2015.

I also tried the code in AutoCAD 2016. The result is the same as with AutoCAD 2015.

So, I had to figure out a way to make my existing application work as before. Fortunately, the solution I found is very simple: calling COM API's AcadApplication.Quit() instead:

   53 private void CadApp_Idle(object sender, EventArgs e)
   54         {
   55             if (_quit)
   56             {
   57                 DialogResult res = MessageBox.Show(
   58                     "Do you really want to quit AutoCAD?", "My Quit App",
   59                     MessageBoxButtons.YesNo, MessageBoxIcon.Question,
   60                     MessageBoxDefaultButton.Button2);
   61 
   62                 //Once "Yes" button is clicked AutoCAD freezes!
   63                 if (res == DialogResult.Yes)
   64                 {
   65                     CadApp.Idle -= CadApp_Idle;
   66                     //CadApp.Quit();
   67                     dynamic comApp = CadApp.AcadApplication;
   68                     comApp.Quit();
   69                 }
   70                 else
   71                 {
   72                     _quit = false;
   73                 }
   74             }
   75         }


However, I cannot explain why .NET API's Quit() stops working in the event handler, while COM API's Quit() works, even both are the wrapper of C++ ObjectARX code. I guess the issue with .NET API might be a bug introduced by removing FIBER in AutoCAD 2015. To me, it is good enough that with the minor change (of using COM API's AcadApplication.Quit()) my existing application can still live with AutoCAD 2015/16.

Blog Archive

Labels

3D Modeling 3D Sketch Inventor AI Design AI in Manufacturing AI Tools Architecture Artificial Intelligence AutoCAD AutoCAD advice AutoCAD Basics AutoCAD Beginners AutoCAD Civil3D AutoCAD commands AutoCAD efficiency AutoCAD features AutoCAD File Management AutoCAD Layer AutoCAD learning AutoCAD print settings AutoCAD productivity AutoCAD Teaching AutoCAD Techniques AutoCAD tips AutoCAD training. AutoCAD tricks AutoCAD Tutorial AutoCAD workflow AutoCAD Xref Autodesk Autodesk 2025 Autodesk AI Tools Autodesk AutoCAD Autodesk Fusion 360 Autodesk Inventor Autodesk Inventor Frame Generator Autodesk Inventor iLogic Autodesk Recap Autodesk Revit Autodesk Software Autodesk Video Automation Automation Tutorial Basic Commands Basics Beginner Beginner Tips BIM BIM Implementation Block Editor ByLayer CAD comparison CAD Design CAD File Size Reduction CAD line thickness CAD Optimization CAD Productivity CAD software clean CAD file cleaning command Cloud Collaboration command abbreviations Construction Technology Contraints Create resizable blocks CTB STB Data Reference Data Shortcut design software Design Workflow Digital Design Digital Twin Drafting Standards Drawing Automation Dref Dynamic Block Dynamic Block AutoCAD Dynamic Blocks Dynamic doors Dynamic windows eco design editing commands energy efficiency Engineering Engineering Design Engineering Innovation Engineering Technology engineering tools Excel Express Tools External Reference Fast Structural Design Fusion 360 Generative Design green building Grips heavy CAD file Heavy CAD Files iLogic Industry 4.0 Insight Inventor API Inventor Drawing Template Inventor Frame Generator Inventor Graphics Issues Inventor IDW Inventor Tips Keyboard Shortcuts Learn AutoCAD Machine Learning in CAD maintenance command Management Manufacturing Innovation Metal Structure ObjectARX .NET API Organization OVERKILL OVERKILL AutoCAD Palette PDF Plot Style AutoCAD Practice Drawing Printing Quality professional printing Professional Tips PTC Creo PURGE PURGE AutoCAD ReCap reduce CAD file size Resizable Block Revit Revit Best Practices Revit Workflow Ribbon screen shortcut keys Shortcuts Siemens NX Sketch Small Firms Smart Block Smart Factory SolidWorks Steel Structure Design sustainability Sustainable Manufacturing toolbar Tutorial User Interface (UI) Workbook Workspace XLS Xref