11

When attempting to run unit tests that use mixed mode assemblies in VS2015 the tests fail to execute with the usual message:

System.IO.FileLoadException: Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

Creating an app.config and adding useLegacyV2RuntimeActivationPolicy to it has no effect - it seems as though this configuration is impossible to change.

This previously worked with no manual steps in VS2013.

Jonathan Dickinson
  • 9,050
  • 1
  • 37
  • 60

1 Answers1

19

Alternative 1: Configuration

Add the startup configuration to C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\TE.ProcessHost.Managed.exe.config:

<startup useLegacyV2RuntimeActivationPolicy="true">
</startup>

Alternative 2: At Runtime

This may stop working.

Simply add this class to the unit test project (source):

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public static class RuntimePolicyHelper
{
    [AssemblyInitialize]
    public static void SetPolicy(TestContext ctx)
    {
        var clrRuntimeInfo =
            (ICLRRuntimeInfo)RuntimeEnvironment.GetRuntimeInterfaceAsObject(
                Guid.Empty,
                typeof(ICLRRuntimeInfo).GUID);

        // Allow errors to propagate so as to fail the tests.
        clrRuntimeInfo.BindAsLegacyV2Runtime();
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("BD39D1D2-BA2F-486A-89B0-B4B0CB466891")]
    private interface ICLRRuntimeInfo
    {
        void xGetVersionString();
        void xGetRuntimeDirectory();
        void xIsLoaded();
        void xIsLoadable();
        void xLoadErrorString();
        void xLoadLibrary();
        void xGetProcAddress();
        void xGetInterface();
        void xSetDefaultStartupFlags();
        void xGetDefaultStartupFlags();

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void BindAsLegacyV2Runtime();
    }
}
Jonathan Dickinson
  • 9,050
  • 1
  • 37
  • 60
  • I couldn't find a file at: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\TE.ProcessHost.Managed.exe. I tried adding one but it didn't work. However, adding the code seemed to work. – Derek Sep 27 '15 at 00:59
  • 1
    @Derek the way I found the .config file was to look at the either the Output or Test window. It will give you the .exe name ("Process TE.ProcessHost.Managed.exe exited with code X"). Search for that in your VS directory. Alternative 2 worked for me at first and then stopped working completely - I'd avoid it. – Jonathan Dickinson Sep 29 '15 at 09:09
  • @Derek I just noticed that the path was incorrect (facepalm). I have corrected it. – Jonathan Dickinson Sep 29 '15 at 12:49
  • I'm not sure why - I don't even have the "TestWindow" folder in that location. – Derek Sep 29 '15 at 14:34
  • Hmm... maybe I installed to a custom location - I had trouble finding the exe that was running - but if I ran tests under the debugger I could find the process in the task manager. Mine is in: C:\MicrosoftVisualStudio14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow ( which I think I might have picked ) – Derek Sep 29 '15 at 14:38
  • I was able to get it working using the method you described - without the code. – Derek Sep 29 '15 at 14:48
  • I wish I could give you more upvotes for coming back to help out more but I guess you just get one :) – Derek Sep 29 '15 at 14:49
  • 1
    For Visual Studio 2012 (version 11) I modified the following file (which I was able to find using the Task Manager solution that @Derek described): `C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.executionengine.x86.exe.config`. I added the following line under the existing `` node: ``. – Dan Forbes Apr 21 '16 at 16:08