How to use config files with Autocad .net DLLs?

How to use config files with Autocad .net DLLs?

BKSpurgeon
Collaborator Collaborator
8,252 Views
14 Replies
Message 1 of 15

How to use config files with Autocad .net DLLs?

BKSpurgeon
Collaborator
Collaborator

Hi folks

 

I have created an autocad .net dll. it compiles and runs fine on my computer. I am also connecting to a database. So I am using Visual Studio to store a connection string to that databse. This connection string basically tells whoever's asking, where my Database is. I have stored this connection string using Visual Studio. Basically, in Visual Studio: you click on: Project --> Project_name Properties ---> And you have all the application/user settings. I've just added a connection string there.

 

(Please see attached screen capture):

 

 

Here is how I create the connection in my code:

 

 OleDbConnection connection = new OleDbConnection(Bubble_Deck.Properties.Settings.Default.Bubble_DeckConnectionString);

In other words it doesn't look like (???) i'm hard coding this because the connection string looks at what the XML file contains.

 

And the value of the connection string is:  Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Koshy\Documents\Drawings and Clients\Bubble Deck3.mdb

 

 

What is the problem?

Works fine on my computer. But what if want to deploy it to another computer? 

 

What I'm doing now when deploying?

I simply go to the Release folder in Visual Studio. I cut and paste the dll in that folder and I give it to my colleague. He then runs it but there's an error: 

 

           "Could not find the file 'C:\Users\Koshy\Documents\Drawings and Clients\Bubble Deck.mdb" at ......etc etc etc 

 

Now on my colleague's computer, I want to change the connection string so that it points to the database on his particular machine. Because it is obviously still pointing to the path specified in my computer. How do I do that?

 

Obviously it's coded somewhere in my DLL because it's doing that without even me giving my colleague a config file.

 

In short, how do I change the connectionString to point to the new database location on his computer?

  • Do I need to copy over the dll's config file and paste the contexts of that file into acad.exe 's config file?

I'm very lost as to how this works. It will probably take you guys less than 2 minutes to work this out, but me, knowing nothing, i am sure it could quite easily take me 2 hours, if not 2 days to work it out. any advice much appreciated.

 

regards

 

 

BK

 

 

 

 

Resources for those researching this problem in the future:

Here are some wonderful links (and attachments) on configuration files - which i'm steadily working through. I trust future readers will find them useful.

 

http://adndevblog.typepad.com/aec/2014/09/get-value-from-appconfig-file-and-sur-la-france.html

http://weblog.west-wind.com/posts/2012/Dec/28/Building-a-better-NET-Application-Configuration-Class-...

http://www.codeproject.com/Articles/16466/Unraveling-the-Mysteries-of-NET-Configuration

 

- Please see attached pdf document - a valuable resource.

 

 

0 Likes
Accepted solutions (3)
8,253 Views
14 Replies
Replies (14)
Message 2 of 15

norman.yuan
Mentor
Mentor

When you add settings via Project->Properties->Settings, VisualStudio generates "app.config" as source file. However, depending on your project type (DLL or EXE), the build-output file of this app.config is different: for EXE app, it is xxx.exe.config, for DLL, it is xxx.dll.config. Just as you need to deploy the xxx.exe.config with your EXE application, you need to deploy xxx.dll.config along with your DLL.

 

Actually, when wirking with AutoCAD .NET API, you have 2 choices of sacing your settings in config file:

 

1. AutoCAD has its own EXE config file (acad.exe.config). You can add settings into that file, and use System.Configuration namespace classes to access the settings.

 

2. Use Propect->Properties->Settings of your DLL project, just as you did. You need to make sure the xxxx.dll.config file goes with your DLL when deploying.

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 15

Anonymous
Not applicable

Try looking at Environment variables as a safe location to save your db too.

I'm assuming that you want your .ini to be in the same logical place

for each users install.

 

Dim iniLocVal As String = Environment.GetEnvironmentVariable("UserProfile") & "\AppData\Roaming\Myfolder\MyIni.ini"

 

Message 4 of 15

dgorsman
Consultant
Consultant

Given that you may need to change where to look for any number of instances, its a good idea to look at already established methods:

  • use a standardized folder and file name.  Must be the same on every computer.  Easiest to do but can cause problems for user-specific settings.
  • use a registry key & value.  Must be the same on every computer, but the contents can be changed easily to other paths and file names.  Allows for per-user and per-computer persistent settings.  Slightly more work, and could run into problems with restricted rights.
  • use a dedicated settings file.  Allows for fully customized format.  More work, usually requires building a user interface.  Requires a means for the program to find the file.

 

These are usually combined in some fashion ie. registry entries are added to point to the install location, which is searched for a standard sub-folder(s) with a configuration file.  Have a look into the AutoCAD sections of the registry to see how they do it - some of it's not optimal but for the most part its a good example of different ways of dealing with this.

 

 

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 5 of 15

