« Launching AutoCAD from a .NET application | Main | Microbenchmarking C# code »
Getting AutoCAD's current directory from a .NET application
This question came in via a comment from Danny Polkinhorn on this post:
After AutoCAD has launched, I often have a need to determine the "Start In" directory specified in the shortcut (Right-click AutoCAD shortcut, Properties, Start in). Is there a way to determine what that directory is? I'm thinking I can use the path of the active drawing (either Drawing1 or the drawing they double-clicked on). Is that a fool-proof way?
This is an interesting topic, and raises the questions of what that the "Start In" setting is used for and how it can be modified.
The "Start In" property in a Windows shortcut specifies the initial "current directory" for a process. The concept of a current or working directory is common across the various Operating Systems I've worked with: processes have a current directory which is the default file-system folder used for certain operations (such as opening a drawing inside AutoCAD). It is also used by Windows when attempting to locate DLLs to load.
As Danny mentions, it is possible to specify the current directory for a process when it is launched: common ways are to edit the "Start In" property in the shortcut used to launch the application, to change the current directory (using CHDIR or CD) in a command-prompt window and launch the executable from there, or even to specify the working directory for an application to be launched from the Visual Studio debugger. And while the current directory is generally specified as the process starts, it can also change during execution.
AutoCAD 2008's default "Start In" location is "C:\Program Files\Autodesk\AutoCAD 2008\UserDataCache\". Just to verify the process of querying it from an application, I copied the standard shortcut and modified the property to "c:\temp":
I know of two ways to query this property:
System.Environment.CurrentDirectory
System.IO.Directory.GetCurrentDirectory()
I created a simple command, CURDIR, to query this property and print the results.
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
namespace CurrentDirectory
{
public class Commands
{
[CommandMethod("CURDIR")]
public void GetCurrentDirectory()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ed.WriteMessage(
"\nSystem.Environment.CurrentDirectory: "
+ System.Environment.CurrentDirectory
+ "\nSystem.IO.Directory.GetCurrentDirectory(): "
+ System.IO.Directory.GetCurrentDirectory()
);
}
}
}
This code works very well, but it may not return the results expected, depending on when the command is executed and - in particular - how the module is loaded. If we use demand-loading to load your module, it will generally returns the results we expect, assuming it runs early enough. Here's what's returned by the CURDIR command once it has demand-loaded our module in the instance of AutoCAD created by the modified shortcut:
Command: curdir
System.Environment.CurrentDirectory: C:\temp
System.IO.Directory.GetCurrentDirectory(): C:\temp
If, on the other hand, we use the NETLOAD command to load our module, we get the directory from which it was loaded:
Command: netload
Command: curdir
System.Environment.CurrentDirectory: C:\Program Files\Autodesk\ObjectARX
2008\samples\dotNet\Prompts\bin\Debug
System.IO.Directory.GetCurrentDirectory(): C:\Program Files\Autodesk\ObjectARX
2008\samples\dotNet\Prompts\bin\Debug
It took me some time to realise what was happening: it appears that the standard "file navigation" dialog inside AutoCAD - whether it's being used to open a drawing, load an application or perform an action on another type of file - sets the current directory to its most recent location, the first time it is run and closed. So even if you escape from the OPEN command, the location to which you had browsed before cancelling becomes the new current directory.
Whether this is intuitive or expected isn't really for me to say (although I can understand why people might have an opinion). The moral of the story is that you cannot reliably determine the "Start In" folder for AutoCAD (or any other complex application, in reality), unless you ask it very early on in its execution. Code hosted in the process can modify this setting as it feels it needs to.
While not 100% reliable - there are no guarantees some other code has not modified the property beforehand - your best chance at identifying the "Start In" location is to have an application module load on AutoCAD start-up and query it there.
December 17, 2007 in AutoCAD, AutoCAD .NET | Permalink
TrackBack
TrackBack URL for this entry:
http://www.typepad.com/t/trackback/876965/24274900
Listed below are links to weblogs that reference Getting AutoCAD's current directory from a .NET application:
Comments
Wow, I wasn't expecting an entire post! Thanks a ton, this definitely confirms some of my earlier testing. I have a dll loading at startup so I'll be sure to check it there.
Thanks again!
-Danny
Posted by: Danny Polkinhorn | Dec 18, 2007 8:12:14 AM
Kean! There are real problems with AutoCAD default directory. Some months ago I put an article "Little Tricks of Default Directory" by S.Vasiliev at my site -
http://www.private.peterlink.ru/poleshchuk/cad/2007/deffoldere.htm
Posted by: Nikolay Poleshchuk | Dec 18, 2007 9:02:09 AM
Hi Kean,
Really interesting behavior.
What about .NET DLLs placed into .NET Assembly Cache?
BTW, this raises another question. Which is the best option for .NET DLLs. Place them inside AutoCAD's root folder or inside GAC?
I have faced some issues regarding to NETLOAD loading the .NET DLL we expect...
Best regards,
Fernando.
Posted by: Fernando Malard | Dec 18, 2007 11:32:03 AM
Hi Fernando,
The recommendation I've heard is to use AutoCAD's root folder. I'm not sure of the benefits or disadvantages of using the GAC.
Regards,
Kean
Posted by: Kean | Dec 18, 2007 11:55:37 AM
Kean,
Yes. I'm doing this way. The problem is when you need to support multiple versions and flavors of AutoCAD. It's not a good idea to have the same DLL copied inside each AutoCAD folder.
In this case would be the Autodesk Commom folder a better solution?
Maybe place the DLLs at the product folder and add its path to each AutoCAD support path list?
Regards,
Posted by: Fernando Malard | Dec 18, 2007 12:21:11 PM
I don't know that it's "not a good idea"... we've gone back to a per-product install of lots of our "shared" files: it helps avoid compatibility issues if a shared file is badly "upgraded" by one of the sharing products. It also gives more flexibility to have per-product implementations.
The choice is ultimately yours, of course.
Kean
Posted by: Kean | Dec 18, 2007 1:25:20 PM
Kean,
Yes, it will be always a pain to support multiple versions and there is no magic solution. All solutions will always give you both good and bad things.
In fact, in my opinion, GAC does not solve this problem once it allows several copies of the same named DLL but with different versions. This may confuse and create more problems than solutions. For me, the so called "DLL hell" was just renamed to "GAC Hell". For instance, in my machine I can see two copies of "Autodesk.AutoCAD.Interop". One has version 17.0.54.0 and the other 17.1.51.0. Even worst, there are 10 copies of "Microsoft.DirectX.Direct3DX" DLLs.
You are 100% right. The most secure way is to keep specific versions, per product, inside its directory and only share global modules that may not affect the way each version works after each update or service pack.
Thanks for sharing your (Autodesk) experience with this. This type of information is very important and should be at SDK documentation too. :)
Regards,
Posted by: Fernando Malard | Dec 18, 2007 1:43:25 PM
Can i use existing drawing for customization using .net to save time to redraw through .net.?
Manoj
Posted by: Manoj | Dec 24, 2007 10:11:29 AM
Hi Manoj,
It depends on the situation. There's not really enough information for me to know what you're trying to do...
Kean
Posted by: Kean | Jan 2, 2008 10:11:18 AM

Atom
