当从PowerShell调用时,无法在dll中转换透明代理,但在c#控制台应用程序中成功

本文关键字:代理 透明 成功 但在 控制台 转换 应用程序 dll 调用 PowerShell 当从 | 更新日期: 2023-09-27 18:09:36

我正在尝试创建一个开源库,生成一个新的AppDomain并在其中运行PowerShell脚本。我有一个静态方法,它采用powershell文件的名称和AppDomain的名称。当从c#控制台应用程序调用该方法时,该方法执行成功,但不包括PowerShell

我知道dll正在加载到第二个应用程序域,因为在fusionlog中有这个条目。

类声明和构造函数如下所示:

public class AppDomainPoshRunner : MarshalByRefObject{
    public AppDomainPoshRunner (){
        Console.WriteLine("Made it here.");
    }
}

无论我是从c#控制台应用程序还是从PowerShell应用程序运行dll,当我调用CreateInstanceFromAndUnwrap时,构造函数中的消息都会得到输出。

当我在下面的静态方法中将CreateInstanceFromAndUnwrap返回的值转换为AppDomainPoshRunner时,会发生失败。

    public static string[] RunScriptInAppDomain(string fileName, string appDomainName = "Unamed")
    {
        var assembly = Assembly.GetExecutingAssembly();
        var setupInfo = new AppDomainSetup
                            {
                                ApplicationName = appDomainName,
                                // TODO: Perhaps we should setup an even handler to reload the AppDomain similar to ASP.NET in IIS.
                                ShadowCopyFiles = "true"
                            };
        var appDomain = AppDomain.CreateDomain(string.Format("AppDomainPoshRunner-{0}", appDomainName), null, setupInfo);
        try {
            var runner = appDomain.CreateInstanceFromAndUnwrap(assembly.Location, typeof(AppDomainPoshRunner).FullName);
            if (RemotingServices.IsTransparentProxy(runner))
                Console.WriteLine("The unwrapped object is a proxy.");
            else
                Console.WriteLine("The unwrapped object is not a proxy!");  
            Console.WriteLine("The unwrapped project is a {0}", runner.GetType().FullName);
            /* This is where the error happens */
            return ((AppDomainPoshRunner)runner).RunScript(fileName);
        }
        finally
        {
            AppDomain.Unload(appDomain);
        }
    }

在PowerShell中运行时,我得到一个InvalidCastExcception与消息无法将透明代理转换为类型JustAProgrammer.ADPR.AppDomainPoshRunner

我做错了什么?

当从PowerShell调用时,无法在dll中转换透明代理,但在c#控制台应用程序中成功

我有同样的问题:我创建了一个沙箱,只有执行权限(最小权限),可以在非常受限制的环境中执行不受信任的代码。所有工作在c#应用程序,但没有工作(相同的强制转换异常),当起点是vbs脚本创建。net COM对象。我想PowerShell也使用COM。我使用AppDomain找到了解决方法。DoCallBack,它避免从appdomain获取代理。这是代码。如果你找到一个更好的选择,请张贴。注册GAC对我来说不是一个好的解决方案…

    class Test
    {
        /*
         create appdomain as usually
        */
        public static object Execute(AppDomain appDomain, Type type, string method, params object[] parameters)
        {
            var call = new CallObject(type, method, parameters);
            appDomain.DoCallBack(call.Execute);
            return call.GetResult();
        }
    }
    [Serializable]
    public class CallObject
    {
        internal CallObject(Type type, string method, object[] parameters)
        {
            this.type = type;
            this.method = method;
            this.parameters = parameters;
        }
        [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
        public void Execute()
        {
            object instance = Activator.CreateInstance(this.type);
            MethodInfo target = this.type.GetMethod(this.method);
            this.result.Data = target.Invoke(instance, this.parameters);
        }
        internal object GetResult()
        {
            return result.Data;
        }
        private readonly string method;
        private readonly object[] parameters;
        private readonly Type type;
        private readonly CallResult result = new CallResult();
        private class CallResult : MarshalByRefObject
        {
            internal object Data { get; set; }
        }
    }

这听起来很像一个加载上下文问题。类型标识不仅仅与物理汇编文件有关;这也关系到它是如何和在哪里装载的。这是苏珊娜·库克的一篇旧博客文章,你可能要读十五遍才能开始理解你的问题。

选择绑定上下文

http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57143.aspx

在你说"但它在控制台应用程序中工作"之前,请记住,当从powershell运行它时,你有一个完全不同的关于调用appdomain的上下文,探测路径,身份等。

祝你好运!