Need to process a dataset via dynamic runtime code in C# - c#

I have been working with C# dynamic code for run time processes. My problem is I cannot seem to pass a dataset object to the dynamic code with out getting:
"Could not load file or assembly 'file:///C:\Users\mgallanx\AppData\Local\Temp\npbylo5z.dll' or one of its dependencies. The system cannot find the file specified."
Here is the simplest dataset processing string I am using:
mycodestring = "using System;
using System.Data;
namespace DaCodeNS
{
public static class DaCode
{
public static DataSet DaMethod( Dataset dsIn)
{
return dsIn;
}
}
}"
the calling method sets the parameters to add the System.dll and System.Data.dll, creates an Object[] mp to one element of sIn.
The call then is:
CompilerResults results = provider.CompileAssemblyFromSource (parameters, mycodestring);
var cls = results.CompiledAssembly.GetType ("DaCodeNS.DaCode");
var method = cls.GetMethod ("DaMethod", BindingFlags.Static | BindingFlags.Public);
return (DataSet) method.Invoke (null, mp);
It breaks at the GetMethod line.
I can get similar code passing integers around to play, but changing the return and passed to DataSet blows up. Any help is appreciated.

You're most likely not including all of the references needed to make your dynamic code compile/run. A simple way to find all the needed references would be to create a standa-alone project that just includes the code you're going to compile. Then look at the references you needed to add to the project to get it to compile/run.

Related

Is it possible to add a new dependency to a .dll without changing the source code?

I have two dotnetcore2.1 projects. First project calls a method of the second project via reflection.
using System;
using System.Reflection;
namespace experiment1
{
class Program
{
static void Main(string[] args)
{
Type _type = Type.GetType("experiment2.Program");
object _object = Activator.CreateInstance(_type);
MethodInfo info = _type.GetMethod("SecondProjectsMethod");
info.Invoke(_object, new object[]{});
}
}
}
I can't give any reference to the Second Project nor changes its code. How can I make this call successfully without adding a Reference to the First Project? I tried to add records to the first project's deps-file and execute the first program like this:
dotnet exec --depsfile experiment1.deps.json experiment1.dll
It didn't work. Is it even possible to do this by changing deps-file or any other config? Or should I manipulate .dll file somehow? Which direction I should go?
You can manually load the assembly by calling:
Assembly.Load("experiment2");
It should look for the assembly in the current folder, or use the deps file to locate it. After that, you should be able to use Type.GetType just fine.
If you want to specify the full path to the assembly, use AssemblyLoadContext.Default.LoadFromAssemblyPath instead.
You can refer to this page for more information on the different ways of loading an assembly in .net core.

Reflection TargetInvocationException error when charging DLL dynamically

I need to load a DLL dynamically so I can compare two identical methods from different DLL version, without using Web-services.
I already did that on an other project, and it worked perfectly.
But the Dll I need to import is more complex now, it uses C++ dll reference etc.
Here is the part of code :
Type type1 = dll1.GetType("MyNamespace.MyClass");
var instance1 = Activator.CreateInstance(type1, "some string", "some string", "some string");
MethodInfo myMethod1 = type1.GetMethods().Where(X => X.Name == "myMethod").FirstOrDefault();
object retour1 = (object)myMethod1.Invoke(instance1, new object[] { fichier.FullName, dossier.FullName, null, false, null });
The last line of code return a "System.Reflection.TargetInvocationException"
apperently in "mscorlib.dll"
Since I am quite new to reflection, I do not really know what is happening, is this because of c++ dll, or did i forget something? The same code works on simpler DLL.
Maybe there is a better way to do this task, but as I cannot do the following :
Using myLib
Using myLib
I am stuck, any help would be very appreciated =)

Could not load file or assembly 'Microsoft.Data.Tools.Schema.Sql' when trying to create an instance of a generic type

