# ESRI ArcMap Add-in with app.settings not recognizing app.config changes

I have an ESRI Add-in developed for ArcMap which requires a configuration file. After spending a while trying to read config values from a single App.Config file (and always getting null) I believe that the Add-in cannot read values from here as it is a class library, and looks for the calling application (ArcMap)'s config file when I ask for a key's value (hence the null).

To get around this I used an App.Settings file, which the application can read fine. Creating this also introduces an App.Config file into the environment and Visual Studio seems to keep the two files in-sync during development.

Now that the Add-in is being deployed I need to be able to change configuration values (e.g. log file location). I have tried opening / extracting the .esriaddin file and updating the App.Config file in there but the Add-in retains the same configuration values it had when compiled. I know that the new App.Config values are being persisted in the .esriaddin file because I can view them again after closing the archive.

Does anyone know a reliable way to configure an Add-in and permit this configuration to be updateable once deployed? Any suggestions very welcome as it seems ridiculous that I should need a custom config file for this.

App.Settings values are at the application level, and currently both App.Settings and App.Config have build action: none / do not copy.

-

string configPath = System.IO.Path.Combine(this.GetType().Assembly.Location,"Config.xml");

-
Thanks for the tip, the path created by the above is not valid as it gives .../addInName.dll/config.xml, but it got me on the right track. I'm now using the slightly simpler this.GetType().Assembly.Location + ".config" – tomfumb Apr 27 '11 at 19:51

Right so I figured out how to configure the addin. Thanks to the suggestions from other people - I've commented where relevant - I'm not simply adding my own answer for point-whoring purposes, but none contained the full approach.

The addin file in ...Documents\ArcGIS\AddIns\Desktop10.0... gets expanded every time ArcMap loads, so the only place that ANY config files embedded in the addin can be edited is in here. I didn't experiment with using registry keys or using a dedicated addin configuration directory as this just seemed overkill.

In the end I used an app.config file (because even if used with a class library, which ignores the config file, it still gets renamed in line with the assembly and automatically included in the addin archive) for my settings. Based on a link provided above I used the following configuration class

 ...

 public AppConfig() { try { ExeConfigurationFileMap map = new ExeConfigurationFileMap(); map.ExeConfigFilename = this.GetType().Assembly.Location + ".config"; config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); } catch (Exception) { ... } } private string getValue(string key) { return config.AppSettings.Settings[key].Value; } 

... 

To edit the config once the addin is deployed I had to close ArcMap, open the .esriAddIn file with winrar, go to \install and open the config file, edit it, close the editor, and then allow winrar to update the file within the archive. Then reloading ArcMap the change goes in. Annoyingly this is one of the first things I tried but I think I had problems because the editor for the config file was still open when winrar updated the archive.

-
Have you run into any errors lately with OpenMappedExeConfiguration? I was using a similar approach that worked fine until, just a couple of days ago, it stopped working, perhaps after installing some Windows Updates. See this StackOverflow question of mine. – blah238 Jul 29 '11 at 21:17
@blah238 I haven't tested this add-in for a while and don't have the opportunity to right now. However if you can summarise your recent Windows / .NET updates I can see if mine (Win7) match and let you know – tomfumb Jul 30 '11 at 18:49
The only one I saw that seemed relevant was a .NET 4 security update. Not sure if that also might affect .NET 3.5 which is what I am targeting. – blah238 Jul 30 '11 at 19:55
FYI, I ended up re-writing the configuration logic of my add-in to use traditional XML (de)serialization instead of the .NET configuration system, the main draw of which I figured was that the .config file is automatically extracted along with the assembly from the .esriAddin file -- something you can't, as far as I can tell, do with an arbitrary XML file -- but for my purposes I decided I didn't really need to supply a default configuration, only persist user-specific settings). I would still like to know if this is also affecting other add-in developers, though. – blah238 Aug 2 '11 at 1:02
Poking around a bit more with the .config approach and Fusion reveals that ESRI is using Assembly.LoadFrom() to load add-in assemblies. From what I have read this goes against the best practice which is setting up a separate AppDomain for add-ins, and may explain why ConfigurationManager doesn't bother looking for the assembly the correct location. What I don't understand is why it even needs to look for the assembly again when it has already been loaded in the default AppDomain. I can only assume that a .NET security update started enforcing that assembly locations be checked more often. – blah238 Aug 2 '11 at 6:26

The standard .NET configuration file is per application, not per library. This means that when your addin runs within ArcMap process, your configuration settings need to be specified in ArcMap.exe.config which needs to be placed besides ArcMap.exe.

This is of course not always possible in production environment and also violates the isolation of addins, which is one of the reasons addins were introduced in the first place.

You will need to store your settings differently, either in your own config file (as hinted in Kirk's answer) or system registry.

You can monitor changes to your config file in various ways, for example leveraging the FileSystemWatcher class.

-

The accepted answer by Kirk Kuykendall didn't work for me, since it kept pointing to the .dll itself. I used the following to point to the config file

System.IO.StreamReader file = new System.IO.StreamReader(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location) + "\\config.cfg");

-

While I have not looked at the new model for the ESRI Addin's what I have done and seen done by others is the user of the UserHive in the registry. You can then have a screen in your addin to update the could of values you need.

Using a App.config file tends to require you to restart the app/extension totally to read new values; while it is easier to do on-the-fly updates from the registry.

-

Have you tried to modify the copy of the config file located in the Add-In Assembly cache? I believe the esriaddin only gets expanded once by ArcGIS. So subsequent modifications may not be used (though it should notice the esriaddin file is newer than its cache).

Vista/7: C:\Users\\AppData\Local\ESRI\Desktop10.0\AssemblyCache

XP: C:\Documents and Settings\\Local Settings\Application Data\ESRI\Desktop10.0\AssemblyCache

-
Interesting suggestion but unfortunately this didn't make a difference.The config file in the AssemblyCache directory is over-written when ArcMap starts - I changed the config file here and in the AddIn at ...\Documents\ArcGIS\AddIns\Desktop10.0 so I have no idea where the value for the overwrite is coming from! – tomfumb Apr 27 '11 at 16:14
Appreciate the input, but it looks like the .esriAddIn file in Documents\ArcGIS\AddIns\Desktop10.0\..... actually gets extracted every time the application loads, so all changes in the add-in assembly cache are lost. – tomfumb Apr 27 '11 at 19:52

I'm wanting to do something similar for this but We have multiple clients that need the same app, but with different config settings (field names, layer names etc) they are not competent enough to do this themselves so we would like to build the app in a way that only a small file needs to be modified to change the settings. I've built an app.config file with all the appropriate settings and base values. I guess im asking if I need a class similar to yours above to update the file each time the app runs?

-
Ideally this is a new question so you can get more people helping with your specific problem, but I think you should look into multiple config files. I believe you can add the attribute file="client/custom.config" to the AppSettings element, then your application will have access (using the same config.AppSettings.Settings[key].Value approach above) to both configs - this way each of your clients gets the common config and their own specific separate config file. No need to change anything at runtime. – tomfumb Jun 17 '11 at 5:18
Andrew please make this a new question. Thanks – Mapperz Nov 19 '12 at 14:12