Git Product home page Git Product logo

appdomaintoolkit's Introduction

AppDomain Toolkit

SUMMARY

Anyone whose ever had to deal with loading Assemblies using standard .NET reflection facilities understands that it's not straightforward. Which context should I load into? How do I know that my Assembly is imported into the correct application domain? What if I want to load two versions of the same assembly into an application domain? How can I tear down an application domain where I've loaded my own assemblies?

I've seen quite a few questions like these all over www.stackoverflow.com, and having dealt with these problems in my own research projects I decided to build a small library that provided some basic functionality:

  1. Ability to set up transient app domains that easily tear themselves down.
  2. Ability to execute remote delegates in an arbitrary app domain.

INSTALLING

Install via the package manager prompt:

PM> Install-Package AppDomainToolkit

You may also search the package gallery for AppDomainToolkit and it should show up. Click install and you're all set.

IMPLEMENTATION NOTES

There are a couple of things to be aware of when utilizing the library. Most of them are non-issues as long as you understand the load context concept of application domains, and some of them stem from the backwards idea of executing code remotely--that is it's not entirely intuitive. I've seen several answers on stackoverflow claiming to solve an application domain problem when the solution still executes the target code in the current domain. Thinking in a remoting context requires a deeper analysis of where you think call sites are executing.

Assembly Loading

The most important of issues to discuss first is how the currently executing assembly is discovered and loaded into the current and foreign app domains for class resolution. You can't execute any assembly loading into an AppDomainContext without first loading the AssemblyLoader class into that domain. There's an interface dedicated to handling domain assembly resolve events and an implementation called PathBasedAssemblyResolver. This class is responsible for loading missing assemblies into any the current application domain whenever an Assembly.Load* method is called or whenever the application domain deduces that it needs to load a specific Assembly. Events that can trigger this include all of the static Assembly methods, along with pretty much anything that reflects across that assembly. By default, the AppDomainContext class will load the currently executing assembly's path as a target for the contained IAssemblyResolver instance, but an overload of AppDomainContext.Create() allows you to pass your own AppDomainSetupInfo instance. When doing this, make sure that you set the ApplicationBase property to be the base directory where your application, and ideally the AppDomainToolkit assembly lives. Usually this can easily be done with a simple Assembly.GetExecutingAssembly.Location() call. Also note that you can access the remote and local IAssemblyResolver instances on an AppDomainContext through the context.AssemblyImporter and context.RemoteResolver properties.

Executing arbitrary code

The typical remoting scenario requires you to create an instance of a remote class using the CreateInstanceAndUnwrap method on an application domain and then utilize instance methods on that type--which is effectively instantiated in the foreign app domain. The .NET runtime also provides a way to execute a block of code in a foreign application domain via the CrossAppDomainDelegate class, but it's extremely limited. If you attempt to pass this class a lambda expression, for example, sometimes you'll get a runtime exception complaining about some mangled class name not being serializable. This will always happen if your lambda has a closure in it--that is some variable is hoisted in the class generated by the compiler to be passed back to your code. The root issue here is that the compiler does not mark the generated class as [Serializable], something MSFT says they may change in the future. But why wait? Building out our own Serializable delegates is easy enough. There are two classes equipped for handling this exact problem, that is the RemoteAction and the RemoteFunc. Please note that both of these classes require all inputs to be serializable, and all output values to be either serializable or extend MarshalObjectByRef. See the examples below for further clarification.

EXAMPLES

Load an assembly into a foreign application domain:

using(var context = AppDomainContext.Create())
{
    context.LoadAssembly(LoadMethod.LoadFile, "C:\path\to\my\test.dll");
}

The AppDomain will be set up with a temporary name, and the application base path and private bin paths will be set to the current executing assembly--which is likely the right thing to do since this assembly will be installed along side whatever program that is using it.

Load an assembly into an app domain with your own setup info:

var rootDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var setupInfo = new AppDomainSetup()
{
    ApplicationName = "My Application",
    ApplicationBase = rootDir,
    PrivateBinPath = rootDir
};

using(var context = AppDomainContext.Create(setupInfo))
{
    context.LoadAssembly(LoadMethod.LoadFrom, "C:\path\to\my\test.dll");
}

This overloaded factory method allows you to assign whatever attributes you wish to the domain setup info.

Execute an action in a foreign application domain with arguments:

