.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

cuiload from .NET dll

3 REPLIES 3
Reply
Message 1 of 4
Anonymous
1430 Views, 3 Replies

cuiload from .NET dll

Hi,
Can anybody explain the strange behavior of this peace of code.
This .dll is registered in order to load on startup.
{code}
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\TestCAD2]
"DESCRIPTION"="Ognyans test app"
"LOADCTRLS"=dword:00000002
"MANAGED"=dword:00000001
"LOADER"="C:\\work\\LocalTestProjects\\acad_CUI\\acad_CUI\\bin\\Debug\\acad_CUI.dll"
{code}

1. When I comment out the "initialize" method the module is starting but the class constructor (Class1) is not starting until I invoke "c1" or "c2".
2. When I don`t comment out anything the program "brakes" in the initialize method in the line
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false, false); but Autocad continues to work without error prompt, but no CUI is loaded.
3. After deleting the registry info and when I netload the .dll without commenting out any code the initialize method the .dll is loaded and the cui is loaded - everything is fine.
c1 command is working fine when netload-ed by hand.

Why is that? To me it looks like that Acad cant receive the command for loading the cui before it loads some other stuff after.
If you place a message in the initialize method the message will appear before the last Acad default console messages.
Is there a way to tell the initialize method to wait until Acad is ready to receive?

{code}
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Customization;

namespace ClassLibrary1
{
public class Class1 : IExtensionApplication
{
public Class1()
{
//throw new System.Exception("The method or operation is not implemented.");
string cuiFile = "C:\\test.cui";
Document doc = Application.DocumentManager.MdiActiveDocument;
object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
object oldFileDia = Application.GetSystemVariable("FILEDIA");
Application.SetSystemVariable("CMDECHO", 0);
Application.SetSystemVariable("FILEDIA", 0);
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false, false);
doc.SendStringToExecute("(setvar \"FILEDIA\" " + oldFileDia.ToString() + ")(princ) ", false, false, false);
doc.SendStringToExecute("(setvar \"CMDECHO\" " + oldCmdEcho.ToString() + ")(princ) ", false, false, false);
}
[CommandMethod("c1")]
public void c1()
{
string cuiFile = "C:\\test.cui";
Document doc = Application.DocumentManager.MdiActiveDocument;
object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
object oldFileDia = Application.GetSystemVariable("FILEDIA");
Application.SetSystemVariable("CMDECHO", 0);
Application.SetSystemVariable("FILEDIA", 0);
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false, false);
doc.SendStringToExecute("(setvar \"FILEDIA\" " + oldFileDia.ToString() + ")(princ) ", false, false, false);
doc.SendStringToExecute("(setvar \"CMDECHO\" " + oldCmdEcho.ToString() + ")(princ) ", false, false, false);
}

[CommandMethod("c2")]
public void c2()
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Hello World!");
}

#region IExtensionApplication Members
void IExtensionApplication.Initialize()
{
//throw new System.Exception("The method or operation is not implemented.");
string cuiFile = "C:\\test.cui";
Document doc = Application.DocumentManager.MdiActiveDocument;
object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
object oldFileDia = Application.GetSystemVariable("FILEDIA");
Application.SetSystemVariable("CMDECHO", 0);
Application.SetSystemVariable("FILEDIA", 0);
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false, false);
doc.SendStringToExecute("(setvar \"FILEDIA\" " + oldFileDia.ToString() + ")(princ) ", false, false, false);
doc.SendStringToExecute("(setvar \"CMDECHO\" " + oldCmdEcho.ToString() + ")(princ) ", false, false, false);
}
void IExtensionApplication.Terminate()
{
throw new System.Exception("The method or operation is not implemented.");
}
#endregion
}
}
{code}
3 REPLIES 3
Message 2 of 4
_gile
in reply to: Anonymous

Hi,

I suppose you can't invoke SendStringToExecute before the the document initialization is completed.

You can make a CuiLoad method using COM interop.

Here's an example:
{code}
private void CuiLoad(string filename, string menuGroup)
{
AcadApplication acadApp = (AcadApplication)Application.AcadApplication;
AcadMenuGroups menus = acadApp.MenuGroups;
try
{
menus.Item(menuGroup);
}
catch
{
menus.Load(filename, false);
}
}{code}
using:
CuiLoad("C:\\test.cui", "TEST");

Or, if you want to add a popup menu to the end of the the menu bar:
{code}
private void CuiLoad(string filename, string menuGroup, string menuName)
{
AcadApplication acadApp = (AcadApplication)Application.AcadApplication;
AcadMenuGroups menus = acadApp.MenuGroups;
try
{
menus.Item(menuGroup);
}
catch
{
menus.Load(filename, false);
AcadMenuBar mnuBar = acadApp.MenuBar;
menus.Item(menuGroup).Menus.Item(menuName).InsertInMenuBar(mnuBar.Count);
}
}{code}

using:
CuiLoad("C:\\test.cui", "TEST", "&Test") Edited by: _gile on Jan 2, 2010 7:48 PM


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 4
Anonymous
in reply to: Anonymous

When you apply the CommandMethod attribute to a non-static method, AutoCAD's
managed runtime will create multiple instances of your class, one for each
document that you invoke the command in. Those instances are not created until
you invoke the command.

The problem you have is that AutoCAD's managed runtime also creates an instance
of the class with the IExtensionApplication attribute on it as well, so multiple
instances of your class are getting created, which obviously wasn't your
intention.

For one thing, it's not wise to implement commands in the same class that
implements IExtensionApplication, but if you really wanted to do that, you could
if you make the command handler methods static. If you're not sure about the
difference between static and non-static (or 'instance') methods, get a hold of
some basic C# learning materials, and try to become more familar with the basic
concepts that underly the tools you're working with.

To solve your immediate probelm, just create another class for the commands, and
unless you want AutoCAD to create multiple, per-document instances of the class,
declare the methods that have the CommandMethod attribute as static methods.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD
Supporting AutoCAD 2000 through 2010

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

wrote in message news:6311255@discussion.autodesk.com...
Hi,
Can anybody explain the strange behavior of this peace of code.
This .dll is registered in order to load on startup.
{code}
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD\R17.1\ACAD-6001:409\Applications\TestCAD2]
"DESCRIPTION"="Ognyans test app"
"LOADCTRLS"=dword:00000002
"MANAGED"=dword:00000001
"LOADER"="C:\\work\\LocalTestProjects\\acad_CUI\\acad_CUI\\bin\\Debug\\acad_CUI.dll"
{code}

1. When I comment out the "initialize" method the module is starting but the
class constructor (Class1) is not starting until I invoke "c1" or "c2".
2. When I don`t comment out anything the program "brakes" in the initialize
method in the line
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false, false); but
Autocad continues to work without error prompt, but no CUI is loaded.
3. After deleting the registry info and when I netload the .dll without
commenting out any code the initialize method the .dll is loaded and the cui is
loaded - everything is fine.
c1 command is working fine when netload-ed by hand.

