Hi,
I just finished developing an plugin for Autocad 2014 using the managed .net api
It appears that the client also want to use this addin in Autocad Mechanical 2014, but when i run netload on my dll nothing happens and my command is not available. Some googling gave me the impression that autocad mechanical only has a COM and c++ api, is that correct? is there any way i can make my code work in autocad mechanical?
Hope someone can give me a quick answer here!
Regards
Henrik
Sounds like there's an issue with your code, as (generally speaking) an assembly compiled for vanilla AutoCAD will load into one if its verticals just fine... As example, I use all of my AutoCAD plug-ins with Civil 3D on a daily basis.
Hard to tell for sure though, as you've not posted any code, such as any Initialize() evaluation, etc.. More information is needed.
Also, instead of manually NETLOADing your assembly, you might try creating an Autoload .bundle since you're using 2014.
Cheers
"How we think determines what we do, and what we do determines what we get."
@BlackBox_ wrote:Sounds like there's an issue with your code, as (generally speaking) an assembly compiled for vanilla AutoCAD will load into one if its verticals just fine... As example, I use all of my AutoCAD plug-ins with Civil 3D on a daily basis.
Apparently, I am mistaken... I'm only finding ObjectARX, and COM developer guides here:
http://usa.autodesk.com/adsk/servlet/index?id=14952981&siteID=123112
Sorry for any confusion... I wonder if these API's are only for the Mechanical aspects of the product, and that they still support AutoCAD's .NET API???
"How we think determines what we do, and what we do determines what we get."
Hi,
Thanks for your quick reply,
Good to know that i didnt make all that code for nothing!
my addin is pretty big, but below i've pasted the code for the main class,
I mananged to get it installed on my dev pc now, and with visual studio debugger i can at least see that it loads the dll and steps into the Initialize function
but any idea why my command methods are not available?
Just saw your second post: jup that developer guide is what scared me too.... but at least it loads, so maybe there is some hocus pocus setting somewhere that makes my commands invisible?
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using Tagit; using Application = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(Program))] [assembly: ExtensionApplication(typeof(Program))] namespace Tagit { class Program : IExtensionApplication { public static TagitMainAutocad TagitMain; private static Document Doc; [CommandMethod("TTBalloon")] public static void PlaceBalloon() { if (TagitMain == null) { if (!ActivateDocument(true)) return; } TagitMain.ShowPosForm(); } [CommandMethod("TTBOM")] public static void ShowBOMForm() { if (TagitMain == null) { if(!ActivateDocument(true)) return; } TagitMain.ShowForm(); } [CommandMethod("TTADD")] public static void CreateItem() { if (TagitMain == null) { if (!ActivateDocument(true)) return; } TagitMain.CurrentBOM.BOMTable.CreateItem(TagitMain); } [CommandMethod("TTCLEANUP")] public static void Cleanup() { if (TagitMain == null) { if (!ActivateDocument(true)) return; } TagitMain.CurrentBOM.Cleanup(); } [CommandMethod("GetRevision")] public static void ReadRevision() { Doc.Editor.WriteMessage("Revision: " + TagitMain.CurrentBOM.Revision.DisplayValue + "\n\n"); } [CommandMethod("SetRevision")] public static void WriteRevision() { var res = Doc.Editor.GetString("Enter revision"); TagitMain.CurrentBOM.Revision = new Revision(res.StringResult); } [CommandMethod("ReadBalloons")] public static void ReadBalloons() { using (var tr = new QueryTransaction(TagitMain.Database)) { foreach (DBObject obj in tr.Find(e => e is MLeader)) { var xdata = obj.GetXDataForApplication(TagitMainAutocad.ApplicationName); if (xdata == null) { TagitMain.Editor.WriteMessage("No XDATA \n\n"); continue; } var array = xdata.AsArray(); TagitMain.Editor.WriteMessage("MLeader: " + array[0].Value.ToString() + ", " + array[1].Value.ToString() + ", " + array[2].Value.ToString() + "\n\n"); } } } [CommandMethod("ReadItems")] public static void ReadBOMItems() { foreach (var block in TagitMain.CurrentBOM.BOMTable.GetTableItems()) { using (var trans = new QueryTransaction(TagitMain.Database)) { string items = ""; foreach (var item in trans.GetBlockAttributes(block)) { items += item.Key + ": " + item.Value + ", "; } items += "\n\n"; TagitMain.Editor.WriteMessage(items); } } } [CommandMethod("ReadXData")] public static void ReadXData() { using (var trans = new QueryTransaction(TagitMain.Database)) { foreach ( BlockReference block in trans.Find(e => e is BlockReference && e.Name == BOMTable.TableItemBlockName)) { var x = block.GetXDataForApplication(TagitMainAutocad.ApplicationName); TagitMain.Editor.WriteMessage("Xdata: " + x.ToString()); } } } public void Initialize() { Application.DocumentManager.DocumentActivated += DocumentManagerOnDocumentActivated; Application.DocumentManager.DocumentToBeDeactivated += DocumentManagerOnDocumentToBeDeactivated; ActivateDocument(); } private void DocumentManagerOnDocumentToBeDeactivated(object sender, DocumentCollectionEventArgs e) { if (TagitMain != null) { using (e.Document.LockDocument()) { ActivateDocument(); } } TagitMain = null; } public static bool ActivateDocument(bool showMessage = false) { var errors = TagitMainAutocad.IsValidDocument(Application.DocumentManager.MdiActiveDocument); if (errors.Count > 0) { if (showMessage) { var message = "This document is not compatible with Tagit. Missing following elements: \n"; foreach (var error in errors) { message += "- " + error + "\n"; } MessageBox.Show(message, "Tagit: Incompatible document."); } return false; } TagitMain = new TagitMainAutocad(); Doc = Application.DocumentManager.MdiActiveDocument; TagitMain.Initialize(Doc); return true; } private void DocumentManagerOnDocumentActivated(object sender, DocumentCollectionEventArgs e) { using (e.Document.LockDocument()) { ActivateDocument(); } } public void Terminate() { Application.DocumentManager.DocumentActivated -= DocumentManagerOnDocumentActivated; Application.DocumentManager.DocumentToBeDeactivated -= DocumentManagerOnDocumentToBeDeactivated; } } }
I haven't scanned the entire code, but this jumped out to me right away... Shouldn't this line:
[assembly: CommandClass(typeof(Program))]
... Be this:
[assembly: CommandClass(typeof(Tagit.Program))]
Again, not sure if that's the (only?) issue, but it did get my attention.
HTH
"How we think determines what we do, and what we do determines what we get."
Sorry, just saw the using statement for Tagit namespace.
Please disregard.
"How we think determines what we do, and what we do determines what we get."
It's looking like you're going to have to use COM, my friend... Everything I'm finding for .NET + Mechanical is in COM.
Perhaps someone more knowledgeable than I can verify?
"How we think determines what we do, and what we do determines what we get."
jup, only found references to com and c++, but i still find it strange, ive developed for plant3d and other verticals without problem, and still find it hopeful that it actually loads the dll and enters the Initialize function, noticed that when i installed mechinical that it upgraded my vanilla autocad to service pack 1 as well (it seems to use the same autocad executable), and also now that i run it in vanilla, that my commands are not available... maybe its an upgrade issue??
strange...
Thanks a lot for your efforts blackbox though,
rewriting it is not really an option (3-4000 lines of code), so at least would be nice to have it from an official source that ac mechanical is not comaptible with managed .net
or does anyone know if the service pack makes any difference?
@Anonymous wrote:
Thanks a lot for your efforts blackbox though,
You're welcome; I'm always happy to not help. LoL
Cheers
"How we think determines what we do, and what we do determines what we get."
Put a try/catch around the code in your IExtensionApplication::Initialize function that prints the info about the caught exception, then let us know what the exception is when you try to NETLOAD your DLL.
Hi,
>> but when i run netload on my dll nothing happens and my command is not available.
>> Some googling gave me the impression that autocad mechanical only has a COM and c++ api, is that correct?
If AutoCAD Mechanical has a command _NETLOAD then it is able to load .NET assembly-DLL's and so supports the .NET api.
You should verify that you have not set the "copy-local" property for AutoCAD-references (like acdbmgd.dll, acmgd.dll, accoremgd.dll, ...).
And as it happens sometimes without an error output ... keep in mind that without special settings a .NET DLL can only be loaded into AutoCAD when it's on your local drive (is seen as trusted), verify that your Mechanical-user does not try to load it from network.
HTH, - alfred -
Thanks for all the responses!
Try/Catch was the trick!
depended on having a searchpath set for block which of course wasnt set when mechanical got installed... big duh to me
Still scary the way it fails silently and doesnt show commands, good to know for another time 🙂
@Alfred.NESWADBA wrote:... keep in mind that without special settings a .NET DLL can only be loaded into AutoCAD when it's on your local drive (is seen as trusted), verify that your Mechanical-user does not try to load it from network.
For those who may be interested, the special setting is to enabled the LoadFromRemoteSources element:
"How we think determines what we do, and what we do determines what we get."
Hi,
>> For those who may be interested, the special setting is to enabled the LoadFromRemoteSources element:
To complete this: this only works for Framework 4.0 (and newer), so starting with AutoCAD 2012, but not before (there the CASPOL.EXE has to be used if loading of assemblies through network is necessary).
- alfred -
@Alfred.NESWADBA wrote:Hi,
>> For those who may be interested, the special setting is to enabled the LoadFromRemoteSources element:
To complete this: this only works for Framework 4.0 (and newer), so starting with AutoCAD 2012, but not before (there the CASPOL.EXE has to be used if loading of assemblies through network is necessary).
- alfred -
Hi Alfred,
Thanks for the clarification.
I've actually never used CASPOL.exe personally (probably in use before I even learned what LISP was?), so I certainly cannot comment on advantages, etc., however, speaking from personal experience enabling LoadFromRemoteSource in 2011 (we use Civil 3D) does in fact allows one to load .NET 3.5 compiled assemblies saved to network. Kean's methodology solved this issue for my work +/-3 years ago, and has not presented a single issue since.
I cannot comment on how this would, or would not affect 2010 and older.
Cheers
"How we think determines what we do, and what we do determines what we get."
Hi,
surprise, surprise, whatever you have found, Microsoft tells us that it started with Framework 4.0 >>>click<<<.
But when it was working for you then it was a solution to you.
- alfred -
@Alfred.NESWADBA wrote:Hi,
surprise, surprise, whatever you have found, Microsoft tells us that it started with Framework 4.0 >>>click<<<.
But when it was working for you then it was a solution to you.
- alfred -
Perhaps you, or Owen could educate me... Just trying to better understand, as I claim no expertise here, I wonder... Is it possible that this only worked for us in 2011, as we also had 2012 installed (.NET 4.0)?
Revisiting Kean's Acad.Exe.Config code snippet, there is a line here:
<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> </startup>
... Which *may*explain why this is successful in 2011, despite that version being .NET 3.5 dependent. I do not have any system that only has 2011 to test my theory.
Cheers
"How we think determines what we do, and what we do determines what we get."
Hi,
in that case I guess your project is set to Framework 4.0, so you get the runtime-security options available for AutoCAD 2011.
Look to your project settings and the active Framework version.
- alfred -
"How we think determines what we do, and what we do determines what we get."
Hi,
sorry to say, in that case (your project is 3.5 and AutoCAD 2011) I have no idea why the switch LoadFromRemoteSources is working.
But I have also to say that I have not tried to reproduce it now.
Let's say thanks to your system that something is working, better than something is not working 😉
- alfred -
Can't find what you're looking for? Ask the community or share your knowledge.