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

Unable to load DLL 'wpfgfx_cor3.dll' or one of its dependencies during unit test #1328

Open
Ql1m4xx opened this issue Mar 14, 2023 · 15 comments

Comments

@Ql1m4xx
Copy link

Ql1m4xx commented Mar 14, 2023

Description:
currently we are migrating our Windows Application (WPF) from .NET Framework 4.8 to .NET 6.
We are using NUnit to test our user interface but we are getting the error that the 'wpfgfx_cor3.dll' could not be loaded

Stacktrace:

  1. Error : Productnamespace.GUIFoundation.Test.ControlTests.ExtendedControl.ExtendedControlTests.BaseElementViewModelTest
    System.DllNotFoundException : Unable to load DLL 'wpfgfx_cor3.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)
    at MS.Win32.PresentationCore.UnsafeNativeMethods.MILFactory2.CreateFactory(IntPtr& ppIFactory, UInt32 SDKVersion)
    at System.Windows.Media.FactoryMaker..ctor()
    at System.Windows.Media.StreamAsIStream.IStreamFrom(IntPtr memoryBuffer, Int32 bufferSize)
    at System.Windows.Media.Imaging.BitmapDecoder.GetIStreamFromStream(Stream& bitmapStream)
    at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
    at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
    at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
    at System.Windows.Media.Imaging.BitmapImage.EndInit()
    at System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource, RequestCachePolicy uriCachePolicy)
    at System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource)
    at Productnamespace.GUIFoundation.Test.ControlTests.ExtendedControl.ExtendedControlTests.SetUp() in C:\Git\Repos\Product\Libraries\GUIFoundation\Sources\GuiFoundation.Test\ControlTests\ExtendedControl\ExtendedControlTests.cs

It's the same issue like #1319

The workaround to adjust the nunit-agent.runtimeconfig.json is not feasible for us because we dont want to adjust the "installed" file that comes with the NUnit.Console

Used Version: 3.16.2

Thanks for your help in advance

@OsirisTerje
Copy link
Member

Does it work with 3.15.2 ?

@Ql1m4xx
Copy link
Author

Ql1m4xx commented Mar 14, 2023

Does it work with 3.15.2 ?

I got not the same problem with version 3.15.2

  1. Invalid : C:/Git/Repos/Product/Libraries/GUIFoundation/Sources/GuiFoundation.Test/bin/Debug/Product.GUIFoundation.Test.dll
    Unable to load one or more of the requested types.
    Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    Could not load file or assembly 'PresentationCore, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
    ----> Could not load file or assembly 'PresentationCore, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.

@OsirisTerje
Copy link
Member

OsirisTerje commented Mar 14, 2023

Ok, then I assume it doesn't work with using dotnet test either?

It would also be great if you could provide a very small repro for this.

@spkl
Copy link

spkl commented Mar 14, 2023

Hi OsirisTerje, I have created a repository with a repro for this: https://github.com/spkl/nunit-console-1328-repro
The test shows and then closes a dialog from a WPF library. I have pasted the results from dotnet test and the two discussed NUnit Console versions as a readme.

I'm on the same dev team as Ql1m4xx. This is not a perfect repro for our scenario, as we are also using a third-party library (DevExpress), but the errors seem to be comparable for now. Thanks for looking into this.

@OsirisTerje
Copy link
Member

@spkl @Ql1m4xx Thanks for the repro. I can confirm I do see the same. It works when using Visual Studio (2022) and it works using dotnet test, either on csproj or directly on the test dll.

I'll summarize the results that I see:

Visual Studio 2022, it works:
image

dotnet test , project level , it works
image

dotnet test nunit-console-1328-test.dll, in the bin folder, It works:
image

All of these use the adapter version 4.2.1 (which has the engine 3.15.2 built-in)

It fails with the nunit console (version 3.15.2, and @spkl show it fails with 3.16.2 too)
image

As @CharliePoole have pointed out earlier, the assembly loading with the adapter is done by the MS testhost, and not the engine, whereas the console will do the loading itself. So that's where it struggles:

Thanks again, we can use this to start working on it.

@CharliePoole Any suggestions? (and yes, I have read the other stuff on this, so let's start from that.)
@rprouse Rings any bells?

@carstencodes
Copy link

carstencodes commented Mar 15, 2023

I might have one additional clue.

The Microsoft Test SDK generates an entrypoint into each test assembly. It can be seen from any reflector like ILspy or dotpeek.
The entrypoint is called from the runtime, which is selected using a runtime.config.json in version and experience/workload.

Hence the unit test is simply deriving from Microsoft.NET.SDK, the resulting runtime should be NetCoreApp, hence a simple console application.
As the assembly under test actively uses WPF and this is executed during the test, it must use the WindowsDesktop runtime.

Hence adding

<UseWPF>true</UseWPF>

to the csproj of the unit test will actually enforce the runtime to select the WindowsDesktop App, which provides the WPF runtime libraries.

This way, the test should run.

@spkl @Ql1m4xx Can you please give it a try?

@spkl
Copy link

spkl commented Mar 15, 2023

@carstencodes nunit-console-1328-test.runtimeconfig.json already contains Microsoft.NETCore.App and Microsoft.WindowsDesktop.App. I've tried adding UseWPF, but it changes nothing.
If I remember correctly from other issues, NUnit Console does not evaluate the runtimeconfig.json of a test assembly.

@carstencodes
Copy link

@spkl Yeah, but it lead me on the right track.

I had to run

$ COREHOST_TRACE=1 dotnet test 2> dotnet-test.corehost_trace.txt
...
$ COREHOST_TRACE=1 dotnet nunit  nunit-console-1328-test/bin/Debug/net6.0-windows/nunit-console-1328-test.dll 2> dotnet-nunit.corehost_trace.txt

and diff the resulting files to actually find it.

The target runtime is not determined by the test assembly but in this case by the starting process.

I replaced

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "rollForward": "Major",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.0"
    },
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

