One question that comes up from time to time is how to "gracefully" close all open documents inside AutoCAD. I use the term "gracefully" in quotes, as this does mean different things to different people. Let me first define what it means to me:
- Changes get saved to modified drawings
- Even if the drawing in question has never been saved before
- Which means you should expect to get some DWGs with names such as "Drawing1.dwg" saved to the working directory
- Active commands get cancelled, where possible
Firstly, we need to define our command in the "session context", which means it can work across drawings. This command will then loop through the documents in the document manager, closing them one-by-one. We need to do certain things to support the above conditions... if a command is active, we need to send a couple of cancel keystrokes to the document, and we also need to check whether the document has been modified or not. To do this last piece we need to activate the drawing and check DBMOD - if you relax the condition about saving (or just force the save, anyway, without checking the value of DBMOD), then you can avoid activating the document.
And that's about all there is to it, at least with my definition of gracefully. :-)
Here's the C# code I used for this:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Interop;
namespace CloseDocuments
{
public class Commands
{
// If you change the command name, be sure to change
// the code that checks for it, below.
//
[CommandMethod("CD", CommandFlags.Session)]
static public void CloseDocuments()
{
DocumentCollection docs = Application.DocumentManager;
foreach (Document doc in docs)
{
// First cancel any running command
if (doc.CommandInProgress != "" &&
doc.CommandInProgress != "CD")
{
AcadDocument oDoc =
(AcadDocument)doc.AcadDocument;
oDoc.SendCommand("\x03\x03");
}
if (doc.IsReadOnly)
{
doc.CloseAndDiscard();
}
else
{
// Activate the document, so we can check DBMOD
if (docs.MdiActiveDocument != doc)
{
docs.MdiActiveDocument = doc;
}
int isModified =
System.Convert.ToInt32(
Application.GetSystemVariable("DBMOD")
);
// No need to save if not modified
if (isModified == 0)
{
doc.CloseAndDiscard();
}
else
{
// This may create documents in strange places
doc.CloseAndSave(doc.Name);
}
}
}
}
}
}
A quick personal note... aside from it being a busy time of year with lots of internal meetings, I've been busy over the last few weeks getting visas for my family and I to travel to China and India. We leave on Wednesday: I'll be working from our Beijing office for 7 weeks, and then from Bangalore for a further 2 weeks. I actually hope this means I'll have a little more time to spend on this blog (at least more than I have during the last three weeks or so, where I've mostly been on the road), but let's see.
I'm especially excited to be taking my family on this trip; I'm sure it's going to be an enriching experience for all of us. I expect I'll end up interjecting my posts over the next few months with some comments on how it's all going... watch this space! :-)