Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=15.1.0.0 #2609

Closed
Evangelink opened this issue Mar 20, 2024 · 12 comments

Comments

@Evangelink
Copy link
Member

Evangelink commented Mar 20, 2024

Thanks, while I have you, I'm trying to run a test project by running directly the EXE generated but I'm facing this error:

Assembly Initialization method Evs.Phoenix.Starasset.Api.Remote.ComponentTest.TestSettings.AssemblyInitializeAsync threw exception. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. [10:02:32 ](https://teamcity.evs.tv/buildConfiguration/Phoenix_EvsPhoenixStarasset_EvsPhoenixStarassetBuildOnCommitSharedResources/13896258?buildTab=log&focusLine=1604&linesState=1604&logView=flowAware) Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
@Evangelink

Originally posted by @TheFireCookie in #2577 (comment)

@Evangelink
Copy link
Member Author

Microsoft.Build.Utilities.Core is a dependency of Microsoft.Testing.Platform.MSBuild but we are relying on version 17.7.2 so I am not sure why you are having this issue. cc @MarcoRossignoli

Would it be possible to have some repro?

@MarcoRossignoli
Copy link
Contributor

Microsoft.Build.Utilities.Core is a dependency of Microsoft.Testing.Platform.MSBuild

It's should not end in the build of the user because it's non consumed as asset for the build.

@TheFireCookie
Copy link

I'll try to drop an isolated sample but it might be hard to get it

@Evangelink
Copy link
Member Author

Would it be possible for you to send us privately some binlog (you can follow the steps here https://learn.microsoft.com/cpp/overview/how-to-report-a-problem-with-the-visual-cpp-toolset?view=msvc-170#to-create-a-problem-report-for-private-information)?

@TheFireCookie
Copy link

I'll try to do that. Meanwhile is there a way to generate a TRX or something similar that my CI could ingest to report the tests?

@Evangelink
Copy link
Member Author

@nohwnd
Copy link
Member

nohwnd commented Mar 20, 2024

There is repro of this, or a similar problem in the internal repo in Verify_Correct_Registration_Order_For_WellKnown_Extensions test, the comment there mentions the same problem when running the test with something else than netstandard2.0. I also saw it when I was doing some changes.

(there are probably many ways to investigate, but dependency walker for .NET maybe would help here: isindicic/DependencyWalker.Net#7 )

@TheFireCookie
Copy link

TheFireCookie commented Mar 21, 2024

So we have a lib and in that lib there is some reflection and this is the method that make it break;
var commandCandidates = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).ToList();
if I remove this line, everything is fine.
But I don't know if the problem is with the reflection itself or if it's the types that comes of the assemblies.

@nohwnd
Copy link
Member

nohwnd commented Mar 22, 2024

we are relying on version 17.7.2

15.1.0.0 is the assembly version that all MSBuild assemblies ship with, including 17.7.2.

var commandCandidates = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).ToList();

This touches all types referenced in all currently loaded assemblies. Our Microsoft.Testing.Extensions.MSBuild.dll relies on Microsoft.Build.Utilities.Core, but does not ship it.

Is there a code above this one, that loads all assemblies in the folder? I can imagine that being the case, if you are shipping commands in separate dlls, and then picking them up based on some interface, or something like that.


I can repro if I force the msbuild task dll to be loaded:

image

// file MSTestSettings.cs
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
<!-- file TestProject77.csproj -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net481</TargetFramework>
    <LangVersion>Latest</LangVersion>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
    <EnableMSTestRunner>true</EnableMSTestRunner>
    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MSTest" Version="3.2.0" />
    <PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.10.1" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
  </ItemGroup>

</Project>
// file UnitTest1.cs
using System.Reflection;

namespace TestProject77
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            // Load all dlls in the test folder into the current appdomain.
            var allDlls = Directory.GetFiles(AppContext.BaseDirectory, "*.dll");
            foreach (var file in allDlls)
            {
                try
                {
                    Assembly.LoadFrom(file);
                }
                catch (BadImageFormatException) { }
            }


            try
            {
                // Touch all types, which forces loading all assemblies we depend on.
                var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).ToList();
            } 
            catch (ReflectionTypeLoadException ex)
            {
                foreach (var item in ex.LoaderExceptions)
                {
                    throw new AggregateException(ex.LoaderExceptions);
                };
            }
        }
    }
}

@TheFireCookie
Copy link

TheFireCookie commented Mar 24, 2024

That's what we do. We load all assemblies loaded in that project and then do some filtering based on if the classes is assignable by a specific interface. I've found a workaround meanwhile to avoid the issue but it's still there osmewhere either in my code or in the MSTest Runner.

@nohwnd
Copy link
Member

nohwnd commented Mar 25, 2024

We load all assemblies loaded in that project

I am not 100% sure what you mean by this. If you load all dlls that are in the same directory as your dll then you will for sure load Microsoft.Testing.Extensions.MSBuild and that does not have all the dependencies needed, because it also contains an MSBuild task that MSBuild loads into a different process and provides the dependencies. So this will for sure throw.

If you are not loading any additional dlls and are just going through all assemblies that are already in the current appdomain, then you should not see the Microsoft.Testing.Extensions.MSBuild, because MSTest will load you in a separate app domain by default. So I am not sure why you are able to repro. Are you disabling appdomain usage in tests explicitly?

(@Evangelink this says that appdomains are disabled by default (since 3.1.0), but I see TestSourceHost being used in the latest 3.4.0-preview on net481, https://github.com/microsoft/testfx/pull/1555/files#diff-5b4ed8ac66033d004915ef38def3061b502aab45fd654c814a541ddd7005f139 am I just misunderstanding the PR, or misunderstanding where this was shipped?)

Anyways, no matter why you see the error @TheFireCookie, it is a good idea to handle the type load error and grab just the usable types from the assemblies:

var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a =>
{
    try
    {
        // Return types when we were able to load all of them from an assembly.
        return a.GetTypes();
    }
    catch (ReflectionTypeLoadException ex)
    {
        // Return the types that we were able to load.
        return ex.Types;
    }
}).ToList();

Copy link
Contributor

Hello @Evangelink,
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 7 days of this comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants