You basically have to open AutoCAD from external C# process, which is discused here and here. I suggest you to make a singleton, that handles opening and closing of the AutoCAD process and takes care for open/insert/save/close of the documents (blocks). Hook to selectionChanged drop-down event and spawn Autocad if it is not. Further you have to call Insert() or WblockCloneObjects() methods in order to insert a block into current document.
private object SpawnCadApplication(string appProgId)
{
var acadType = Type.GetTypeFromProgID(appProgId);
return Activator.CreateInstance(acadType);
}
private bool ApplicationIsInstalled(string appProgId)
{
return Type.GetTypeFromProgID(appProgId) != null;
}
private bool GetRunninApplication(string appProgId, out object cadApp)
{
cadApp = null;
try
{
cadApp = Marshal.GetActiveObject(appProgId);
}
catch (Exception e)
{
}
return cadApp != null;
}
private void ReleaseObject(object obj)
{
try
{
Marshal.FinalReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
}
}
Once you have controll over AutoCAD, then you could make everything you want
public void OpenSaveCloseFile(string filePath)
{
object cadApp;
if (!GetRunninApplication(AutoCadProgId, out cadApp))
{
cadApp = SpawnCadApplication(AutoCadProgId);
}
var cadDocuments = cadApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, cadApp, null);
// open a file
var openArgs = new object[2];
openArgs[0] = filePath; // Name
openArgs[1] = false; // ReadOnly
var acDoc = cadDocuments.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, cadDocuments, openArgs, null);
// save the file
acDoc.GetType().InvokeMember("Save", BindingFlags.InvokeMethod, null, acDoc, null);
// close the file
var closeArgs = new object[2];
closeArgs[0] = true; //Save changes
closeArgs[1] = filePath; // Document Name
acDoc.GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, acDoc, closeArgs);
ReleaseObject(acDoc);
}
Insert block into current document should be somehting like:
var activeDocument = cadApp.GetType().InvokeMember("ActiveDocument", BindingFlags.GetProperty, null, cadApp, null);
var database = activeDocument.GetType().InvokeMember("Database", BindingFlags.GetProperty, null, activeDocument, null);
var insertArgs = new object[3];
insertArgs[0]=*Objects*;
insertArgs[1]=*Owner*;
insertArgs[2]=*IdPairs*;
database.GetType().InvokeMember("CopyObjects", BindingFlags.InvokeMethod, null, database, insertArgs, null);
However you have to figure it out how to fill the arguments array. Look at the attached puctures.
CloneObjects from Interop interface has to correspond to WBlockCloneObjects.
![WBlockCloneObjets]()
The cool thing is that you don't have to add any Acad libs as a reference.