using(var context = AppDomainContext.Create())
{
    RemoteAction.Invoke(
        context.Domain,
        "Hello World",
        (message) =>
        {
            var msg = message + " from AppDomain " + AppDomain.CurrentDomain.SetupInformation.ApplicationName
            Console.WriteLine(msg);
        });
}

All arguments passed through the static Invoke method must be serializable or MarshalByRefObject derivatives.

Execute a function in a foreign application domain with a return value:

using(var context = AppDomainContext.Create())
{
    var area = RemoteFunc.Invoke(
        context.Domain,
        3.146,
        5,
        (pi, r) =>
        {
            return pi * r * r;
        });
}

Return values and inputs may be serializable or MarshalByRefObject derivatives. Pay attention to the lifetime cycle of any objects marshaled by reference. If the time runs out, then the returned value will be GC'd before you're finished with it. Function arguments passed to Invoke must be serializable.

Execute a function with my own custom serializable types:

Reply reply = null;
using(var context = AppDomainContext.Create())
{
    reply = RemoteFunc.Invoke(
        context.Domain,
        new Request("Hello World"),
        (request) =>
        {
            return !string.IsNullOrEmpty(request.Message) ?
                new Reply("Hello yourself!") :
                new Reply("You said nothing!");

        });
}

// Since the reply is serializable, you can use it after the domain has
// been unloaded! This is super powerful!
Console.WriteLine(reply.Message);

[Serializable]
public class Request
{
    public Request(string message)
    {
        this.Message = message;
    }

    public string Message { get; private set; }
}

[Serializable]
public class Reply
{
    public Request(string message)
    {
        this.Message = message;
    }

    public string Message { get; private set; }
}

Execute remote code and return a proxy

using(var context = AppDomainContext.Create())
{
    var result = RemoteFunc.Invoke(
        context.Domain,
        "Hello",
        (phrase) =>
        {
            return new Greeter(phrase);
        });

    // Executes in the remote domain.
    result.SayHello("jduv");
}

public class Greeter : MarshalByRefObject
{
    private readonly string helloPhrase;

    public void RemoteGreeter(string helloPhrase)
    {
        this.helloPhrase = helloPhrase;
    }

    public void SayHello(string name)
    {
        return this.helloPhrase + " " + name + "!";
    }
}

This code is quite powerful. It will create a remote object and return a handle to it as long as the remote class extends MarshalByRefObject. It's important to understand here, though, that the remote object won't live outside the using block. If you wish to persist a remote object longer, check out the next example. Also note that you can pass constructor arguments to the RemoteFunc.Invoke method. It's a simple params array after the AppDomain argument.

Create a persistent remote proxy

var context = AppDomainContext.Create()

// The second arg is ctor arguments.
var remoteGreeter = Remote<Greeter>.CreateProxy(context.Domain, "Hello");

remoteGreeter.SayHello("jduv");

// Eventually, it's a good idea to unload the app domain.
// *Always* use dispose for this. Don't call AppDomain.Unload(context.Domain)
context.Dispose();
var context = AppDomainContext.Create();

// Alternatively, you can place a proxy into a using block for automatic disposal.
using(var remoteGreeter = Remote.<Greeter>.CreateProxy(context.Domain, "Hello"))
{
    remoteGreeter.SayHello("jduv");
}

The Remote class was stolen off the internet and modified slightly to suite my needs. Credit should be placed where credit is due, so the original version of the Remote class lives here. Alot of the inspiration for this entire library was based on that implementation along with some stackoverflow questions I've been lurking.

appdomaintoolkit's People

Contributors

jduv avatar joebrockhaus avatar martindevans avatar rducom avatar rene-sackers avatar smalgin-esri avatar xumix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

appdomaintoolkit's Issues

How to persist an AppDomain and manually unload assembly?

I'm working on an app that needs to dynamically load assemblies that are needed to connect to SQL Server using NHibernate. I am creating these assemblies on the fly and then need to load them into a separate AppDomain. In your examples, I see that you are using the using(){} block to create an AppDomainContext. Instead of a using(){} block, if I have a persistent variable to hold the AppDomainContext and then manually call the Dispose() method on it, will that effectively do the same thing? The assembly needs to be released so that another instance of my driver class can load it. Will disposing the AppDomainContext also definitively unload the assembly?

EDIT: I meant to mark this with a Question label, but seems like I cannot do that. I added a follow-up question.

Accessing types from loaded assemblies

