Bug 51261 - Embedding Mono Exception "The 'ExeConfigFilename' argument cannot be null"
Summary: Embedding Mono Exception "The 'ExeConfigFilename' argument cannot be null"
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.XML (show other bugs)
Version: 4.6.0 (C8)
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on: 12669
Blocks:
  Show dependency tree
 
Reported: 2017-01-06 08:33 UTC by Shui
Modified: 2017-01-06 13:43 UTC (History)
2 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Code to reproduce the bug (1.11 KB, application/x-zip-compressed)
2017-01-06 08:33 UTC, Shui
Details

Description Shui 2017-01-06 08:33:37 UTC
Created attachment 19110 [details]
Code to reproduce the bug

Related Bug 12669, which works well for me, there is no exception.

Context:
I try to call the C#.dll from C++ program on Linux (CentOS 7) by Embedding Mono (Mono JIT compiler version 4.6.2).

Exception:
If C# contains the codes:
-Configuration _config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
-or XmlSerializer xml = new XmlSerializer (typeof(TestConfiguration));
It will give an exception "The 'ExeConfigFilename' argument cannot be null".
Eles it works without exception.

How to reproduce:
I upload one .zip file, who contains 2 files: (I also copy the code Here at the end)
-TestConfigurationCSharp.cs, the C# program
-hello.cpp, the C++ program who will call C#.dll
Use this command to compile the C# code:
-mcs /nologo /warn:4 /debug:pdbonly /o  /out: TestConfigurationCSharp.dll /target:library TestConfigurationCSharp.cs /reference:System.Configuration.dll,System.Xml.dll,System.dll
Then we can have a file named 'TestConfigurationCSharp.dll', Use this command to compile C++ code:
-g++ hello.cpp -g3 `pkg-config --cflags --libs mono-2` -o hello
and execute by the command:
-./hello

Then we will get the exception:
Methode NewConfiguration
ex-NewConfiguration: Exception System.ArgumentException: The 'ExeConfigFilename' argument cannot be null.
  at System.Configuration.ExeConfigurationHost.CheckFileMap (System.Configuration.ConfigurationUserLevel level, System.Configuration.ExeConfigurationFileMap map) [0x0002b] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ExeConfigurationHost.InitForConfiguration (System.String& locationSubPath, System.String& configPath, System.String& locationConfigPath, System.Configuration.Internal.IInternalConfigRoot root, System.Object[] hostInitConfigurationParams) [0x00036] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.InternalConfigurationSystem.InitForConfiguration (System.String& locationConfigPath, System.String& parentConfigPath, System.String& parentLocationConfigPath) [0x00000] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.Configuration..ctor (System.Configuration.InternalConfigurationSystem system, System.String locationSubPath) [0x0001f] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.InternalConfigurationFactory.Create (System.Type typeConfigHost, System.Object[] hostInitConfigurationParams) [0x0000e] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ConfigurationManager.OpenExeConfigurationInternal (System.Configuration.ConfigurationUserLevel userLevel, System.Reflection.Assembly calling_assembly, System.String exePath) [0x00107] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ConfigurationManager.OpenExeConfiguration (System.Configuration.ConfigurationUserLevel userLevel) [0x00012] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at TestConfigurationCSharp.TestConfiguration.NewConfiguration () [0x00000] in <99c29f36eee1438fb513414ce1c939b9>:0 
