FileNotFoundException for CefSharp when running XUnit test - c#

I am making some test with XUnit on a application using CefSarp.
But the test are crashing with the exception :
System.IO.FileNotFoundException: Could not load file or assembly 'CefSharp, Version=55.0.0.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138'or one of its dependencies. The system cannot find the file specified.
at CefSharp.CefSharpApp.OnBeforeChildProcessLaunch(CefSharpApp* , CefRefPtr* commandLine)
On Xunit issue tracker (https://github.com/xunit/xunit/issues/4) the workaround is to set the shadowCopy option to false. But this does not work for me.
CefSharp have some files which need to be next the executable (https://github.com/cefsharp/CefSharp/wiki/Frequently-asked-questions#Runtime_dependencies). All those files are present in the bin folder and when I check the current directory with System.IO.Directory.GetCurrentDirectory(), this is the right folder.
I tried to use the SetDllDirectory from Kernel32 to add the bin folder but it change nothing.
I also tried to load the assembly manualy with Assembly.LoadFile(). This call succeed but later when cef is initialized, the exception still happen. So the problem is probably not finding the assembly itself but the files needed by CefSharp.
Where should I put all the CefSharp file to allow XUnit to find them? I have the same problem with the Xunit test integrated in VisualStudio and with the Xunit console.
Edit :
Problem solved (see anwser). All the test are passing except test created with SpecFlow.
It throw the Could not load file or assembly but with CefSharp.Core this time.

The problem was that CefSharp does not support multiple AppDomains.
The config file of the unit test in the CefSharp repo contains the following :
<configuration>
<appSettings>
<add key="xunit.appDomain" value="denied"/>
</appSettings>
</configuration>
which prevent XUnit to use multiple AppDomains.
This config must be added in the app.config of each test library .
The CefSharp test also contains
var isDefault = AppDomain.CurrentDomain.IsDefaultAppDomain();
if (!isDefault)
{
throw new Exception(#"Add <add key=""xunit.appDomain"" value=""denied""/> to your app.config to disable appdomains");
}
to check is multiple AppDomains are used.

Related

NUnit TestEngine throws "Unable to load one or more of the requested types" when trying to explore assembly

I'm working on a tool that needs to extract the NUnit tests names that are contained in an assembly.
As I need the exact name of the tests when they are run, and NUnit's way of naming the tests is not straightforward, I use the NUnit TestEngine to explore the assembly.
Something like that :
Assembly testAssembly; //loaded somewhere else
using var testEngine = new TestEngine();
testEngine.WorkDirectory = Path.GetDirectoryName(testAssembly.Location);
var package = new TestPackage(testAssembly.Location);
using var runner = testEngine.GetRunner(package);
var testsFound = runner.Explore(new TestFilter(string.Empty));
I build the whole tool with one of our projects as test subject, and it works well.
But when I try it on other similar projects (.Net 6, NUnit test projects for a web API), I have the following error :
Unable to load one or more of the requested types.
Could not load file or assembly 'Microsoft.AspNetCore.Hosting.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
The tests run properly inside the Visual Studio, with VS test runner or Resharper.
The current directory is set to the bin folder.
Looking at the project, it seems that this is a implicit dependency of Microsoft.AspnetCore.Hosting (referenced by AppInsight)
But :
I don't see any version 6.0.0.
I have another similar project that loads properly and have the exact same dependencies
I can't find any Nuget package that has this version (highest is 2.2.0), so I can't force the reference.
The Assembly loads properly (with Assembly.LoadFrom()), it fails in NUnit, when it tries to call LoadTests
I can't find where this reference is needed and why one solution is working and others are not, while they are very similar !
I'm out of ideas to make it work, so I'm looking for suggestions.
Have you considered simply telling NUnit to produce the list of tests for you?
The --explore option followed by a file name creates XML output but without a following name it produces a readable list of names on the console. You can redirect the output to a file if that's what you want.
nunit3-console yourtests.dll --explore
UPDATE
Make sure you use the standard .NET Framework build of NUnit3-console with the above option, not the .NET 6.0 build. The standard runner creates whatever process is needed to properly explore the test assembly.

Could not load file or assembly C# Console Application with Class Library

I've created a Class Library in C# .Net Framework 4.8, and in the solution I've also included a Console Application, same target.
I'm running both in a x64 configuration.
No errors on build.
I referenced the App in the Library, and when I run a Button in a Form in the Class Library I'm getting an error:
System.IO.FileNotFoundException: Could not load file or assembly
'ExampleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or
one of its dependencies. The system cannot find the file specified.
File name: 'ExampleApp, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'
I've combed the internet and SO for a solution. I tried repairing Visual Studio, I tried deleting the .vs folder in the projects, I tried things like:
solution 1
and
solution 2
I seriously tried everything I could think of. It has to be something to do with the .dll dependencies imho, because the only one that my ExampleApp is using is the Microsoft.CognitiveServices.Speech reference which I installed via NugetPackage in my solution.
No idea how to debug this further or get a proper trace stack from this error...
Any ideas on how to proceed?
Thanks
Solved by changing the .dll's Copy Local property to True
Exactly #Yafim Simanovsky, I solved also my problem by changed <Private> flag to True.
My problem (“Could not load file or assembly…”) was with new Designer ‘WpfSurface.exe’ from VS 2022, which after changing the reference tags ‘Private’ to True, was able to copied all dependent .dll files to Cache.

DNN 7 Web API Module; Could not load file or assembly

Background
I'm building a mobile app for an existing DNN 7 site; made by someone else who left a year ago or so. I had previously set up a WebApi module to handle authentication. Then I had the idea of setting up a class library to hold my DTO objects; since I would have to modify several existing modules to expose web methods and they'd have to interact with my app. So I created a class library threw in two classes and compiled. Added the dll reference to both my app and the web module and they have no issues building when referencing my objects. However, when I send a web request, from either my app or Postman chrome extension, to my module I get:
"Could not load file or assembly 'Elf.Web.Models, Version=1.0.6081.13955, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.",
My app doesn't seem to have issues creating and using the objects, just with the web module.
What I Tried/Checked
Properties I made sure both my class library and my web module were targeting the same framework; .NET Framework 4.5
Reference Property Copy Local is True and per Other Question
I tried manually editing my .csproj file to add the attribute Private to True under my reference. I even tried adding a binding redirect to my assembly.
Manual I also tried opening up my modules install zip tossing the class library dll into the bin folder, re-zip, and then installed to the dnn site. The problem persisted.
If anyone else has an idea of what could be an issue it'd be appreciated.
Putting the library dll in the bin folder of the installer zip file will not automatically put your library dll file into the bin folder of the DotNetNuke installation during install.
Add this to the installer .dnn file under the <components> node.
<component type="Assembly">
<assemblies>
<assembly>
<name>myLibrary.dll</name>
<path>bin</path>
</assembly>
</assemblies>
</component>
If you want the file to be added to the installer zip automatically, you have to make a reference in the ModulePackage.targets file.
<Copy SourceFiles="$(MSBuildDnnBinPath)\myLibrary.dll" DestinationFolder="$(MSBuildProjectDirectory)\Package\bin"/>

NHibernate & NET Persistence API not working in test project

I am getting following error while creating EntityManager in my Data Access Layer(DAL) (Class Library project):
File name: 'Iesi.Collections, Version=1.0.1.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' ---> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
I am getting this error from my TestProject (Class Library project) where I have return NUnit test cases.
I have one web application which also calls DAL, but during this call it is able to create EntityManager properly.
Actually I need to add following lines to config files which avoids the above error:
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
Now the problem is, I have obviously added these lines to my web.config, and that is I am able to create EntityManager. But how can I add this lines to my TestProject (which is a Console Library), because it will not have a config file associated with it.
PS: I am using NHibernate and NET Persistence API.
You have to copy the Iesi.Collections in the bin directory, the easiest way is to add a reference in your test project.

TFS 2010 msbuild overwrites different versions of referenced library in output directory

I'm building Web project using TFS 2010. The project contains Silverlight client and .NET/C# server side. Both of these (client and server) are referencing one 3rd party library for which we have Silverlight and .NET version, but both versions use the same name. The problem is that msbuild with outdir property specified puts all the libraries to one flat hierarchy in output directory so one library overwrites the other.
I know that one solution would be to modify build template and not specify outdir, but this brings problems with other parts of the build template (I had problem with unit tests and I read about people having problems with putting output to _PublishedWebsites).
Another workaround would be to rename that library/libraries so the names will not collide. But this will not be solution if there is a lot of such libraries.
I'd like to find some clean solution. Do you know about some elegant way how to solve this?
According to Microsoft there are (at least) three ways of referencing assemblies:
install the assembly in the GAC
specify the assembly in the application configuration
or use the AssemblyResolve Event
The GAC is no option here, as you would have the same problem (same names).
Using the AssemblyResolve Event and then use Assembly.LoadFrom would possibly a way of doing it, but easier would be imho ...
... to do it the second mentioned way: specify the assembly in the application configuration. Here you basically edit the App.config like so:
<configuration>
<runtime>
<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
<probing privatePath=”bin;Silverlight;ParentFolder\SubFolder;”/>
</assemblyBinding>
</runtime>
</configuration>
and the application will search for the assemblies in specified directories.
So, you could create specific folders (possibly "NET" and "Silverlight" or the like), copy the respective assembly into that folder and probe for the assembly in the proper folder as described above.
Considering that when no reference is specified in the application configuration the application will be looking into either the same folder as the referencing assembly or into a folder with the name of the referencing assembly, you could also simply create 2 folders with the same name as the respective application (say "Client" and "Server" if they are called "Client.exe" and "Server.exe") and copy the proper assembly into that folder. In that case there would not even be any need to change the application configuration file.

Categories

Resources