Unable to load assembly in appDomain - .net-assembly

Until recently I was loading my assembly by calling Assembly.LoadFrom and it was ok. But now I need to load it in a temporary appDomain but I keep having a FileLoadException when trying to load the assembly in the temp domain. I have tried to pass appDomainSetup parameters to the CreateDomain method but without success.
Here is my code.
var tempDomain = AppDomain.CreateDomain("TempDomain");
Assembly sampleAssembly = tempDomain.Load(pathToDll);
My assembly is in a sub directory of my application base directory

AppDomain.Load loads the assembly in the currently executing AppDomain and not in the "TempDomain" one. As remarked in the MSDN doc:
This method should be used only to load an assembly into the current
application domain. This method is provided as a convenience for
interoperability callers who cannot call the static Assembly.Load
method. To load assemblies into other application domains, use a
method such as CreateInstanceAndUnwrap.
Now in your case the call fails because the currently executing AppDomain (most probably your main AppDomain) cannot locate assemblies from the sub directory. When you try to load assemblies in the load context, you should make sure that these assemblies are located in one of the following places:
the base dir of the AppDomain
a sub directory of the base dir that is specified in the AppDomain's private bin paths
the GAC
For more info you can check the following articles:
How the Runtime Locates Assemblies
Best Practices for Assembly Loading
Back to Basics: Using Fusion Log Viewer to Debug Obscure Loader Errors

Related

Metadata file could not be opened -- PE image doesn't contain managed metadata