with

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "rollForward": "Major",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.0"
      },
      {
        "name": "Microsoft.WindowsDesktop.App",
        "version": "6.0.0"
      }
    ],
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

in the nunit-console's runtime config json file.

The result was:

$ dotnet nunit nunit-console-1328-test/bin/Debug/net6.0-windows/nunit-console-1328-test.dll
NUnit Console 3.16.2 (Release)
Copyright (c) 2022 Charlie Poole, Rob Prouse
Mittwoch, 15. März 2023 08:46:01

Runtime Environment
   OS Version: Microsoft Windows 10.0.19044
  Runtime: .NET 6.0.14

Test Files
    nunit-console-1328-test/bin/Debug/net6.0-windows/nunit-console-1328-test.dll


Run Settings
    DisposeRunners: True
    WorkDirectory: C:\git\external\github\nunit-console-1328-repro
    NumberOfTestWorkers: 12

Test Run Summary
  Overall result: Passed
  Test Count: 1, Passed: 1, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2023-03-15 07:46:02Z
    End time: 2023-03-15 07:46:08Z
    Duration: 6.272 seconds

Results (nunit3) saved as TestResult.xml

Hence, in order to support additional frameworks like WPF-Test, XUnit-STA, FlaUI or XAMLTest, it might be a good idea to create a desktop-runtime runner for these cases.
(It cannot be added to the regular runtime as it might actually break linux/mac support).

@rprouse
Copy link
Member

rprouse commented Mar 15, 2023

This is great info @carstencodes ,thanks for the work you put into it

@OsirisTerje
Copy link
Member

@carstencodes @spkl @Ql1m4xx May I just ask: What is the reason you need to use NUnit.Console and not just use dotnet test?

@Ql1m4xx
Copy link
Author

Ql1m4xx commented Mar 16, 2023

@OsirisTerje We are using NUnit.Console since 10 or more years to execute more than 10k tests with it. We parse the result and display it and it worked very well in the last decade.
A switch to dotnet test for us is not a thing that we can do over night.
We would highly appreciate that NUnit.Console supports us and I think other users, too, with a solution that dont requires the change of installed files.

@CharliePoole
Copy link
Member

I need to re-confirm this in the latest release.

@FleurLotus
Copy link

I used 1.19.2, I still have the problem with WPF core dll using net8.0

NUnit NetCore Console Runner 3.19.2 (Release)
Copyright (c) 2022 Charlie Poole, Rob Prouse
12 February 2025 16:13:10

Runtime Environment
OS Version: Microsoft Windows 10.0.19045
Runtime: .NET 8.0.12

Test Files
C:\Temp\MPSD-Work\CommonLibraries\UnitTests\Common.WPF.UnitTests\bin\Debug\net8.0-windows\Common.WPF.UnitTests.dll

Errors, Failures and Warnings

  1. Error : Common.WPF.UnitTests.ImageSourceConverterTest.TestConvertUriToImageSource
    System.DllNotFoundException : Unable to load DLL 'wpfgfx_cor3.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)
    at MS.Win32.PresentationCore.UnsafeNativeMethods.MILFactory2.CreateFactory(IntPtr& ppIFactory, UInt32 SDKVersion)
    at System.Windows.Media.FactoryMaker..ctor()
    at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
    at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
    at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
    at Common.WPF.Converter.ImageSourceConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) in C:\Temp\MPSD-Work\CommonLibraries\Common.WPF\Converter\ImageSourceConverter.cs:line 24
    at Common.WPF.UnitTests.ImageSourceConverterTest.TestConvertUriToImageSource() in C:\Temp\MPSD-Work\CommonLibraries\UnitTests\Common.WPF.UnitTests\Converter\ImageSourceConverterTest.cs:line 35
    at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
    at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

@CharliePoole
Copy link
Member

CharliePoole commented Feb 12, 2025

@FleurLotus Can you provide a repro for this? The simpler the better. :-) I'd like to make sure you are having the same problem as others on this thread.

@FleurLotus
Copy link

FleurLotus commented Feb 12, 2025

@CharliePoole

Here is the simplest solution I could NunitConsoleSample.zip

In VS I have

Image

with nunit3-console.exe (from NUnit.Console-3.19.2\bin\net8.0)

Image

my command

SET NUNIT=.\NUnit.Console-3.19.2\bin\net8.0\nunit3-console.exe
SET NET=bin\Debug\net8.0

"%NUNIT%" ".\Common.WPF.UnitTests\%NET%-windows\Common.WPF.UnitTests.dll"

I do not put the compiled version or the nunit-console to reduce the size.

Hoping it will help you

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

7 participants