We have a unit test project for testing SQL Server stored procedures in VS2012. I'm trying to write a generic method that builds and populates a TestCondition object:
public static T CreateTestCondition<T, P>(Expression<Func<T, P>> propertyDelegate, object value)
where T : TestCondition, new()
{
var expression = (MemberExpression)propertyDelegate.Body;
string propertyName = expression.Member.Name;
T condition = new T();
typeof(T).GetProperty(propertyName).SetValue(condition, value);
return condition;
}
And this is how the method is called:
NotEmptyResultSetCondition condition =
CreateTestCondition((NotEmptyResultSetCondition x) => x.ResultSet, 1);
When I run this, I get the following exception
Could not load file or assembly 'Microsoft.Data.Tools.Schema.Sql, Version=10.3.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
The system cannot find the file specified.
On line T condition = new T(). If I try to do something like
NotEmptyResultSetCondition condition = new NotEmptyResultSetCondition();
It works fine, however for some reason I can't create an instance using the generic type even though when I look T at runtime it has a fully qualified type name. I also tried to use the Activator class and pass in the full assembly and type names seperately, but that doesn't work either (which I'd be surprised if it did). Any idea why VS can't find the assembly?

How can I get the executing assembly version?

I am trying to get the executing assembly version in C# 3.0 using the following code:
var assemblyFullName = Assembly.GetExecutingAssembly().FullName;
var version = assemblyFullName .Split(',')[1].Split('=')[1];
Is there another proper way of doing so?
Two options... regardless of application type you can always invoke:
Assembly.GetExecutingAssembly().GetName().Version
If a Windows Forms application, you can always access via application if looking specifically for product version.
Application.ProductVersion
Using GetExecutingAssembly for an assembly reference is not always an option. As such, I personally find it useful to create a static helper class in projects where I may need to reference the underlying assembly or assembly version:
// A sample assembly reference class that would exist in the `Core` project.
public static class CoreAssembly
{
public static readonly Assembly Reference = typeof(CoreAssembly).Assembly;
public static readonly Version Version = Reference.GetName().Version;
}
Then I can cleanly reference CoreAssembly.Version in my code as required.
In MSDN, Assembly.GetExecutingAssembly Method, is remark about method "getexecutingassembly", that for performance reasons, you should call this method only when you do not know at design time what assembly is currently executing.
The recommended way to retrieve an Assembly object that represents the current assembly is to use the Type.Assembly property of a type found in the assembly.
The following example illustrates:
using System;
using System.Reflection;
public class Example
{
public static void Main()
{
Console.WriteLine("The version of the currently executing assembly is: {0}",
typeof(Example).Assembly.GetName().Version);
}
}
/* This example produces output similar to the following:
The version of the currently executing assembly is: 1.1.0.0
Of course this is very similar to the answer with helper class "public static class CoreAssembly", but, if you know at least one type of executing assembly, it isn't mandatory to create a helper class, and it saves your time.
using System.Reflection;
{
string version = Assembly.GetEntryAssembly().GetName().Version.ToString();
}
Remarks from MSDN http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getentryassembly%28v=vs.110%29.aspx:
The GetEntryAssembly method can return null when a managed assembly has been loaded from an unmanaged application. For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly.
Product Version may be preferred if you're using versioning via GitVersion or other versioning software.
To get this from within your class library you can call System.Diagnostics.FileVersionInfo.ProductVersion:
using System.Diagnostics;
using System.Reflection;
//...
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var productVersion = FileVersionInfo.GetVersionInfo(assemblyLocation).ProductVersion
This should do:
Assembly assem = Assembly.GetExecutingAssembly();
AssemblyName aName = assem.GetName();
return aName.Version.ToString();
I finally settled on typeof(MyClass).GetTypeInfo().Assembly.GetName().Version for a netstandard1.6 app. All of the other proposed answers presented a partial solution. This is the only thing that got me exactly what I needed.
Sourced from a combination of places:
https://msdn.microsoft.com/en-us/library/x4cw969y(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/2exyydhb(v=vs.110).aspx

Parse XML function names and call within whole assembly

I have written an application that unit tests our hardware via a internet browser.
I have command classes in the assembly that are a wrapper around individual web browser actions such as ticking a checkbox, selecting from a dropdown box as such:
BasicConfigurationCommands
EventConfigurationCommands
StabilizationCommands
and a set of test classes, that use the command classes to perform scripted tests:
ConfigurationTests
StabilizationTests
These are then invoked via the GUI to run prescripted tests by our QA team. However, as the firmware is changed quite quickly between the releases it would be great if a developer could write an XML file that could invoke either the tests or the commands:
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite>
<StabilizationTests>
<StressTest repetition="10" />
</StabilizationTests>
<BasicConfigurationCommands>
<SelectConfig number="2" />
<ChangeConfigProperties name="Weeeeee" timeOut="15000" delay="1000"/>
<ApplyConfig />
</BasicConfigurationCommands>
</testsuite>
I have been looking at the System.Reflection class and have seen examples using GetMethod and then Invoke. This requires me to create the class object at compile time and I would like to do all of this at runtime.
I would need to scan the whole assembly for the class name and then scan for the method within the class.
This seems a large solution, so any information pointing me (and future readers of this post) towards an answer would be great!
Thanks for reading,
Matt
To Find all classes in an assembly:
public Type FindClass(string name)
{
Assembly ass = null;
ass = Assembly.Load("System.My.Assembly"); // Load from the GAC
ass = Assembly.LoadFile(#"c:\System.My.Assembly.dll"); // Load from file
ass = Assembly.LoadFrom("System.My.Assembly"); // Load from GAC or File
foreach(Type t in ass.GetTypes())
{
if (t.Name == name)
return t;
}
return null;
}
In reality you should tag your class with an attribute, it makes them more discoverable.
To instantiate an instance of said class:
public T Instantiate<T>(Type typ, object[] arguments)
{
return (T)Activator.CreateInstance(typ, arguments, null);
}
Don't forget, you should probably wrap these with appropriate try/catch blocks
Then to find a method on a class
Type t = FindClass("MyType");
MethodInfo meth = t.GetMethod("TestSomething", typeof(string), typeof(int)); // finds public ??? TestSomething(string, int)
Just play around with the Object Browser in VStudio and learn the Reflection classes, there's lots you can do.

Categories