Hi, I'm trying to use your library but I'm facing a problem. So far I've managed to load an assembly (using the method LoadFile), and inspecting the context with Visual Studio I've seen it's loaded correctly. The problem is that I can't access by code that assembly (like, for instance, using context.Domain.GetAssemblies()).

The scenario I'm using your library for is to be able to load external assemblies and instantiating and using classes inside without knowing what exact type are them (but knowing they're subclasses of other classes I know). So, I can't directly call "new MyClass()" because I don't know what MyClass is, but it's inside the assembly. If I'd be able to access the loaded assembly, I could fetch the type and do something like Type.GetConstructor().

Is there any way to access the Assembly objects loaded in the context?

Thanks.

nuget package request

This would be great to have available as a nuget package; really takes the tedium out of using small libraries like this in your own projects.

IDisposable usage is not intuitive

Hi,

First of all, thanks for the library!
While I was implementing my code with this library, I ran into an interesting issue with a piece of code that, at first glance, seems fairly normal:

using (var context = AppDomainContext.Create())
{
    using (var proxy = Remote<MyType>.CreateProxy(context.Domain))
    {

    }
}

By the dispose of the inner block, both the proxy and the wrapped AppDomain are disposed (and therefore the AppDomain is unloaded), and by the dispose of the outer block, there is an exception because it tries to re-unload the wrapped appdomain (the appdomain wrapper object for the context is different than the appdomain wrapper for the proxy, and it is still not marked as disposed, so it thinks the appdomain is still up and running).

I've seen the code and the readme file, and I think that the idea is, if you use Remote.CreateProxy, then you shouldn't dispose the context by hand. However, this is counterintuitive in two fronts:

  1. it seems odd to have a IDisposable object (context) that you must NOT dispose, and more importantly,
  2. what if you create more than one proxy via Remote.CreateProxy? You then must dispose just one of them, and not the others or the context.

Anyway, it's not a bug per-se, but I thought it was worth mentioning.

Thanks,

Fernando Nájera

Serialization failure using RemoteFunc.Invoke

Hi there,

I'm stuck trying to use RemoteFunc.Invoke to make use of a dynamic domain. It appears I'm hitting the exact serialization issue mentioned in the readme (the lambda not getting marked as serializable).

There's a class DTLogic.Slave.DynamicDomain+<>c__DisplayClass7 which is apparently trying to be serialized. Using ILSpy on my assembly, this appears to be the RemoteFunc.Invoke expression :(

