There are some usefull COM Interfaces predating the introduction of the .NET software development platform for the customization of the AutoCAD ( COM Interoperability (.NET)).
When developing for AutoCAD OEM, you have to be aware that the approach to work with the COM Interfaces is different than when working with a vanilla AutoCAD (see here for more details)
Here is some sample code where an existing drawing is openend and all layouts are cycled to zoom the paperspace to the maximum extents.
using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using AcApp2 = Autodesk.AutoCAD.ApplicationServices.Application;
using AcApp = Autodesk.AutoCAD.ApplicationServices;
using AcRt = Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcIop = Autodesk.AutoCAD.Interop;
[assembly: AcRt.ExtensionApplication(null)]
[assembly: AcRt.CommandClass(typeof(layout.ZoomLayoutsToExtents))]
namespace Zoom
{
public class Layouts
{
[AcRt.CommandMethod("ZoomLayoutsToExtents", AcRt.CommandFlags.Session)]
public void ZoomLayoutsToExtents()
{
try
{
/* get path to executing assembly */
string dwgPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
/* Full file path to a sample drawing that is located in the same directory as the executing assembly */
dwgPath += "test.dwg";
/* close document without saving */
bool bSaveDocumentBeforeClosing = false;
/* open document from filepath */
AcApp.DocumentCollection docCol = AcApp2.DocumentManager;
AcApp.Document doc = AcApp.DocumentCollectionExtension.Open(docCol, dwgPath, false);
docCol.MdiActiveDocument = doc;
AcDb.Database db = doc.Database;
/* ObjectId List to store the objectIds for all layouts */
List<AcDb.ObjectId> oIdList = new List<AcDb.ObjectId>();
/* Here we get the objectId's of all layouts */
using (AcApp.DocumentLock docLoc = AcApp2.DocumentManager.MdiActiveDocument.LockDocument())
{
using (AcDb.Transaction trans = db.TransactionManager.StartTransaction())
{
/* switch to modelspace */
AcDb.LayoutManager.Current.CurrentLayout = @"Model";
/* ALTERNATIVE >> */
/* AcApp.Application.SetSystemVariable("TILEMODE", 1); */
/* get layout dictionary */
AcDb.DBDictionary layoutDict = trans.GetObject(db.LayoutDictionaryId, AcDb.OpenMode.ForRead) as AcDb.DBDictionary;
/* get objectId's from dictionary */
foreach (AcDb.DBDictionaryEntry entry in layoutDict)
oIdList.Add(entry.Value);
trans.Commit();
} // using trans
} // using trans
/* this works with vanilla AutoCAD */
#if !OEM
dynamic thisApp = AcApp.Application.AcadApplication;
/* dynamic does NOT work for AutoCAD OEM */
/* Use AcIop.AcadApplication instead */
#elif OEM
AcIop.AcadApplication thisApp = AcApp.Application.AcadApplication as AcIop.AcadApplication;
#endif
/* lock the document for editing */
using (AcApp.DocumentLock docLoc = doc.LockDocument())
{
/* cycle objectId's */
foreach (AcDb.ObjectId oId in oIdList)
{
AcDb.LayoutManager.Current.SetCurrentLayoutId(oId);
if (AcDb.LayoutManager.Current.CurrentLayout != "Model")
{
using (var tr = doc.Database.TransactionManager.StartTransaction())
{
/* https://forums.autodesk.com/t5/net/how-to-activate-viewport-in-paperspace/td-p/12740814 */
doc.Editor.SwitchToPaperSpace();
tr.Commit();
}
}
/* zoom paperspace to extents */
thisApp.GetType().InvokeMember("ZoomExtents", BindingFlags.InvokeMethod, null, thisApp, null);
}
}
/* The command MUST be run in AcRt.CommandFlags.Session */
/* otherwise, there is a System.Runtime.InteropServices.COMException */
if (bSaveDocumentBeforeClosing)
AcApp.DocumentExtension.CloseAndSave(doc, dwgPath);
else
AcApp.DocumentExtension.CloseAndDiscard(doc);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(
ex.Message.ToString(),
@"Error Message",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error
);
}
} // END
} // class
} // namespace
The zoom is done with this COM Interop:
thisApp.GetType().InvokeMember("ZoomExtents", BindingFlags.InvokeMethod, null, thisApp, null);
For vanilla AutoCAD you can use
dynamic thisApp = AcApp.Application.AcadApplication;
to get a variable for the AutoCAD application.
This will not work for AutoCAD OEM.
For AutoCAD OEM you have to add the using to the interop:
using AcIop = Autodesk.AutoCAD.Interop;
and an explicit variable assignment with
AcIop.AcadApplication thisApp = AcApp.Application.AcadApplication as AcIop.AcadApplication;
You can do this to target vanilla AutoCAD and AutoCAD OEM:
/* this works with vanilla AutoCAD */
#if !OEM
dynamic thisApp = AcApp.Application.AcadApplication;
/* dynamic does NOT work for AutoCAD OEM */
/* Use AcIop.AcadApplication instead */
#elif OEM
AcIop.AcadApplication thisApp = AcApp.Application.AcadApplication as AcIop.AcadApplication;
#endif
When you want to use the variable as a parameter for a subroutine, you have to avoid some implicit casting. This will not work with AutoCAD OEM:
private void SomeSubRoutine(
dynamic thisApp);
Instead, you have to do this with explicit variable parameters:
private void SomeSubRoutine(
#if !OEM
dynamic thisApp
#elif OEM
AcIop.AcadApplication thisApp
#endif
)