Hi:
I would like to export a DWG file to WMF. I've read in the forum I need to add Autodesk.Autocad.interop.dll and Autodesk.Autocad.interop.common.dll, but with these references the interface displays too many duplicate definitions.
How can I do without using Interop references?
thanks,
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
You can use the 'dynamic' type (Framwork4 / A2012+) or late binding with reflection with prior versions.
The main inconvenient is that you won't have help from Visual Studio at editing and compiling time (intellisense). If there's an error in the code (i.e. a typo in a method or property or a bad argument type) the exception will raise at runnig time.
To avoid writing every time: "GetType().InvokeMember("membername", blah blah blah )" with late binding, you can use some extension methods which make the code more legible, there're many examples, here's one:
using BF = System.Reflection.BindingFlags; namespace LateBindingHelpers { public static class LateBinding { public static object GetInstance(string appName) { return System.Runtime.InteropServices.Marshal.GetActiveObject(appName); } public static object CreateInstance(string appName) { return System.Activator.CreateInstance(System.Type.GetTypeFromProgID(appName)); } public static object GetOrCreateInstance(string appName) { try { return GetInstance(appName); } catch { return CreateInstance(appName); } }
public static void ReleaseInstance(this object obj)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
} public static object Get(this object obj, string propName, params object[] parameter) { return obj.GetType().InvokeMember(propName, BF.GetProperty, null, obj, parameter); } public static void Set(this object obj, string propName, params object[] parameter) { obj.GetType().InvokeMember(propName, BF.SetProperty, null, obj, parameter); } public static object Invoke(this object obj, string methName, params object[] parameter) { return obj.GetType().InvokeMember(methName, BF.InvokeMethod, null, obj, parameter); } } }
than you Gille,
I'm working with VB.NET but I will try to translete the code to VB.NET.
Now, I would like to export the drawing to WMF but I'm not able to use the export command,..
Using examples.
With late binding extension methods
[CommandMethod("ExportWmf", CommandFlags.Modal)] public void ExportWmf() { Document doc = AcAp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptSelectionResult psr = ed.GetSelection(); if (psr.Status != PromptStatus.OK) return; object acadDoc = doc.AcadDocument; // replace with doc.Getacaddocument() for A2013+ object selSet = acadDoc.Get("ActiveSelectionSet"); acadDoc.Invoke( "Export", System.IO.Path.ChangeExtension(db.Filename, "wmf"), "wmf", selSet); selSet.Invoke("Delete"); }
With dynamic type
[CommandMethod("ExportWmf", CommandFlags.Modal)] public void ExportWmf() { Document doc = AcAp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptSelectionResult psr = ed.GetSelection(); if (psr.Status != PromptStatus.OK) return; dynamic acadDoc = doc.AcadDocument; // replace with doc.Getacaddocument() for A2013+ dynamic selSet = acadDoc.ActiveSelectionSet; acadDoc.Export( System.IO.Path.ChangeExtension(db.Filename, "wmf"), "wmf", selSet); selSet.Delete(); }
Sorry,
VB.net doesn't allow using extension methods with the Object type. But, if you set the Strict option to Off (default), VB.net uses implicitly late binding for the Object type.
So, you can write your code as if you referenced AutoCAD.Interop with replacing interop types with Object.
<CommandMethod("ExportWmf")> _ Public Sub ExportWmf() Dim doc As Document = AcApp.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim psr As PromptSelectionResult = ed.GetSelection() If psr.Status <> PromptStatus.OK Then Return End If
' replace with doc.GetAcadDocument() for A2013+ Dim acadDoc As Object = doc.AcadDocument Dim selSet As Object = acadDoc.ActiveSelectionSet acadDoc.Export( _ System.IO.Path.ChangeExtension(db.Filename, "wmf"), _ "wmf", _ selSet) selSet.Delete() End Sub
hi,
The code you send is ok to use like command in a single drawing but I would like to use in batch process and when I execute the code appears "InvalidCastException" and it no runs.
thanks for your answer!,
For a batch process, as you need to open the drawing in the editor for a selection, you cannot use Database.ReadDwgFile() method.
Here's a quick and dirty (no error handling) which shows a way to open each selected dwg into the current session.
<CommandMethod("ExportWmf", CommandFlags.Session)> _ Public Sub ExportWmf() Dim docMan As DocumentCollection = AcApp.DocumentManager Dim fileDlg As OpenFileDialog = New OpenFileDialog() fileDlg.Filter = "Drawing (*.dwg)|*.dwg" fileDlg.Multiselect = True If fileDlg.ShowDialog = DialogResult.OK Then For Each filename As String In fileDlg.FileNames Dim doc As Document = docMan.Open(filename) ExportDocument(doc, filename) doc.CloseAndDiscard() Next End If End Sub Private Sub ExportDocument(ByVal doc As Document, ByRef filename As String) Using doc.LockDocument() Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim acad As Object = AcApp.AcadApplication Dim acadDoc As Object = doc.AcadDocument db.TileMode = True acad.ZoomExtents() Dim psr As PromptSelectionResult = ed.SelectAll() If psr.Status <> PromptStatus.OK Then Return End If Dim selSet As Object = acadDoc.ActiveSelectionSet acadDoc.Export( _ Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)), _ "wmf", _ selSet) selSet.Delete() End Using End Sub
When I was trying the code , two errors have appeared:
+ With Dim acadDoc As Object = doc.AcadDocument : 'AcadDocument' is not a member of 'Autodesk.AutoCAD.ApplicationServices.Document'
+ Dim psr As PromptSelectionResult = ed.SelectAll() : Error eNotApplicable.
If I execute Dim psr As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.editor.SelectAll() the sentece runs.
karea a écrit :When I was trying the code , two errors have appeared:
+ With Dim acadDoc As Object = doc.AcadDocument : 'AcadDocument' is not a member of 'Autodesk.AutoCAD.ApplicationServices.Document'
+ Dim psr As PromptSelectionResult = ed.SelectAll() : Error eNotApplicable.
If I execute Dim psr As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.editor.SelectAll() the sentece runs.
With AutoCAD 2013 (and 2014) the Document.AcadDocument property have been replaced by the DocumentExtension.GetAcadDocument() method.
This code seems to work for me (A2014).
<CommandMethod("ExportWmf", CommandFlags.Session)> _ Public Sub ExportWmf() Dim docMan As DocumentCollection = AcApp.DocumentManager Dim fileDlg As OpenFileDialog = New OpenFileDialog() fileDlg.Filter = "Drawing (*.dwg)|*.dwg" fileDlg.Multiselect = True If fileDlg.ShowDialog = DialogResult.OK Then For Each filename As String In fileDlg.FileNames Dim doc As Document = docMan.Open(filename, True) Dim name As String = Path.Combine( _ Path.GetDirectoryName(filename), _ Path.GetFileNameWithoutExtension(filename)) Using doc.LockDocument() Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim acad As Object = AcApp.AcadApplication Dim acadDoc As Object = doc.GetAcadDocument() db.TileMode = True acad.ZoomExtents() Dim psr As PromptSelectionResult = ed.SelectAll() If psr.Status <> PromptStatus.OK Then Return End If Dim selSet As Object = acadDoc.ActiveSelectionSet acadDoc.Export(name, "wmf", selSet) selSet.Delete() End Using doc.CloseAndDiscard() Next End If End Sub
great! it runs!
The code has a little problem with this sentence:
Dim psr As PromptSelectionResult = ed.SelectAll()
Because it appears an error 'eNotApplicable'
Instead of this I put:
Dim psr As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.Editor.SelectAll()
and it's ok,
thanks,
Can't find what you're looking for? Ask the community or share your knowledge.