1

The documentation for ConfigurationManager.OpenExeConfiguration(string exePath) states:

Opens the specified client configuration file as a Configuration object.

It also states that exePath is "The path of the executable (exe) file"

The method is supposed to open the *.exe.config file for the executable at the path specified by exePath, and that a ConfigurationErrorsException will be thrown if "A configuration file could not be loaded.".

The following code uses the path of a non-executable and the directory of that path contains no *.exe.config files. Yet the code executes without any exceptions, nor any other sign of an invalid argument.

var configs = Directory.GetFiles("C:\\NoConfig", "*.config");
Debug.Assert(configs.Length == 0);
File.WriteAllText("C:\\NoConfig\\notes.txt", "This is not an executable, and there is no .config file in its folder.");
var config = ConfigurationManager.OpenExeConfiguration("c:\\notes.txt");
Debug.Assert(config != null);

Yet it will now slowly become deprecated for the new .NET Core JSON based configuration, and will not be reviewed or fixed anyway.

So, is this due to a bug in this overload of the OpenExeConfiguration method?

I just wanted a 2nd, and nth opinion before I raised it on MS Connect. And Connect is down at the moment.

ADDED: If I call OpenExeConfiguration with a valid exePath, to a real executable (tested), with a valid .config file, then it reads but does not parse the file. I have to request the xml for the appSettings section and parse it myself, using the workaround from this answer to AppSettings from custom files. This adds to my suspicion that this code is not commonly used in this mode, has been accepted as working and not reviewed, and could thus be buggy.

I'm sure it will receive scant attention with the new .NET Core configuration API replacing the old XML only one.

Community
  • 1
  • 1
ProfK
  • 49,207
  • 121
  • 399
  • 775
  • It is open sourced, so check the code to see if it is by design. https://referencesource.microsoft.com/#System.Configuration/System/Configuration/ConfigurationManager.cs,82b0d78ddc6f04b3 – Lex Li Oct 08 '16 at 12:34
  • @LexLi I'm very interested to see the source code, thanks for the link, but if it's by design, (a) it doesn't make sense, and (b) it should be documented as designed. In fact, I'm downloading the whole bloody framework, it's only 59MB. – ProfK Oct 08 '16 at 12:38
  • It is perfectly normal for an .exe to not have a .config file. So if it works the way you think, how could you ever create one with this api? Just read the description correctly: "could not be *loaded*" == found the file but it contains gibberish. Feature, not a bug. – Hans Passant Oct 09 '16 at 06:10
  • @HansPassant, If the .exe does not have a .config file, surely the method in question should somehow notify me of that. After all, the docs have me taking for granted the .config was read, and my code may make faulty decisions based on assuming config elements are not present. Please see my edit referring to further buggy behaviour. Bring on .NET Core! – ProfK Oct 09 '16 at 15:07

2 Answers2

2

So you have two concerns as I understand:

  1. OpenExeConfiguration does not fail for files with extensions other than "exe".

  2. OpenExeConfiguration does not fail if configuration file not already exists.

I understand both points, but I'd say both of them are arguable.

  1. Executable file does not necessary mean file with .exe extension. Yes, on Windows that's usually true, but let's take Linux for example (and we can do that because .NET is not restricted to Windows only). I can have executable .NET file with any extension (even notes.txt), or without extension at all, it doesn't matter. I can happily execute that file with "mono notes.txt" and it will run as usual.

  2. Non existing configuration file is not an exceptional condition for Configuration object. It even has property named HasFile which indicates if that file exists or not. I can do the following with your code:

    var config = ConfigurationManager.OpenExeConfiguration("c:\\notes.txt"); 
    // config.HasFile == false here
    config.AppSettings.Settings.Add("test", "test");
    config.Save(ConfigurationSaveMode.Full, true);
    // config.HasFile == true here, and file is written to disk
    
Evk
  • 98,527
  • 8
  • 141
  • 191
  • Yes, but this old, pre Core code, and without opportunity to provide a config file path, it must be inferred as `exename.exe.config`. The 4.6 CLR, as best I know, will not look for any 'notes.txt.config' types of filename. I'm going to debug it today, stepping into the CLR code. – ProfK Oct 09 '16 at 03:09
0

Not sure whether it could be called a bug or not but

As per this reference

According to http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/3943ec30-8be5-4f12-9667-3b812f711fc9 the parameter is the location of an exe, and the method then looks for the config corresponding to that exe (I guess the parameter name of exePath makes sense now!).

It also gives a workaround --

ExeConfigurationFileMap map = new ExeConfigurationFileMap { ExeConfigFilename = "EXECONFIG_PATH" };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
Community
  • 1
  • 1
Miguel Sanchez
  • 434
  • 3
  • 11
  • I'm just adding validation that the path is for an ece file and it does have a *.exe.config file. – ProfK Oct 08 '16 at 12:36