.NET remoting exception: Permission denied: cannot call non-public or static methods remotely

孤者浪人 提交于 2019-12-13 13:27:07

问题


I'm writing a program which will allow to load a specific managed .DLL file and play with it. Since I want the ability to unload the .DLL file, I'm creating two AppDomains - one for the app itself, the other for the currently loaded .DLL.

Since most of the objects in the loaded .DLL do not serialize well, I'm creating a MarshalByRefObject wrapper class which will keep the object itself in its own AppDomain, and expose some reflection functions to the main application AppDomain.

However when I try to invoke a method on the remote object I get stuck with an exception:

Permission denied: cannot call non-public or static methods remotely.

This is very strange, because I'm not using any non-public or static methods at all. In essence, what I have is:

class RemoteObjectWrapper: MarshalByRefObject
{
    private Type SourceType;
    private object Source;

    public RemoteObjectWrapper(object source)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        this.Source = source;
        this.SourceType = source.GetType();
    }
    public T WrapValue<T>(object value)
    {
        if ( value == null )
            return default(T);
        var TType = typeof(T);
        if (TType == typeof(RemoteObjectWrapper))
            value = new RemoteObjectWrapper(value);
        return (T)value;
    }
    public T InvokeMethod<T>(string methodName, params object[] args)
    {
        return WrapValue<T>(SourceType.InvokeMember(methodName,
            System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Instance |
            System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, this.Source, args));

    }
}

And I get the exception when I try to do:

var c = SomeInstanceOfRemoteObjectWrapper.InvokeMethod<RemoteObjectWrapper>("somePublicMethod", "some string parameter");

What's going on here? As far as I can understand, the InvokeMethod method doesn't even get executed, the exception is thrown when I try to run it.

Added: To clarify - SomeInstanceOfRemoteObjectWrapper is constructed in the .DLL's AppDomain and then returned to my main AppDomain, The InvokeMethod<T>() is called from my main AppDomain (and I expect it to execute in the .DLL's AppDomain).


回答1:


Even the method InvokeMethod<T> is public it is contained within an internal class. No modifier in C# makes it internal. Hence the effective visibility of InvokeMethod<T> is internal and you are getting the exception. Making RemoteObjectWrapper public should fix this problem.




回答2:


I have the exact same problem. If you an object such as:

class MyClass : MarshalByRefObject
{
  public T Foo<T>() where T : MarshalByRefObject {
    // stuff
  }
}

Calls to MyClass.Foo with an internal type T work fine but only as long as your MyClass object is not remote. I suppose this is because you can't necessarily assume the place you're making the call to has any access to T. It's very awkward, however, when you can't make the type you're using public. You can sometimes get around it by wrapping or replacing Foo with:

class MyClass : MarshalByRefObject
{
  public object Foo(Type t) {
    // stuff
  }
}

Which isn't type safe at all and requires a cast on the caller's side. I don't know if there's a better solution, though, if you can't be bothered to expose your internal type.



来源:https://stackoverflow.com/questions/2497484/net-remoting-exception-permission-denied-cannot-call-non-public-or-static-met

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!