In azure functions I uploaded private dll's to bin folder using following instructions
If you need to reference a private assembly, you can upload the assembly file into a bin folder relative to your function and reference it by using the file name (e.g. #r "MyAssembly.dll").
but I when run the function, I am getting this error for every dll. "Metadata file could not be opened -- PE image doesn't contain managed metadata"
Looks like you're adding references to native binaries as well. Your references must be .NET assemblies. If you're deploying native indirect dependencies, you don't need to reference those from your function script.
UPDATE: There as a defect in the last portal deployment causing the content of files uploaded in the portal to be prefixed and suffixed with multipart form data, invalidating files.
The issue has been fixed and is being rolled out, but in the meantime, please upload the files using Kudu to workaround this issue. You can find more information about the problem here (and by following the issue link)
I also faced the same issue while building MAUI app in android platform. A native module was present in the project with .so extension. But a windows native DLL also present in the project for the purpose for running the same project in windows. Excluding the windows native DLL while building running in android fixed the issue. Sometimes I have to close the project and delete bin and obj folder and then rebuild the project to get rid of this issue.

Azure Functions - Could not load file or assembly Microsoft.IdentityModel.Extensions

I'm trying to create a Azure Function that references 'Microsoft.IdentityModel.Extensions'.
I have a helper library dll, that includes code to provisioning a SharePoint Online site. This dll uses Microsoft.IdentityModel.Extensions.
I have put this helper library in the bin folder and reference it from run.csx using the #r syntax, but I keep getting this error in the log:
Exception while executing function: Functions.ATPCreateSiteFunction. mscorlib: Exception has been thrown by the target of an invocation. ATP.SiteProvisioning.Cloud: Could not load file or assembly 'Microsoft.IdentityModel.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=69c3241e6f0468ca' or one of its dependencies. The system cannot find the file specified.
I have tried the following approaches to get Azure Functions to find the Microsoft.IdentityModel.Extensions assembly:
Include the Microsoft.IdentityModel.Extensions.dll in the bin folder and reference in run.csx with this: #r "../bin/Microsoft.IdentityModel.Extensions.dll"
Trying to include as Nuget package by referencing "Microsoft.Identity.Model.Extensions": "2.0.1459.0" in project.json (same Nuget used in the helper library itself)
I don't think you need to reference the file path to the DLL. Instead of #r "../bin/Microsoft.IdentityModel.Extensions.dll", try #r "Microsoft.IdentityModel.Extensions.dll".

.NET MEF DirectoryCatalog issue

I am developing Excel add-in and use MEF to provide extensibility. DirectoryCatalog works fine on my local drive, however when I deploy solution to the network drive composition silently fails.
In regular .exe application this problem can be resolved by adding "loadFromExternalSources=true" to "runtime" section of application configuration file, however for Excel add-in this file does not exist (and I can't add Excel.exe.config to the folder, containing Excel executable since this folder is read-only). Is there any way to programmatically enable loadFromExternalSources behavior?
Is there any way to programmatically enable loadFromExternalSources behavior?
If you create a seperate AppDomain with AppDomain.CreateDomain, then you can pass a AppDomainSetup which has a ConfigurationFile property.
However, I suppose that comvisible objects are normally created in the default appdomain so making the new AppDomain talk to Excel will probably be difficult. I guess it would involve shim classes in the default appdomain which pass calls through to the other appdomain.

How can we protect ourselves from other third parties installing DLLs with the same names as some of ours into C:\WINDOWS?

Our product includes several DLLs built from open source into files with default names as delivered by the open source developers. We're careful to install the files in our own directories and we carefully manage the search path (only for our processes) to keep the loader happy.
Another developer -- a towering intellect -- decided it would be easier to install their own build of some of the same open source into C:\WINDOWS under the same default DLL filenames. Consequently, when we launch a process which depends on these open source DLLs, the system searches C:\WINDOWS before our directories and finds the DLLs installed by the other developer. And they are, of course, incompatible.
Ideas which have occurred to me so far:
rename all our DLLs to avoid the default names, which would only make
it less likely we would encounter collisions
load all our DLLs by full path so the loader captures their names into
RAM and doesn't search anywhere else the next time they are requested
For various reasons, neither of these options is palatable at the moment.
What else can we do to defend ourselves against the towering intellects of the world?
You've got only two options: deploy the DLL in the same directory as the EXE (that's where Windows looks first) or using manifests and deploy the DLL to the Windows side-by-side cache. I don't think the latter option is common in the Open Source world but it is the only real fix if you want to share DLLs between different apps.
To add to the already excellent answers, you have a couple more choices:
The preferred solution(s) to this problem, supported since Windows XP, is to turn your dll's into a win32 assembly (They don't have to be .NET but the documentation on creating win32 assemblies with strong names is appallingly light so its easy to get confused and think this is a .NET only technology).
An assembly is noting more complicated than a folder (With the name of the assembly) containing the dlls and a .manifest (With the name of the assembly) that contains an assemblyIdentiy element, and a number of file nodes for each dll in the assembly.
Assembly based searching works even when dlls are statically linked!
The easiest option is to create unversioned assemblies and store them in the same folder as your .exe files (Assuming all your exe's are in a single folder).
If the exe's are in different folders, then there are two ways to access shared assemblies:
You can store your assemblies in a private alternate location if you expect your application to be used on Windows 7 and higher. Create a app.exe.config file for each of your exe's, and point a probing privatePath element to a common folder where you are storing the assemblies.
If you are ok with requiring administrative access to perform installs, (via MSI's) then you can deal with the appallingly bad documentation (well, absent documentation) that deals with giving your assemblies a strong name, and then store the assembly in WinSxS.
If you can't, or do not want to bundle your dlls as assemblies then this page covers dll search order
Using functions like SetDllDirectory are only going to help for dlls loaded dynamically at runtime (via LoadLibrary).
Dll search order used to be:
Directory containing the process exe
Current directory
various windows folders
PATH
Which you could have used to your advantage - launch each exe, setting the "current" directory to the folder containing the OSS dlls.
With the advent of SafeDllSearchMode the search order now is:
Directory containing the process exe
various windows folders
Current directory
PATH
Meaning theres now less control than ever :( - It goes even faster to the "untrusted" c:\windows & System32 folders.
Again, if the initial dll is being loaded via LoadLibrary, and its the dependent dll's that are the problem, LoadLibraryEx with the LOAD_WITH_ALTERED_SEARCH_PATH flag will cause the following search order (Assuming you pass a full path to LoadLibraryEx) :-
Directory part of the Dll path passed to LoadLibraryEx
various windows folders
Current directory
PATH
The directory from which the application loaded is normally the first directory searched when you load a DLL. You can, however, use SetDllDirectory to get the "alternate search order". In this case, the directory you specify to SetDllDirectory gets searched first.
There is also a SafeDllSearchMode that affects this to a degree. Turning it on excludes the current directory from the search.
Maybe just compile them to a static library?
Why not?
Also, the current directory, where the exe is activated from is searched before c:\windows.

Errors creating WebPart subclass in another assembly

I am trying to create a subclass of WebPart that will act as a parent to any WebParts we create. If I create an empty class in the same project, I am able to inherit from it as one would expect. However, if I try to place it in another assembly -- one that I've been able to reference and use classes from -- I get the following error:
Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Other information that may be pertinent (I am not normally a SharePoint developer): I compile the dlls, reference them from the dev project, and copy them into the /bin directory of the SharePoint instance. The assemblies are all signed. I'm am attempting to deploy using VS2008's 'deploy' feature.
Unfortunately, this does not appear to be a SharePoint specific error, and I'm not sure how to solve the problem. Has anyone experienced this and do you have any suggestions?
OK, I found the problem. The packaging task uses reflection for some reason or another. When it finds that your class inherits from a class in another domain, it tries to load it using reflection. However, reflection doesn't do binding policy, so that domain isn't loaded.
The authors of the packaging program could solve this by adding the following code:
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}
However, if you need a solution for your project, just add the assemblies to the GAC and it will be able to resolve them.

Resources