Magick.NET-Q16-x64.Native.dll not found - c#

I am creating nopCommerce plug-in for image compression using Magick.Net library, I make ImageOptimizer object and when calling LosslessCompress method it gives an error like unable to load dll Magick.NET-Q16-x64.Native.dll or one of its dependencies: The specified module could not be found.
I have found Magick.NET-Q16-x64.Native.dll and when I am trying to add a reference for that it gives an error like reference is invalid or unsupported
var file = new FileInfo(filepath);
var optimizer = new ImageOptimizer();
optimizer.LosslessCompress(file);
I expect no error occurs when LosslessCompress method runs and image is successfully compressed.

Related

How to trigger "BadImageFormatException'?

I need to create a "BadimageFormatException" in my local to test some cacheing issue. How to create "BadImageFormatException"?
As already specified in the comments, you can just create and throw this exception:
throw new BadImageFormatException();
If you want to cause this exception naturally, then as per MSDN documentation,
This exception is thrown when the file format of a dynamic link library (.dll file) or an executable (.exe file) doesn't conform to the format that the common language runtime expects
It means that you can cause it by trying to load an invalid assembly file:
string tempPath = Path.GetTempFileName();
using (var file = File.OpenWrite(tempPath))
using (var sw = new StreamWriter(file))
{
sw.WriteLine("I am not an assembly");
}
Assembly.LoadFile(tempPath);
Thanks to #Xiaoy312 for the advice. There is a much simpler way to do this using Assembly.Load:
Assembly.Load(new byte[] { 0 });
If new to this, then one way also is to load an unmanaged assembly for example notepad.exe.
try
{
// path to notepad.exe.
string path = Environment.ExpandEnvironmentVariables("%windir%") + #"\System32\notepad.exe";
Assembly assembly = Assembly.LoadFile(path);
}
catch (System.BadImageFormatException exception)
{
// catch an exception.
}
As Notepad is unmanaged and not compiled with .Net, .net isnt very happy and throws the exception.
For interesting trivia, BadImageFormatException has nothing to do with bad image format like gifs or jpegs but its an exception when .Net attempts to load a DLL or exe which isnt compatible with CLR.
Also, all exceptions are derived from System.Exception. BadImageFormatException is just inherited from System.Exception.

Xamarin Android runtime C# compilation

I am trying to compile a simple code in C# using Microsoft.CodeAnalysis.CSharp.
The problem is in trying to add the reference to mscorlib.dll.
As the CreateFromAssembly method of the MetadataReference class is deprecated I am trying to use the CreateFromFile method (as suggested):
var mscorlibAssembly = Assembly.Load(new AssemblyName("mscorlib.dll")).ManifestModule.Assembly;
var mscorlibref = MetadataReference.CreateFromFile(mscorlibAssembly.Location);
result.Add(mscorlibref);
The Location property of the assembly returns "mscorlib.dll" and not the full path causing the error: System.IO.FileNotFoundException: Could not find file "/mscorlib.dll"
How can I load the correct MSCorLib reference to be able to use CSharpCompilation?

How can I feed a loaded Assembly to a Roslyn Workspace in C#

I am enhancing an existing process with runtime code generation. The code I am creating at runtime needs access to some of the same dlls that the process creating the code is already referencing.
Problem is that the process runs within some 3rd party software that loads dlls from resources and injects them into my process... thus I do not have access to either a dll on disk nor to the resource that contained the dll in the external wrapper.
As a result I am trying to use the assemblies I already have in memory and feed them into the Roslyn workspace into which I place my runtime code for compilation.
I thought I could try serializing the Assembly with a binary formatter as per this SO:
Opposite operation to Assembly Load(byte[] rawAssembly)
But even if I pretty much take the code as is:
Assembly yourAssembly = typeof(object).Assembly;
var formatter = new BinaryFormatter();
var ms = new MemoryStream();
formatter.Serialize(ms, yourAssembly);
var reloadedAssembly = Assembly.Load(ms.GetBuffer());
I get:
An exception of type 'System.BadImageFormatException' occurred in mscorlib.dll but was not handled in user code
None of the other search results seemed any better.
What I want to do is something like:
var assemblyRef = MetadataReference.CreateFromAssembly(typeof(object).Assembly);
mySolution.AddMetadataReference(projectId, assemblyRef);
Any suggestions?
For a managed assembly loaded using Assembly.Load(byte[]) you can create a Roslyn MetadataReference like so:
var assembly = Assembly.Load(bytes);
var modulePtr = Marshal.GetHINSTANCE(assembly.ManifestModule);
var peReader = new PEReader((byte*)modulePtr, bytes.Length))
var metadataBlock = peReader.GetMetadata();
var moduleMetadata = ModuleMetadata.CreateFromMetadata((IntPtr)metadataBlock.Pointer, metadataBlock.Length);
var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
var reference = assemblyMetadata.GetReference();
Note that this doesn't work for assemblies loaded from a file, since the layout in the memory is different.