ex-NewConfiguration: Exception Message The 'ExeConfigFilename' argument cannot be null.
Methode NewXmlSerializer
ex-NewXmlSerializer: Exception System.Configuration.ConfigurationErrorsException: Error Initializing the configuration system. ---> System.ArgumentException: The 'ExeConfigFilename' argument cannot be null.
  at System.Configuration.ExeConfigurationHost.CheckFileMap (System.Configuration.ConfigurationUserLevel level, System.Configuration.ExeConfigurationFileMap map) [0x0002b] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ExeConfigurationHost.InitForConfiguration (System.String& locationSubPath, System.String& configPath, System.String& locationConfigPath, System.Configuration.Internal.IInternalConfigRoot root, System.Object[] hostInitConfigurationParams) [0x00036] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.InternalConfigurationSystem.InitForConfiguration (System.String& locationConfigPath, System.String& parentConfigPath, System.String& parentLocationConfigPath) [0x00000] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.Configuration..ctor (System.Configuration.InternalConfigurationSystem system, System.String locationSubPath) [0x0001f] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.InternalConfigurationFactory.Create (System.Type typeConfigHost, System.Object[] hostInitConfigurationParams) [0x0000e] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ConfigurationManager.OpenExeConfigurationInternal (System.Configuration.ConfigurationUserLevel userLevel, System.Reflection.Assembly calling_assembly, System.String exePath) [0x00107] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ClientConfigurationSystem.get_Configuration () [0x00011] in <d6de850e07274db588ca7c247bfa5ec6>:0 
   --- End of inner exception stack trace ---
  at System.Configuration.ClientConfigurationSystem.get_Configuration () [0x00030] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection (System.String configKey) [0x00000] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.ConfigurationManager.GetSection (System.String sectionName) [0x00005] in <d6de850e07274db588ca7c247bfa5ec6>:0 
  at System.Configuration.PrivilegedConfigurationManager.GetSection (System.String sectionName) [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.DiagnosticsConfiguration.GetConfigSection () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.DiagnosticsConfiguration.Initialize () [0x00033] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.DiagnosticsConfiguration.get_SwitchSettings () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.Switch.InitializeConfigSettings () [0x00019] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.Switch.InitializeWithStatus () [0x0004f] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.Switch.get_SwitchSetting () [0x0000d] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Diagnostics.BooleanSwitch.get_Enabled () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly (System.Type type, System.String defaultNamespace, System.Xml.Serialization.XmlSerializerImplementation& contract) [0x0001d] in <1140eab9e72948548294172a9716416d>:0 
  at System.Xml.Serialization.XmlSerializer..ctor (System.Type type, System.String defaultNamespace) [0x00096] in <1140eab9e72948548294172a9716416d>:0 
  at System.Xml.Serialization.XmlSerializer..ctor (System.Type type) [0x00000] in <1140eab9e72948548294172a9716416d>:0 
  at TestConfigurationCSharp.TestConfiguration.NewXmlSerializer () [0x00000] in <99c29f36eee1438fb513414ce1c939b9>:0 
ex-NewXmlSerializer: Exception Message Error Initializing the configuration system.
ex-NewXmlSerializer: Exception InnerException Message The 'ExeConfigFilename' argument cannot be null.


CODE TestConfigurationCSharp.cs:
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;

namespace TestConfigurationCSharp
{

    public class TestConfiguration
    {
        public TestConfiguration()
        {
		Console.WriteLine ("TestConfiguration: constructor");
	}

	public void NewConfiguration()
	{
		try{
			Configuration _config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
		}
		catch (Exception e)
		{
			Console.WriteLine("ex-NewConfiguration: Exception " + e);
			Console.WriteLine("ex-NewConfiguration: Exception Message " + e.Message);
			if(e.InnerException != null)
				Console.WriteLine("ex-NewConfiguration: Exception InnerException Message " + e.InnerException.Message);
		}
	}

	public void NewXmlSerializer ()
	{
		try{
			XmlSerializer xml = new XmlSerializer (typeof(TestConfiguration));
		}
		catch (Exception e)
		{
			Console.WriteLine("ex-NewXmlSerializer: Exception " + e);
			Console.WriteLine("ex-NewXmlSerializer: Exception Message " + e.Message);
			if(e.InnerException != null)
				Console.WriteLine("ex-NewXmlSerializer: Exception InnerException Message " + e.InnerException.Message);
		}
	}
    }
}

CODE hello.cpp:
#include <mono/jit/jit.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

int main(int argc, char* argv[]) {
mono_config_parse(NULL);

  MonoDomain* domain = mono_jit_init("TestConfigurationCSharp.dll");
  MonoAssembly* assembly = mono_domain_assembly_open(domain, "TestConfigurationCSharp.dll");
  MonoImage* image = mono_assembly_get_image(assembly);
  MonoClass* entityClass = mono_class_from_name(image, "TestConfigurationCSharp", "TestConfiguration");
  MonoObject* entityInstance = mono_object_new(domain, entityClass);

printf("Constructor\n");
  MonoMethodDesc* ctorDesc = mono_method_desc_new("TestConfigurationCSharp.TestConfiguration:.ctor()", false);
  MonoMethod* ctorMethod = mono_method_desc_search_in_class(ctorDesc, entityClass);
  mono_runtime_invoke(ctorMethod, entityInstance, NULL, NULL);

printf("Methode NewConfiguration\n");
  MonoMethodDesc* doConfigDesc = mono_method_desc_new("TestConfigurationCSharp.TestConfiguration:NewConfiguration()", false);
  MonoMethod* doConfigMethod = mono_method_desc_search_in_class(doConfigDesc, entityClass);
  mono_runtime_invoke(doConfigMethod, entityInstance, NULL, NULL);

printf("Methode NewXmlSerializer\n");
  MonoMethodDesc* doXmlDesc = mono_method_desc_new("TestConfigurationCSharp.TestConfiguration:NewXmlSerializer()", false);
  MonoMethod* doXmlMethod = mono_method_desc_search_in_class(doXmlDesc, entityClass);
  mono_runtime_invoke(doXmlMethod, entityInstance, NULL, NULL);

  mono_jit_cleanup(domain);
}
Comment 1 Shui 2017-01-06 10:41:02 UTC
In this case (C++ call C#.dll), the value ‘AppDomain.CurrentDomain.SetupInformation.ConfigurationFile’ is always null in C# code.
Comment 2 Tim Matthews 2017-01-06 13:25:32 UTC
You need to add a call to mono_domain_set_config. It is not automatic. Though it doesn't really matter what you supply as the config file name it doesn't need to exist.
Comment 3 Shui 2017-01-06 13:43:00 UTC
Yeah, good job, it works!
Thank you very much! You save my time!
In fact I have tried 'mono_set_dirs', 'mono_set_config_dir' etc... But it does not work.
Thanks again!

Note You need to log in before you can comment on or make changes to this bug.