I have an MVC project that has been working for years that I just re-published to the server yesterday. I opened it up to debug and make changes to code. Some time in between compiles, something happened and now the build fails complaining that
The type 'System.Windows.FrameworkElement' is defined in an assembly that is not referenced. You must add a reference to assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
and
The type 'System.Windows.DependencyObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
I have looked at similar questions and done as they have suggested to make sure all files are set to the Build Action compile, content or none for the project. I didn't add any new files and I didn't copy paste any images into solution.
Any ideas?
Edit:
Not sure if this will be helpful. I didn't include it because it doesn't seem like it would be, but this is where it takes me when I double click on the errors given.
public PartialViewResult GetByJobID(int jobID)
{
ViewBag.Jobid = jobID;
var getAllHolesByJobID = _toolCalloutService.getAllJobHoles(jobID);
var toolOrderHoleViewModels = //error happens here on var
getAllHolesByJobID.Select(Mapper.Map<HoleInfoViewModel, ToolOrderHoleViewModel>).ToList();
var shipOrigins = _toolCalloutService.GetDistricts();
ViewData["ToolOrderHoleViewModels"] = toolOrderHoleViewModels;
ViewData["ShipOrigins"] = shipOrigins;
ViewData["OrderedBy"] = System.Web.HttpContext.Current.User.Identity.Name.Substring(9);
return PartialView("~/Views/ToolCallout/ToolCallout.cshtml");
}
It just highlights the var keyword at var toolOrderHoleViewModels.
Related
i use Unity version 2020.1.11f1
I am trying to create Docs using the Xceed library. However, every time I mention Color, I get the following error :
error CS0012: The type 'Color' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
example code:
s1.Color = Color.red;
s1.Bind( brazil, "Category", "Expenses" );
c.AddSeries( s1 );
I tried to use this : [System.ComponentModel.TypeConverter("System.Drawing.Color, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
along with this code:
s1.Color = System.Drawing.Color.Green;
and now the error looks like this:
error CS1069: The type name 'Color' could not be found in the namespace 'System.Drawing'. This type has been forwarded to assembly 'System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Consider adding a reference to that assembly.
The solution was that the Xceed bundle had lost its reference to the System.Drawning.Color library or could not pull it up. When adding the library to the directory, the problem was solved.
Setup
I am working on a C# project without external dependencies, named "Hopper". I have split it up into a couple of different modules, each contained within a corresponding sub-folder. The relevant ones for the problem are the following:
Utils/Hopper.Utils.csproj
Shared/Hopper.Shared.csproj
Core/Hopper.Core.csproj, which references Utils and Shared, more details later
Mine/Hopper.Mine.csproj, which references Core
All of these target .NET 4.8, including Hopper.Core.
I have set the AssemblyName property for each of the projects to the corresponding string. For example, the Hopper.Utils.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net4.8</TargetFramework>
<AssemblyName>Hopper.Utils</AssemblyName>
</PropertyGroup>
</Project>
Hopper.Core.csproj references the other projects via ProjectReference, like so:
<ItemGroup>
<ProjectReference Include="..\Utils\Hopper.Utils.csproj" />
<ProjectReference Include="..\Shared\Hopper.Shared.csproj" />
</ItemGroup>
Hopper.Mine.csproj, created for testing purposes, references core like this:
<ItemGroup>
<ProjectReference Include="..\Core\Hopper.Core.csproj" />
</ItemGroup>
The Hopper.Core project contains some types, both classes and structs. Some source files have been autogenerated by a tool and contain #pragma warning disable at the top. (Removing it did not help).
The two projects referenced by Hopper.Core just contain some types and attributes, used by Core, so nothing of interest to the problem. They do not reference any other projects or dll's.
The problem
I am able to compile Hopper.Mine by running dotnet build in the sub-folder with the project file. I am able to see the output dll's of the referenced sub-projects in bin/Debug/net4.8/Hopper.Whatever.dll under each project's folder. Intellisense in VSCode also works correctly and does not report any errors.
Hopper.Mine has a single class with a Main function, created for a test. It lists the types of Hopper.Core that have loaded successfully, and reports the ones that have not been loaded:
using System;
using System.Reflection;
using System.Text;
namespace Hopper.Mine
{
public class Program
{
public static void Main(string[] args)
{
Assembly lib = typeof(Hopper.Core.Action).Assembly;
Type[] types;
try
{
types = lib.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
StringBuilder sb = new StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
Console.WriteLine(exSub.Message);
}
types = ex.Types;
}
foreach (Type type in types)
{
if (type != null)
Console.WriteLine(type.FullName);
}
}
}
}
Running this code, I can see a bunch of problematic types, some of which repeat, and the rest of types that have loaded successfully:
Could not load type 'Hopper.Core.Stat.Attack' from assembly 'Hopper.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'Hopper.Core.Stat.Dig' from assembly 'Hopper.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'Hopper.Core.Stat.Move' from assembly 'Hopper.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'Hopper.Core.Stat.Push' from assembly 'Hopper.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'Hopper.Core.Stat.Attack' from assembly 'Hopper.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'Hopper.Core.Stat.Attack' from assembly 'Hopper.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
... more errors here ...
Hopper.Core.DirectedPredict
Hopper.Core.UndirectedPredict
Hopper.Core.DirectedDo
... more types here ...
Hopper.Core.Stat.Attack+Source+Resistance
Hopper.Core.Stat.Push+Source+Resistance
To be noted 4 things:
The types that failed to load are all structs and derive from IStat.
The source files with these types have been autogenerated by a tool (other files generated by the tool load without errors).
The types do not reference any types from Hopper.Shared or Hopper.Utils.
Some of the types have nested structs, up to 3 level deep, some of the deeper ones seem to have loaded successfully.
I am pretty sure that the dll output from the Hopper.Core's output folder is identical to the one in the output folder of Hopper.Mine. I am also pretty sure that the right dll is linked against when I start the program (I've tried debugging with VS, where I can see which dll is being linked against and the paths matched).
I have tried removing AssemblyName properties, renaming csproj files from Hopper.Whatever.csproj to Hopper_Whatever.csproj, I've obviously tried cleaning up any previous output dll's and building from scratch, none of which helped. I have also been able to reproduce this on a different machine with the exact same results.
I have tried looking at the Hopper.Core dll with a decompiler, ILSpy. I am able to see the "missing" types as they are in code.
I have searched on google for hours for a problem like mine, to no avail. I have found many cases of people setting up their project files incorrectly, due to which they unexpectedly link against a different version of the dll than they expected. For some, such dependency showed up in requirements of one of the referenced third party projects. Some blame GAC for providing incorrect version of the dll. However, I'm pretty sure that my projects are set up right (+ the set up is pretty simple and no third party projects are being referenced) and I am referencing the right dll's (since I can see my types in it). It kind of seems like the types are 'declared' in the dll, but not 'defined' (sort of), so the dll's turn out corrupted. But then why would the decompilation not fail? So I'm currently completely stuck on this.
Loading the assembly manually
I have tried linking against the dll's dynamically, by their names. Listing the types imported from Hopper.Shared and Hopper.Utils works, however, when I try it with Hopper.Core, I get the same output as the example above.
To achieve this, I have copied the previous dll's from the output over to a new folder, removed the reference from Hopper.Mine, compiled the new code with dotnet build, after which moved the executable to the new folder and finally ran it in the console. The code:
using System;
using System.Reflection;
using System.Text;
namespace Hopper.Mine
{
public class Program
{
public static void Main(string[] args)
{
Assembly shared = Assembly.LoadFrom("Hopper.Shared.dll");
Assembly utils = Assembly.LoadFrom("Hopper.Utils.dll");
Assembly core = Assembly.LoadFrom("Hopper.Core.dll");
Type[] types;
try
{
types = core.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
StringBuilder sb = new StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
Console.WriteLine(exSub.Message);
}
types = ex.Types;
}
foreach (Type type in types)
{
if (type != null)
Console.WriteLine(type.FullName);
}
}
}
}
To reproduce
If it helps, you may try running my code. Here's the github link to the current state of the project. In order to run it, you need:
.NET 4.8 installed.
Clone the repository from the link above.
Some code is still missing. You need to run the project in the folder Meta to generate it. Just run dotnet run in the Meta folder.
Now you can run the Mine subproject.
Found out the reason. There is a bug in the CLR type system that has been around for 6 years. Basically, fields (either static or non-static) of type of a generic struct declared in other structs cause this behavior. See this github thread for more details.
In my case, I have been able to make a shorter version that illustrates the bug.
public struct Index<T>
{
}
public struct Test
{
public static Index<Test> Index;
}
Use the following code to test the program:
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine(typeof(Test).Assembly.GetTypes());
}
}
When the code is run, the following error is thrown:
Unhandled Exception: System.TypeLoadException: Could not load type 'Hopper.Mine.Test' from assembly 'Hopper.Mine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
at Hopper.Mine.Program.Main(String[] args)
However, there is an easy sort of workaround for this. Changing Test from struct to class works:
// This works!
public struct Index<T>
{
}
public class Test
{
public static Index<Test> Index;
}
That may not be acceptable in some cases. So here is another workaround — storing the static field in an array and accessing it with a property also works:
public struct Index<T>
{
}
public struct Test
{
public static Index<Test> Index { get => index[0]; set => index[0] = value; }
public static Index<Test>[] index = new Index<Test>[1];
}
Apologies for the dodgy question - happy to rephrase if someone has a better suggestion.
I'm trying to create an object by dynamically invoking an assembly belonging to another application.
The following PowerShell code is working nicely for me:
[Reflection.Assembly]::LoadFrom("C:\Program Files\Vendor\Product\ProductAPI.dll")
$bobject = new-object ProductAPI.BasicObject
$bobject.AddName("Some Name")
I'm struggling to do the same thing in C#. Based on other posts on StackOverflow I currently have this:
System.Reflection.Assembly myDllAssembly =
System.Reflection.Assembly.LoadFile("C:\\Program Files\\Vendor\\Product\\ProductAPI.dll");
System.Type BasicObjectType = myDllAssembly.GetType("ProductAPI.BasicObject");
var basicObjectInstance = Activator.CreateInstance(BasicObjectType);
The final line results in a TargetInvocationException.
{"Could not load file or assembly 'AnotherObject, Version=1.2.345.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
It appears that the BasicObject constructor is trying to invoke AnotherObject (from AnotherObject.dll in the same folder) but can't find it.
Any tips on how to get around this?
If it can't find a dependent assembly in the usual places, you'll need to manually specify how to find them.
The two easiest ways I'm aware of for doing this:
manually load the dependent assemblies in advance with
Assembly.Load.
handle the AssemblyResolve event for the domain which is loading the
assembly with additional assembly dependencies.
Both essentially require you to know the dependencies for the assembly you're trying to load in advance but I don't think that's such a big ask.
If you go with the first option, it would also be worthwhile looking into the difference between a full Load and a reflection-only Load.
If you would rather go with 2 (which I'd recommend), you can try something like this which has the added benefit of working with nested dependency chains (eg MyLib.dll references LocalStorage.dll references Raven.Client.dll references NewtonSoft.Json.dll) and will additionally give you information about what dependencies it can't find:
AppDomain.CurrentDomain.AssemblyResolve += (sender,args) => {
// Change this to wherever the additional dependencies are located
var dllPath = #"C:\Program Files\Vendor\Product\lib";
var assemblyPath = Path.Combine(dllPath,args.Name.Split(',').First() + ".dll");
if(!File.Exists(assemblyPath))
throw new ReflectionTypeLoadException(new[] {args.GetType()},
new[] {new FileNotFoundException(assemblyPath) });
return Assembly.LoadFrom(assemblyPath);
};
In a console application; If I execute:
Assembly.LoadFrom(#"c:\...\MyWinRTApp.exe")
I get:
System.BadImageFormatException occurred
HResult=-2147024885
Message=Could not load file or assembly 'file:///C:\_...\MyWinRTApp.exe' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Source=mscorlib
Is there any way around this?
EDIT 1
In relation to "Vyacheslav Volkov"'s answer below, I now get a step further, thank you. However I now get a different issue.
"assembly.GetExportedTypes()"
now throws
"Cannot resolve dependency to Windows Runtime type 'Windows.UI.Xaml.Application'. When using the ReflectionOnly APIs, dependent Windows Runtime assemblies must be resolved on demand through the ReflectionOnlyNamespaceResolve event."
If I try to ReflectionOnlyLoad the referenced assemblies, then I get the error:
"Could not load file or assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)".
This is related to loading winmd references, and explained in the post here: Could not load file or assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'.
The full code I'm trying is this:
using System.Runtime.InteropServices.WindowsRuntime;
var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
/*WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (x, y) =>
{
y.NamespaceName ???
y.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(???));
return;
};*/
foreach (var references in assembly.GetReferencedAssemblies())
{
try
{
Assembly.ReflectionOnlyLoad(references.FullName);
}
catch (FileNotFoundException)
{
var fi = new FileInfo(assemblyPath);
var fi2Name = String.Format("{0}\\{1}.dll", fi.DirectoryName, references.Name);
var fi2 = new FileInfo(fi2Name);
if (fi2.Exists)
{
Assembly.ReflectionOnlyLoadFrom(fi2.FullName);
}
}
catch (FileLoadException)
{
// When a winmd assembly is attempted.
}
}
return assembly;
Any more ideas?
Thanks, Jon
Edit 2
The latest idea successfully resolves "{Windows.UI.Xaml, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime}".
However, when ".GetExportedTypes()" is called on the "Client.exe" assembly, the 'ReflectionOnlyNamespaceResolve' event is only fired once for namespace "Windows.UI.Xaml", which resolves to "C:\windows\system32\WinMetadata\Windows.UI.Xaml.winmd".
An exception is then thrown within ".GetExportedTypes()", which is "Cannot resolve dependency to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.".
If you want only to discover the containing types you should use the Assembly.ReflectionOnlyLoad method.
Assembly.ReflectionOnlyLoadFrom(#"c:\...\MyWinRTApp.exe")
UPDATE
Here's the code that works for me:
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, eventArgs) => Assembly.ReflectionOnlyLoad(eventArgs.Name);
WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (sender, eventArgs) =>
{
string path =
WindowsRuntimeMetadata.ResolveNamespace(eventArgs.NamespaceName, Enumerable.Empty<string>())
.FirstOrDefault();
if (path == null) return;
eventArgs.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(path));
};
Assembly loadFrom = Assembly.ReflectionOnlyLoadFrom(#"C:\....\WinRTApp.exe");
Type[] types = loadFrom.GetExportedTypes();
foreach (Type type in types)
{
Console.WriteLine(type);
}
I have retrycode Logic outside of my application which Loads the Assemblies using Assembly.LoadFile(Asmpath);
and returns the object from the loaded assembly back to the my application.
and i have the reference to the same assembly in app. which i have created using Add Refferences.
i am able to return the object. but while casting the returned object to its type in my application its throwing the following Error:
[A]SampleAssembly1.Class1 cannot be cast to [B]SampleAssembly1.Class1. Type A originates from 'SampleAssembly1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location 'C:\Users\v-saabdu\Desktop\Final Code for RetryMethod\ReflectionSamples\SampleAssembly1\bin\Debug\SampleAssembly1.dll'. Type B originates from 'SampleAssembly1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Users\v-saabdu\Desktop\Final Code for RetryMethod\ReflectionSamples\ReflectionAssembly\bin\Debug\SampleAssembly1.dll'.
from the above error message I understood that the way assemblies are loaded in my application and in retrycode (outside of my app) differning in context.
can any one suggest me solution for this..
Thankx,
Assembly assembly = Assembly.LoadFile("Libtest.dll");
TestLib lib = (TestLib)assembly.CreateInstance("Lib");
lib.doSomething();
Lib class must implement the TestLib interface and must be accessible both from both Foo.dll and bar.dll.