InvalidCastException for two Objects of the same type

I have this weird problem that I cannot handle myself. A class in the model of my mvp-project designed as singleton causes an InvalidCastException.
The source of error is found in this code line where the deserialised object is assigned to the instance variable of the class: engineObject = (ENGINE)xSerializer.Deserialize(str);. It occurs whenever I try to add one of my UserControls to a Form or to a different UC. All of my UCs have a special presenter that accesses the above mentioned instance variable of the singleton class.
This is what I get when trying to add a UC somewhere:
'System.TypeInitializationException: The type initializer for 'MVP.Model.EngineData' threw an exception. ---->
System.InvalidCastException: [A]Engine cannot be cast to [B]Engine. Type A originates from 'MVP.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither'
at location '[...]\AppData\Roaming\Microsoft\VisualStudio\9.0\ProjectAssemblies\uankw1hh01\MVP.Model.dll'.
Type B originates from 'MVP.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither'
at location '[...]\AppData\Roaming\Microsoft\VisualStudio\9.0\ProjectAssemblies\u_hge2de01\MVP.Model.dll'
...
So I somehow have two assemblies and they are not accessed from my project folder, but from a VS temp folder? I googled a lot and only found this: IronPython Exception: [A]Person cannot be cast to [B]Person. There is a solution offered, but it concerns IronPhyton and I don't know where to use it within my project.
Types are per-assembly; if you have "the same" assembly loaded twice, then types in each "copy" of the assembly are not considered to be the same type.
These issues normally crop up when the two assemblies are in the Load and LoadFrom contexts. See
Difference between LoadFile and LoadFrom with .NET Assemblies?
and the link to suzcook's blog for details on that issue.
Also, consider using the fusion log viewer to help diagnose the problem.
http://msdn.microsoft.com/en-us/library/e74a18c4%28VS.71%29.aspx
Judging by the context in which the assembly is getting loaded (the context is "LoadNeither"), some developers may be doing something like loading an assembly that has been internally packaged as a resource with your application. If you do this, you will be using the AppDomain.CurrentDomain.AssemblyResolve event handler, so that your application can specify where .NET should get any particular assembly that it needs.
My answer will not explain the machinations of how to do that - but I'm mentioning it because this process led directly to the same exact error encountered by the original poster. As Eric Lippert mentions, types are per-assembly. So if you load an individual assembly more than once, the same defined class will appear as different classes - even though visual inspection shows that they appear to be the same.
We've seen instances in which .NET will call the ResolveEventHandler more than once for the same DLL. I'm not sure why .NET sometimes does this (it happened on some machines, but not all machines). But to resolve the problem, we needed keep a global list of handles to loaded assemblies, so that if .NET wanted to load the assembly again, we returned a handle to the same Assembly that was originally loaded, instead of loading another copy into memory.
I have included the code that caused the issue for us, and notes about how to handle it properly.
public void AppStartup (object sender, StartupEventArgs e)
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
public System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
dllName = dllName.Replace(".", "_");
if (dllName.EndsWith("_resources")) return null;
System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
byte[] bytes = null;
try
{
bytes = (byte[])rm.GetObject(dllName);
}
catch (Exception ex)
{
}
if (bytes != null)
{
// the following call will return a newly loaded assembly
// every time it is called
// if this function is called more than once for the same
// assembly, you'll load more than one copy into memory
// this can cause the InvalidCastException
// instead of doing this, you keep a global list of loaded
// assemblies, and return the previously loaded assembly
// handle, instead of loading it again
return System.Reflection.Assembly.Load(bytes);
}
return null;
}
My situation involved two copies of the same dll. One was in the bin folder and one was in a sub-folder of the same bin folder. Both were loaded, amazingly some things worked fine, but some things didn't and that's when this error message appeared:
System.InvalidOperationException; There was an error generating the XML document.; Source: System.Xml; TargetSite: Void Serialize(System.Xml.XmlWriter, System.Object, System.Xml.Serialization.XmlSerializerNamespaces, System.String, System.String);
Hidden in this was the following inner exception (this was to do with Microsoft Dynamics CRM 4.0, but could relate to anything)
System.InvalidCastException; [A]XXX.CRMCustomCode.YYY.CreateCompanyRequest cannot be cast to [B]XXX.CRMCustomCode.YYY.CreateCompanyRequest. Type A originates from 'XXX.CRMCustomCode, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadFrom' at location 'C:\Program Files\Microsoft CRM\Server\bin\assembly\XXX.CRMCustomCode.dll'. Type B originates from 'XXX.CRMCustomCode, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Program Files\Microsoft CRM\Server\bin\XXX.CRMCustomCode.dll'.;
I simply deleted the duplicate dll (in C:\Program Files\Microsoft CRM\Server\bin) and the error went away.
My particular case - class library referenced in web application was renamed and rebuilt. Older version of library was still in bin folder under old name. The framework loads whatever in bin folder (both libraries) and emits this error. So it happens not only when assemblies are loaded explicitly.
The obvious solution in my case is to clean bin folder.
I got it working when I tried changing this cast:
var t = (TeacherWebPages)Session["TeachersAD"];
To this:
var t = Session["TeachersAD"] as TeacherWebPages;
However the assembly/session/memcache was different and no data got back but no error occurred. So later I still had to delete specific temporary files every time source page was changed from the folder it was complaining about which would require me to kill IIS process from task manager. Or in my case I can just logout and it clears the session state.