Why is that? To me it looks like that Acad cant receive the command for loading
the cui before it loads some other stuff after.
If you place a message in the initialize method the message will appear before
the last Acad default console messages.
Is there a way to tell the initialize method to wait until Acad is ready to
receive?

{code}
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Customization;

namespace ClassLibrary1
{
public class Class1 : IExtensionApplication
{
public Class1()
{
//throw new System.Exception("The method or operation is not
implemented.");
string cuiFile = "C:\\test.cui";
Document doc = Application.DocumentManager.MdiActiveDocument;
object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
object oldFileDia = Application.GetSystemVariable("FILEDIA");
Application.SetSystemVariable("CMDECHO", 0);
Application.SetSystemVariable("FILEDIA", 0);
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false,
false);
doc.SendStringToExecute("(setvar \"FILEDIA\" " +
oldFileDia.ToString() + ")(princ) ", false, false, false);
doc.SendStringToExecute("(setvar \"CMDECHO\" " +
oldCmdEcho.ToString() + ")(princ) ", false, false, false);
}
[CommandMethod("c1")]
public void c1()
{
string cuiFile = "C:\\test.cui";
Document doc = Application.DocumentManager.MdiActiveDocument;
object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
object oldFileDia = Application.GetSystemVariable("FILEDIA");
Application.SetSystemVariable("CMDECHO", 0);
Application.SetSystemVariable("FILEDIA", 0);
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false,
false);
doc.SendStringToExecute("(setvar \"FILEDIA\" " +
oldFileDia.ToString() + ")(princ) ", false, false, false);
doc.SendStringToExecute("(setvar \"CMDECHO\" " +
oldCmdEcho.ToString() + ")(princ) ", false, false, false);
}

[CommandMethod("c2")]
public void c2()
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Hello
World!");
}

#region IExtensionApplication Members
void IExtensionApplication.Initialize()
{
//throw new System.Exception("The method or operation is not
implemented.");
string cuiFile = "C:\\test.cui";
Document doc = Application.DocumentManager.MdiActiveDocument;
object oldCmdEcho = Application.GetSystemVariable("CMDECHO");
object oldFileDia = Application.GetSystemVariable("FILEDIA");
Application.SetSystemVariable("CMDECHO", 0);
Application.SetSystemVariable("FILEDIA", 0);
doc.SendStringToExecute("_.cuiload " + cuiFile + " ", false, false,
false);
doc.SendStringToExecute("(setvar \"FILEDIA\" " +
oldFileDia.ToString() + ")(princ) ", false, false, false);
doc.SendStringToExecute("(setvar \"CMDECHO\" " +
oldCmdEcho.ToString() + ")(princ) ", false, false, false);
}
void IExtensionApplication.Terminate()
{
throw new System.Exception("The method or operation is not
implemented.");
}
#endregion
}
}
{code}
Message 4 of 4
Anonymous
in reply to: Anonymous

Thanks to both of you!
Your hints are most helpful!
I did not know that Acad instantiates the class for every single document. You are right that all the methods should be static.
The final goal achieved is a program that is installed just with xcopy that reconstructs its Cui when it detects the update of the dll holding the command methods. Making it that way saves a lot of maintenance work of the installations on multiple computers in one office.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost