3

新しいライブラリを生成し、その中でスクリプトを実行するオープンソースライブラリを作成しようとしています。PowerShellファイルの名前との名前を取得する静的メソッドがあります。このメソッドは、C#コンソールアプリから呼び出された場合は正常に実行されますが、実行されません。AppDomainPowerShellAppDomainPowerShell

フュージョンログにこのエントリがあるため、dllが2番目のアプリドメインに読み込まれていることがわかります。

クラス宣言とコンストラクターは次のようになります。

public class AppDomainPoshRunner : MarshalByRefObject{

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

コンストラクター内のそのメッセージは、C#コンソールアプリから実行するかPowerShellアプリから実行するかに関係なく、 CreateInstanceFromAndUnwrapを呼び出すと出力されます。

以下の静的メソッドでAppDomainPoshRunnerCreateInstanceFromAndUnwrapに返された値をキャストすると、失敗が発生します。

    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

私は何が間違っているのですか?

4

2 に答える 2

2

私は同じ問題を抱えていました: 非常に制限された環境で信頼できないコードを実行するために、実行のみのアクセス許可 (最小限の権限) を持つサンドボックスを作成しました。C# アプリケーションではすべてうまく機能しましたが、開始点が .NET COM オブジェクトを作成する vbs スクリプトである場合は機能しませんでした (同じキャスト例外)。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; }
        }
    }
于 2012-12-06T21:02:43.383 に答える
0

これは、ロード コンテキストの問題によく似ています。型 ID は、物理アセンブリ ファイルだけに関するものではありません。また、ロードされた方法と場所についてもです。これは、Suzanne Cook の古いブログ投稿です。問題を理解できるようになるまで、おそらく 15 回は読む必要があるでしょう。

バインディング コンテキストの選択

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

「でもコンソール アプリで動作する」と言う前に、PowerShell から実行する場合、呼び出し元の appdomain のコンテキスト、プローブ パス、ID などに関して、まったく異なるやかんがあることを思い出してください。

幸運を!

于 2011-09-25T18:47:55.237 に答える