Can't load multiple MEF parts

I have a Winforms desktop application that is loading multiple MEF parts with the same Interface type.
Problem:
When I try to load more than one of the same type I get the following exception:
The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) No valid exports were found that match the constraint '((exportDefinition.ContractName = "BOCA.TaskPilot.Common.Extensions.IFolderViewExtension") && (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") && "BOCA.TaskPilot.Common.Extensions.IFolderViewExtension".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
Resulting in: Cannot set import 'TaskPilot.Windows.MainForm.FolderViewExtension (ContractName="BOCA.TaskPilot.Common.Extensions.IFolderViewExtension")' on part 'TaskPilot.Windows.MainForm'.
Element: TaskPilot.Windows.MainForm.FolderViewExtension (ContractName="BOCA.TaskPilot.Common.Extensions.IFolderViewExtension") --> TaskPilot.Windows.MainForm
Here is the code to load the parts:
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
//string myExecName = Assembly.GetExecutingAssembly().Location;
//string myPath = Path.GetDirectoryName(myExecName);
catalog.Catalogs.Add(new DirectoryCatalog(#"C:\Data\TaskPilot\Development\Source\BOCA.TaskPilot.FolderView\bin\Debug"));
catalog.Catalogs.Add(new DirectoryCatalog(#"C:\Data\TaskPilot\Development\Source\BOCA.TaskPilot.TaskView\bin\Debug"));
// Uncomment below line and it works without exceptions raised
//catalog.Catalogs.Add(new DirectoryCatalog(#"C:\Data\TaskPilot\Development\Source\BOCA.FileManager\bin\Debug"));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
Here's the code at the class for each of the MEF parts:
[Export(typeof(IFolderItemsViewExtension))
public partial class TaskTreeView : DevExpress.XtraEditors.XtraUserControl, IFolderItemsViewExtension, IPartImportsSatisfiedNotification]
Here's the Import used on the Main form:
[ImportMany(AllowRecomposition = true)]
private IEnumerable<IFolderItemsViewExtension> TaskViewExtensions = null;
If I uncomment the last Catalog.Catalogs.Add line it throws the exception. If I run it without that it runs just fine. That line loads a different user control that implements the IFolderItemsViewExtension Interface. I've tried to just load a dummy project that all it has is the user control and that interface and I still get the same exception. No matter what I do I still get this exception.
It seems that everything runs fine as long as I'm not loading more than one of the same type of MEF part export.
This is using the latest version of 2009.22.10.0 of the System.ComponentModel.Composistion from the MEF download.
The error indicates that it can't find an export of type IFolderViewExtension. Note that this is different from the import of IFolderItemsViewExtension you have shown.
My guess is that the problem is not that you have multiple IFolderItemsViewExtensions, but that you have multiple IFolderViewExtensions, or there is some other contract that you have more than one of that you are using with an import that requires exactly one.
This may be caused because you have the same assembly in more than one of your directory catalogs. It is easy for this to happen if you have a reference to an assembly and copy local is set to true.
I guess might have more than one export statement in your Export class.
I was facing the same issue and this solved when i removed all other expert statement from that export class. and now it is working fine.

Categories

Resources