BKSpurgeon
Collaborator
Collaborator

Hello Thank you all for your advice. It will be invaluable to future readers.

 

> Use Propect->Properties->Settings of your DLL project, just as you did. You need to make sure the xxxx.dll.config file goes with your DLL when deploying.

 

I've simply given my colleague my dll and the associated config file (which as you pointed out, was named after my dll). (No installers)

 

When I netload the dll on his computer, it seems as if the dll is not even referring to what is contained in the config file. I seem to be missing something here.

 

The connection string contains the location of my database. So obviously on my colleagues computer, I would have to point the connection string to where the database resides on his computer (as opposed to mine). But no matter what I do to his config file (which stores the connection string) -  when i netload Autocad is still looking for the database location on my computer as opposed to his. I have even deleted his config file altogether, but still the connection string source points to the database path on my computer. In other words, the XML file seems completely superfluous.

 

This is how I"m referring to the XML file to pick up the connection string from the XML file:

 

OleDbConnection connection = new OleDbConnection(Bubble_Deck.Properties.Settings.Default.Bubble_DeckConnectionString);

 

In other words how should I refer to the config file from my DLL so my dll will pick up all the settings stored in the xml file?

 

 

I don't know how to fix this. Any advice would be much appreciated.

 

rgds

 

BK

 

 

Message 6 of 15

dgorsman
Consultant
Consultant

First order of business - don't put program content in a path that is dependant on a specific user.  Use those paths for per-user content - UI element positions, active project pointer/name, and so on.  Most of the time thats simple enough that a database is overkill.  Anything along the lines of program or project data should be in the same place regardless of user; the possibility of shared/common network locations should also be taken into consideration even if not fully implemented.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 7 of 15

BKSpurgeon
Collaborator
Collaborator

All agreed - 100%. 

 

this error i'm getting confusing. I have created a hello world application to get to the bottom of this. Check it out - it's most curious.

 

What does it do?

It looks for a string value in the xml file. It should then print that particular string value to the autocad editor window. It should print "ItsWorking!" because that is the value in the config file. But for one reason or another, Visual Studio hard codes the default settings value originally set when i was coding, rather than reading the values in the xml config file.

 

Check it out: i'd be curious to hear what you all think.

0 Likes
Message 8 of 15

Keith.Brown
Advisor
Advisor

Maybe off topic but I found the article below many years ago and still use those classes today to create and save settings.

 

http://www.codeproject.com/Articles/5304/Read-Write-XML-files-Config-files-INI-files-or-the

Message 9 of 15

norman.yuan
Mentor
Mentor
Accepted solution

Well, I could not say what is wrong in your code/project without seing/opening your project in VisualStudio, it should be as simple as deploying the xxx.dll.config file with the DLL together.

 

To prove it, I just created a very simple DLL project.

 

Here is the code:

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(DllAppSettings.MyCommands))]

namespace DllAppSettings
{
    public class MyCommands 
    {
        [CommandMethod("MyCmd", CommandFlags.Session)]
        public static void RunMyCommand()
        {
            Document dwg = CadApp.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            ed.WriteMessage(
                "\nConnectionString-{0}", Properties.Settings.Default.MyConnection);
        }       
    }
}

Here is the picture of the project's Properties->Settings window:

 

Properies_Settings.png

 

This is the picture of app.config in the project, which is generated by VisualStudio automatically after a setting is added into the project:

 

App.config.png

 

This is the picture of the generated output xxx.dll.config file, which should go together with the DLL file:

 

Dll_Config.png

 

I did the project with AutoCAD 2015 and VisualStudio2013.

 

Now, I copied the these 2 files

 

DllAppSettings.dll

DllAppSettings.dll.config

 

to 2 other computers with AutoCAD installed (one is AutoCAD2015 and ther other is AutoCAD 2016), NETLOADED the dll into AutoCAD, enter command "MyCmd". Guess what? it works as exactly expected: the setting value is correctly read by the code.

 

Attached is the whle project, if you want to try.

 

To be honest, I have no idea why such a simple thing would be an issue on your side, thus I pictured all the details how it should work.

 

Hope this helps.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 10 of 15

Keith.Brown
Advisor
Advisor
Accepted solution

Your dll will automatically create the config file the first time it is ran with the default settings that you specifiy in the properties.  I am pretty sure that supplying the config file will do nothing for you unless you copy it to the correct location which is buried pretty deep.  You can search for the location with google

You should really not be using the application settings to save your information.  Because your application is ran inside of Autocad, the config file is linked to autocad in some way.  If you supply mechanisms for the user to change the settings they will save correctly to the config file.  However, if you update to a newer version of autocad or if you apply a service pack you will lose all of your settings as the config file will reset to the default settings that are in your dll.

 