.class public auto ansi beforefieldinit DTLogic.Slave.DynamicDomain
extends [mscorlib]System.Object
{
// Nested Types
.class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass7'
    extends [mscorlib]System.Object
{

My lambda takes a custom serializable type (InvokeRequest) and returns another serializable one (InvokeResult). I've been chipping away at these to get them happy, now everything seems to be unblocked, but then this. Doh.

Finding this library has been great and saved me a bunch of time, I'm just now at the last hurdle of actually getting it running. I'd love to hear any ideas you might have on solving this. I can post a snippet if that helps.

Here's my stack trace:

System.Runtime.Serialization.SerializationException: Type 'DTLogic.Slave.DynamicDomain+<>c__DisplayClass7' in Assemb
y 'DT.Logic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

Server stack trace:
at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector su
rogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, Object
riter objectWriter, SerializationBinder binder)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberN
meInfo, NameInfo typeNameInfo)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __Bina
yWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object gr
ph, Header[] headers, Boolean fCheck)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeMessageParts(ArrayList argsToSerialize)
at System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage..ctor(IMethodCallMessage mcm)
at System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage.SmuggleIfPossible(IMessage msg)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at AppDomainToolkit.RemoteFunc2.Invoke(T arg, Func2 toInvoke)
at AppDomainToolkit.RemoteFunc.Invoke[T,TResult](AppDomain domain, T arg1, Func`2 toInvoke) in z:\Developer\GitHu
\AppDomainToolkit\AppDomainToolkit\RemoteFunc.cs:line 76
at DTLogic.Slave.DynamicDomain.ExecuteInvoke(InvokeRequest request) in c:\Users\Eddie\Documents\work\git\dtrunner
DT.Logic\Slave\DynamicDomain.cs:line 84

Issue with Resolve event

Thanks for this great AppDomainToolkit!
I had an issue with the "probePaths" order in the PathBasedAssemblyResolver.Resolve() method. The solution for me was that I changed the constructor of the AppDomainContext class: I swapped the two AddProbePath() lines because I wanted to search in the PrivateBinPath directory first. There I want to load a plugin with some dependencies. Unfortunately one dependency (assembly dll) was also in the ApplicationBase path but had the wrong version. So I wanted to load the correct version of the assembly which was in the PrivateBinPath.
Maybe this was only an issue for me. But one general solution could be not to add the ApplicationBase directory to the search paths. If someone wants to add it, he could add it to the PrivateBinPath ( ';' separated) in the order he prefers.
I just want to let you know. Maybe you have other ideas how to do this correctly.
Thanks, Lorenz

Assembly deep references

Hi im new using this toolkit,

If i call LoadAssemblyWithReferences and my dll have references in the references this dont load it then i change the method to

public IList<Assembly> LoadAssemblyWithReferences(LoadMethod loadMethod, string assemblyPath)
{
    var assembly = this.LoadAssembly(loadMethod, assemblyPath);

    Dictionary<string, AssemblyName> listFound = new Dictionary<string, AssemblyName>();
    List<Assembly> results = new List<Assembly>();
    Stack stack = new Stack();

    results.Add(assembly);

    AssemblyName[] an = assembly.GetReferencedAssemblies();

    for (int i = an.Length - 1; i >= 0; --i)
    {
        listFound.Add(an[i].Name, an[i]);
        stack.Push(an[i]);
    }

    while (stack.Count > 0)
    {
        var info = (AssemblyName)stack.Pop();

        Assembly child = Assembly.Load(info.Name);
        results.Add(child);

        AssemblyName[] subchild = child.GetReferencedAssemblies();
        for (int i = subchild.Length - 1; i >= 0; --i)
        {
            if (!listFound.ContainsKey(subchild[i].Name))
            {
                listFound.Add(subchild[i].Name, subchild[i]);
                stack.Push(subchild[i]);
            }
        }
    }

    return results;
}

And this load all the references tree...
Sorry i dont know how to make a "pull request" and i dont know if this go help..

Unable to see how this can work when the assemblies being loaded are not known to the host at compile time

Please advise if this scenerio is possible.
Attempting to use this library to support plugins. where the plugins implement a simiple interface with a Run() method (that will display its own form etc)
From the examples provided I don't see a way to crea ta proxy on the host side of things that can interact with the assembly loaded in the app domain. I know I must be missing something... I dont want the host to have to have the dlls being loaded and executed in its reference list.
please advise

Appdomain is sometimes loading dlls from Parent directory of PrivateBinPath and sometimes from PrivateBinPath

Hi,

I am using AppdomainToolKit and my code goes as follows:

         string basePath = "C:\\Uploader\\Bin";
         var setupInfo = new AppDomainSetup();
         setupInfo.ApplicationName = "SomeName";
         setupInfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
         setupInfo.PrivateBinPath = Path.Combine(basePath, "PluginFolder\\Plugin.dll");
         try
          {
              var context = AppDomainContext.Create(setupInfo);
              context.LoadAssembly(LoadMethod.LoadFrom, Path.Combine(basePath,                                                                                                                       
                                                   "PluginFolder\\Plugin.dll"));
              return context.Domain;
          }

I see that Appdomain is sometimes loading dlls from basePath (C:\Uploader\Bin) and sometimes from PrivateBinPath.

The exact issue is Plugin.dll is using Polly.dll which is signed and PluginFolder(C:\Uploader\Bin\PluginFolder) contains it. And C:\Uploader\Bin (basePath) is holding another Polly.dll which is unsigned. Now when the Plugin.dll is loaded into Appdomain its looking for Polly.dll in basePath (C:\Uploader\Bin) instead of C:\Uploader\Bin\PluginFolder and throws exception.
Am i doing the right thing in my code?

Please help me to understand the concept behind this issue and help me resolve it.

Examples of hot swapping assemblies

@jduv

Great library. Do you have any examples of hot swapping assemblies and calling methods on those classes using reflection? My use case requires loading a "plugin", calling a method on that plugin, unloading that plugin and then replacing with a new version, and then calling a method on that newly loaded plugin.

Is that possible with this library?

Is there a way to get a direct reference to the Assembly object in the AppDomainContext?

I see that you can access the AssemblyTargets by iterating through AppDomainContext.LoadedAssemblies, but I'm not seeing a way to get a direct reference to the Assembly object. I have a wrapper class that operates on the Assembly object directly and I was adding an AppDomainContext as an intermediary layer between the Assembly and the wrapper class. Is there a way to access the Assembly object from an AppDomainContext in which the assembly was loaded?

AppDomain requests unrestricted access upon creation

Thanks for this great library!

Unfortunately, I have an issue.

I am trying to create a sort of plugin-in based application. Where the plugins have very restricted access. Basically plain C#, and an API that will be exposed.
When I try to restrict the created app domain, it seems to instantly demand unrestricted permissions when the AppDomain gets created:

error

Do you have any clue why this is happening?
I've uploaded the project to GitHub, you may view it here.

Cannot build downloaded ZIP

I downloaded a zip version of the solution and I get the following error:

Error 1 Cannot import the following key file: Key.pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: VS_KEY_************************** AppDomainToolkit

Key is hidden, but the error is generic. When I tried to run sn -i Key.pfx VS_KEY_**************************, it asked me for a password which I didn't have or find in the documents. How should I fix this issue?

EDIT: I ran the sn command on Key.pfx.

getting "could not load file or assembly"

hi im trying to create a object instance in a "remote domain". but when i'm finding the object class i'm getting this error:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.IO.FileNotFoundException: Could not load file or assembly 'kalman, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'kalman, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.Load(String assemblyString)
   at System.UnitySerializationHolder.GetRealObject(StreamingContext context)

   at AppDomainToolkit.RemoteFunc`2.Invoke(T arg, Func`2 toInvoke)
   at AppDomainToolkit.RemoteFunc.Invoke[T,TResult](AppDomain domain, T arg1, Func`2 toInvoke) in z:\Developer\GitHub\AppDomainToolkit\AppDomainToolkit\RemoteFunc.cs:line 76
   at tiempoRealComun.Objects.Method..ctor(String rutadll, Configuration conf) in c:\CodigoTransmodeler\simTiempoCercanoReal\tiempoRealComun\Objects\Method.cs:line 27
   at simTiempoCercanoReal.UI.uiConfiguration.cbxMetodos_SelectedIndexChanged(Object sender, EventArgs e) in c:\CodigoTransmodeler\simTiempoCercanoReal\simTiempoCercanoReal\UI\uiConfiguration.cs:line 174
   at simTiempoCercanoReal.UI.uiConfiguration.rellenarDesdeArchivo() in c:\CodigoTransmodeler\simTiempoCercanoReal\simTiempoCercanoReal\UI\uiConfiguration.cs:line 72
   at simTiempoCercanoReal.UI.uiConfiguration.btnLoadConfiguration_Click(Object sender, EventArgs e) in c:\CodigoTransmodeler\simTiempoCercanoReal\simTiempoCercanoReal\UI\uiConfiguration.cs:line 56
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

=== Pre-bind state information ===
LOG: DisplayName = kalman, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/TransModeler/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.

but when i load the dll using the "normal way", im not getting any error.

this is my source code:

                FileInfo fio = new FileInfo(dllpath);

                context.RemoteResolver.AddProbePath(fio.Directory.FullName);
                dll = context.LoadAssembly(LoadMethod.LoadFrom, dllpath);
                var methodType= RemoteFunc.Invoke(
                                        context.Domain,
                                        dll.FullName,
                                        (string fullname) =>
                                        {
                                            Assembly asm = AppDomain.CurrentDomain.GetAssemblies().Single(s => s.FullName.Equals(fullname));
                                            return asm.GetType("algoritmo", true, true);
                                        });

Test FindByCodeBase_NoRefAssembly_LoadFrom fails when project is part of another solution

I imported the projects AppDomainToolkit and AppDomainToolkit.UnitTests to a solution in which I've been working to debug through your code, but it seems that two tests are failing, presumably because of incorrect paths. The error message is as such:

Could not load file or assembly 'file:///C:...\CSharp\Automation\TestResults****************** 2014-07-02 14_13_25\Out\test-assembly-files\TestWithNoReferences.dll' or one of its dependencies. The system cannot find the file specified.

I've hidden some personal information in that path but if you're interested in the knowing the full path I can tell you. I'm guessing the problem is happening because the project folder is NOT under the solution folder, and I can see that TestWithNoReferences.dll does exist in the project folder at C:...\CSharp\AppDomainToolkit-master\AppDomainToolkit-master\AppDomainToolkit.UnitTests\bin\Debug\test-assembly-files\TestWithNoReferences.dll .

Note that the test is looking under the solution folder rather than the project folder, and TestWithNoReferences.dll exists in the project folder. I can provide any additional debugging information you may need.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.