2011-10-25 8 views
1

.NET Windowsサービスのアプリケーションドメイン間でオブジェクトをマーシャリングするときに問題が発生します。クラスが別の名前空間にあるときの.NETオブジェクトのマーシャリング

私はアプリケーション全体でマーシャリングで多くの経験を持っていないので、最初のアプリケーションがコンセプトのシンプルな証拠だったMarshalByRefObject

プロキシを介してアプリケーションドメインと実行コード全体で2のアプリのこと元帥オブジェクト作成されましたドメイン。これには、プロジェクトの残りの部分と同じ名前空間にMarshalByRefObjectが定義されている単一のプロジェクトが含まれています。このアプリは、他のアプリとほぼ同じコードを使ってうまく動作します。主な違いは、2番目のアプリケーションでマーシャリングするクラスが別の名前空間で定義されていることです。

他のプロジェクトは複雑ですが、複数のプロジェクトを持つWindowsサービスです。メインのWindowsサービスは、マーシャリングを実行するライブラリをロードします。マーシャルターゲットタイプのクラスタイプは別のライブラリで定義されているため、完全修飾名前空間/クラス名を使用します。

私が直面しています問題は、それはそれ以下のコードの最後の行に到達したときには、例外をスローすることです:

は組み立てProductNameService製品からCompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompilerをロードできませんでした。 nameはメインのWindowsサービスクラスです。

コード:

AppDomain compilerDomain = null; 
AppDomainSetup compilerDomainSetup; 
CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler scriptCompiler; 

... 

// Setup a seperate AppDomain 
compilerDomainSetup = new AppDomainSetup(); 
exeAssembly = Assembly.GetEntryAssembly().FullName; 
compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory; 

compilerDomainSetup.DisallowBindingRedirects = false; 
compilerDomainSetup.DisallowCodeDownload = true; 
compilerDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 
compilerDomain = AppDomain.CreateDomain("LiveLinkCSScriptDomain", null, compilerDomainSetup); 

// Create an instance of the MarshalByRefScriptCompiler in the other AppDomain 
scriptCompiler = (CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler)compilerDomain.CreateInstanceAndUnwrap(exeAssembly, typeof(CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler).FullName); 

私はこの例外の研究を行っていると私は見つけるほとんどすべてが、それはDLLのバージョン管理に問題があることを述べている、しかし、私のDLLのは、GACに含まれていない、とあります他のバージョンはインストールされていません。私はきれいにビルドして、installutilでサービスをインストールしています。

私はタイプが別のライブラリであるため、MarshalByRefScriptCompilerをロードすると問題がある場合、私は疑問に思ってマーシャリング

を行うコードを作成するためのガイドとしてMSDN documentationを使用。私は単純なwinformsアプリケーションでMarshalByRefScriptCompilerを作成することができますが、私はWindowsサービスで例外を取得します。

ヒントや洞察力があれば幸いです。

答えて

2

私はあなたを助けることができるはずです。私は多くの時間(How do I pass references as method parameters across AppDomains?)さまざまなクロスappdomainマーシャリングの問題に取り組んで過ごしました。私の最初の提案は、の代わりにのCreateInstanceFromAndUnwrapとCreateInstanceAndUnwrapを使用することです。

また、私はこのラインの少し警戒してる:

元のAppDomainが作成されている方法
compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory; 

? IISでホストされていますか?元のAppDomainはShadowCopyを使用しますか?すべてのdllは1つのフォルダに含まれていますか?

EDIT:

要約すると、あなたはあなたのcompilerDomainSetup場合CreateInstanceAndUnwrapを使用することができます。ApplicationBaseはdllを含むディレクトリに設定され、正しい最初のパラメータ(typeof(MarshalByRefScriptCompiler).Assembly.FullNameなど)を渡します。

または、最初のパラメータとして格納しているアセンブリのCreateInstanceFromAndUnwrapを使用して、ちょうど場所(例えばtypeof演算(MarshalByRefScriptCompiler).Assembly.Location)に渡すことができます。

+0

お返事ありがとうございます。私はApplicationBaseを次のように変更しました: 'compilerDomainSetup.ApplicationBase = @" C:\ ServiceSchedulerDebug \ Debug ";'これはすべてのDLLが(すべて単一のフォルダにあります)です。しかし、例外ではまだそれはC:\ Windows \ System32を見て示しています。何か案は? – dmck

+0

あなたの変更のようなほとんどの音が拾われなかった。あなたのWindowsサービスはC:\ ServiceSchedulerDebug \ Debugフォルダで動作していますか? –

+0

はい、私はデバッグビルドを行い、コマンドラインからinstallutilを使ってインストールしています。サービスはC:\ ServiceScheduler \ Debugにインストールされます(ディレクトリが変更されました)。 AppDomain.CurrentDomain.BaseDirectoryはC:\ ServiceScheduler \ Debugです。私はまだそれがC:\ Windows \ System32で見ている理由を理解しようとしていますが、これは問題を引き起こしていると思います。 – dmck

1

最初に、Process Monitorを試して、欠落しているタイプをロードしようとしている場所を判断することができます。それはあなたのアセンブリのために間違ったディレクトリを探しているのと同じくらい簡単です。

+0

ありがとう私はそれを試してみましょう.. – dmck

関連する問題