2011-10-25 15 views
1

我在.NET Windows Service中跨應用程序域編組對象時遇到問題。當類在另一個命名空間中時編組.NET對象

我已經通過代理MarshalByRefObject

的首次應用是一個觀念的一個簡單證明,因爲我沒有很多的經驗,在應用程序編組創建了兩個應用程序的元帥對象跨應用程序域和運行代碼域。它包含一個項目,其中MarshalByRefObject在與項目其餘部分相同的名稱空間中定義。這個應用程序工作正常,使用與我的其他應用程序幾乎相同的代碼。主要區別在於我在第二個應用中編組的類是在另一個命名空間中定義的。

其他項目比較複雜,它是一個包含多個項目的Windows服務。主要的Windows服務加載一個庫,它進行編組。 Marshal目標類型的類型在另一個庫中定義,因此我使用完全限定的名稱空間/類名稱。

我現在面臨的問題是,當它到達它下面的代碼的最後一行拋出異常:

未能從程序集加載CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler ProductNameService其中產品名稱是主要的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安裝該服務。

我用MSDN documentation爲導向,創造,做編組

我想知道是否有與加載MarshalByRefScriptCompiler一個問題,因爲該類型是在另一個庫中的代碼。我可以在簡單的winforms應用程序中創建MarshalByRefScriptCompiler,但我在我的Windows服務中遇到了異常。

任何提示或見解將不勝感激!

回答

2

我應該可以幫到你。我最近花了很多時間(How do I pass references as method parameters across AppDomains?)處理不同的跨域apparmain編組問題。我的第一個建議是嘗試使用CreateInstanceFromAndUnwrap而不是CreateInstanceAndUnwrap

我也有點擔心這行:

compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory; 

如何被創建了原始的AppDomain?您是否託管在IIS中,在這種情況下,您的原始AppDomain將使用ShadowCopy?所有的dll都涉及單個文件夾嗎?

編輯:

總之,如果你的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

相關問題