Scott
Scott

Reputation: 999

Hosting CLR and programmatically providing app.config?

I have a native third party game, which allows me to write native extensions for it by exporting a particular function in a native DLL. I have been using this to host the CLR using C++/CLI compiler-generated hosting code, allowing me to call C# code from the game. This has been working great and it is a very elegant solution.

Once the CLR is loaded by the game, it searches game.exe.config in the game executable folder, for further .NET assembly probing information:

<?xml version="1.0"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="@Arma2NET"/>
    </assemblyBinding>
  </runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>

This arbitrary config file breaks my folder structure; I would like my project to be self-contained in the @Arma2NET folder and not have random config files in the game folder. At the moment, having the project files in the same folder as the native CLR-hosting DLL is impossible because of the game's folder requirements.

Is there a way to programmatically provide the CLR with this config from native code when it is starting, short of writing the entirety of the CLR-hosting code myself?

Upvotes: 2

Views: 809

Answers (2)

Scott
Scott

Reputation: 999

I ended up using the AssemblyResolve event to tell .NET where to find the rest of my assemblies:

    Assembly^ ResolveAssembly(Object ^sender, ResolveEventArgs ^e)
    {
        String ^directory = Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location);
        AssemblyName ^assemblyName = gcnew AssemblyName(e->Name);
        for each (String ^extension in gcnew array<String^> { ".dll", ".exe" })
        {
            String ^fileName = Path::Combine(directory, assemblyName->Name + extension);
            try
            {
                return Assembly::LoadFile(fileName);
            }
            catch (...)
            {
            }
        }
        return nullptr;
    }

Upvotes: 1

Simon Wang
Simon Wang

Reputation: 2943

How about you change the app.config in the library project build action to "Embedded Resource" then use something like ConfigurationManager.OpenMappedExeConfiguration to read it.

Upvotes: 0

Related Questions