13

I need to embed my app.config file which contains only supportedRuntime settings into my exe file. I tried doing build action embedded resource, but it's not reading the values from the config file now and it doesn't work. this is my config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
      <supportedRuntime version="v2.0.50727"/>
      <supportedRuntime version="v4.0"/>
    </startup>
</configuration>

so the idea is to run my .Net 2.0 exe on .Net 4.0 as well. any ideas?

Thanks.

Shahab78
  • 277
  • 1
  • 11
  • .net is backwards-compatible. If a machine has 4.0 installed, it will run an app compiled with 2.0. You don't need two tags. – Andrew Jun 17 '14 at 18:56
  • 12
    Thanks Andrew, but unfortunately that's not true. – Shahab78 Jun 17 '14 at 19:11
  • Here we go; try this: http://stackoverflow.com/a/13915723/436282 – Andrew Jun 17 '14 at 19:12
  • 6
    Thanks Andrew, that's exactly correct, but as I mentioned I'm trying to find a way to do this without the config file, or embed the config file into the exe. – Shahab78 Jun 17 '14 at 19:18

1 Answers1

6

This is not possible. If you absolutely must have executable without config file, closest you can get is to write unmanaged loader that will run the CLR for you.

Suppose you have c# app like:

using System;

namespace DumpVersion
{
    class Program
    {
        static int EntryPoint(string argument)
        {
            Console.Out.WriteLine(argument);
            Console.Out.WriteLine(Environment.Version);
            Console.In.ReadLine();
            return 0;
        }

        static void Main()
        {
            EntryPoint("Main");
        }
    }
}

You can create unmanaged () loader like:

#include <metahost.h>

#pragma comment(lib, "mscoree.lib")

#import "mscorlib.tlb" raw_interfaces_only \
    high_property_prefixes("_get","_put","_putref") \
    rename("ReportEvent", "InteropServices_ReportEvent")

int wmain(int argc, wchar_t* argv[])
{
    HRESULT hr;
    ICLRMetaHost *pMetaHost = NULL;
    ICLRRuntimeInfo *pRuntimeInfo = NULL;
    ICLRRuntimeHost *pClrRuntimeHost = NULL;

    // build runtime
    // todo: add checks for invalid hr 
    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
    hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
    if (hr != S_OK) {
        hr = pMetaHost->GetRuntime(L"v2.0.50727", IID_PPV_ARGS(&pRuntimeInfo));
    }
    hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
        IID_PPV_ARGS(&pClrRuntimeHost));

    // start runtime
    hr = pClrRuntimeHost->Start();

    // execute managed assembly
    DWORD pReturnValue;
    hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
        L"c:\\temp\\TestLoading\\DumpVersion\\bin\\Debug\\DumpVersion.exe",
        L"DumpVersion.Program",
        L"EntryPoint",
        L"hello .net runtime",
        &pReturnValue);

    // free resources
    pMetaHost->Release();
    pRuntimeInfo->Release();
    pClrRuntimeHost->Release();

    return 0;
}

More info: https://www.codeproject.com/Articles/607352/Injecting-Net-Assemblies-Into-Unmanaged-Processes

Ondrej Svejdar
  • 21,349
  • 5
  • 54
  • 89