If you really want to use the config file then you will need to save your database in a place that is common to every computer or you will need to break your connection string in to several parts as Quigs pointed out above.  If you know the database is in the Documents folder then use .net tools to point to each users document folder and then add the rest of the connection string.

 

** Edit:** check out article. http://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files

 

The thing to remember is that your application is not the application that is storing the config file.  AutoCAD is the application.  This is why you should avoid using the config files if all possible.

Message 11 of 15

norman.yuan
Mentor
Mentor
Accepted solution

Hi Keith,

 

I have to disagree with you. There is nothing wrong using .NET built-in application setting mechanism (*.config), be the project is DLL or EXE. In early version of .NET (1.x for sure), there is only app.config can only be outputed as *.exe.config. Output app.config as *.dll.config was only available in later version (since .NET2.x or 3.x, I could not remember exactly).

 

I remebered when I started Acad .NET API programming with .NET 1.1, I had to place some of app settings in acad.exe.config, which caused technical diificulty when the app settings needed update, because acad.exe.config usually is located in C:\Program files\... folder, along with acad.exe, and that folder most likely a read-only to non-local admin users. with *.dll.config, as long as it goes with the DLL, all the settings in it can be accessed just as in *.exe.config. Now, with *.dll.config, in some CAD applications, I no longer need to update acad.exe.config, if some settings are needed. I can place them in the DLL's Properties->Settings, which eventually go to *.dll.config. But to be honest, I rarely use *.config file for Cad apps I developed, because we are in a corporate environment, we have a centralized app setting system for all application level settings. Only when very few user level settings are stored in *.dll.config files.

 

Also, with app.config, the settings can be in 2 scopes: application and user. for application level of settings, they are read-only once they set in the config file. However, for user level of settings, the values in the config file are default value, after the first time run of the DLL, a copy of the config (be it *.exe.config, or *.dll.config) would be created in user's profile folder (C:\Users\[user name]]\app data\local....the value of the settings in user copy of the config file can be updated. 

 

To the OP's case, if not taking security (exposing database connection information) into account, there is nothing wrong to store the connectionstring as application setting in the config file. While in my reply I used application level setting, the OP may want to use user level setting with default database connection. Then he/she can use code to handle DB file not found exception to allow user to choose a different database file in user computer, and then save the new connectionstring to the user level setting, so that the setting would be used when that user logs in this computer and runs the app.

 

The only thing that puzzles me is why the simply mechanism of *.exe/dll.config not working for the OP

Norman Yuan

Drive CAD With Code

EESignature

Message 12 of 15

Keith.Brown
Advisor
Advisor

Hi Norman,  I would certainly defer to your knowledge of the subject.  I can only relate to my own experience of using the settings file.  I know that in my case that I never had to ship the settings file with my app.  The application created it the first time it was ran using the values that were in the settings dialog.  (I didnt know how to override this behavior)  In the app i had dialogs that would allow the user to customize the settings to whatever they want and would save the settings to the config file.  However, anytime that AutoCAD was updated to a new version or a Service Pack was installed the settings would revert back to their default state.  It would be nice to know how to stop this from happening!

 

Taking all of this into account and using the link I posted about the custom settings file, I created my own settings class that would allow me to save as either xml or in the registry.  I like the xml option because it allowed me to easily create import/export functionality for the user.  One user can change the settings to what they desire and then share with the rest of the user base.

Message 13 of 15

BKSpurgeon
Collaborator
Collaborator

Thank you for your clear explanations Norman and Keith.

 

I was wondering why it wasn't working.

 

For those reading in the future, here is what i was trying to do:

 

  1. create a config file (with user and application config settings).
  2. deploy to another computer.
  3. I was then changing the connection string settings from within the config file i deployed to the other computer ----> big mistakes. If you want to change the config file settings, then you can change the user level config settings by looking deep within your user settings folders.
  4. If you want to change the application level configuration settings after deploying to a new computer - then you cannot do it at all ----> Do I have this correct Norman?
0 Likes
Message 14 of 15

norman.yuan
Mentor
Mentor

Sorry to come back to this topc very late.

 

I was only partially correct on what I said previously about *.dll.config, and wasn't explain clearly (or correctly) what would happen when you done with your coding and try to use the dll with its *.dll.config in different computer with different setting values. 

 

I happened run into an article that has a quite complete explanation on how to use configuration settings with .NET DLLs, which would definitely be very helpful:

 

http://www.sep.com/sep-blog/2010/09/05/configuration-settings-for-net-class-libraries-dlls/

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 15 of 15

Anonymous
Not applicable

NET API for reading and writing user-related directories. In principle, it should be a low-privilege access directory unrelated to the user directory, such as the Documents directory.

0 Likes