2013-05-26 44 views
2

好了,所以...我有一個WPF應用程序(我們稱之爲Launcher.exe)加載並執行另一個WPF應用程序(我們稱之爲Loaded.exe)動態地使用這樣的事情:動態加載的程序集 - 設置及通訊

Byte[] assemblyData; 

using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) 
    assemblyData = reader.ReadBytes(Convert.ToInt32(fs.Length)); 

Assembly assembly = Assembly.Load(assemblyData); 
MethodInfo method = assembly.EntryPoint; 

if (method != null) 
{ 
    Object instance = assembly.CreateInstance(method.Name); 
    method.Invoke(o, null); 
} 

現在......問題是Launched.exe在文件Loaded.exe.config中有它自己的設置,並且它也在綁定中使用它們。例如:

Topmost="{Binding Mode=TwoWay, Path=Topmost, Source={x:Static p:Settings.Default}}" 

首先的問題是,如何才能讓我的動態加載的程序集正確加載/綁定/更新,更普遍的,使用自己的設置?我不認爲它可以處理這個自動...

第二個問題是:可以Loaded.exe溝通Launcher.exe?假設Loaded.exe需要一些數據,只有Launcher.exe可以檢索...它如何要求它?我想我需要像兩個程序集之間的代理,但我甚至不知道如何開始編碼...

回答

1

我建議你需要加載一個單獨的程序集與它自己的.config文件,不是嗎? 我這樣做的一種方法是將程序集加載到新的AppDomain中。您可以將該程序集部署到具有所有必需參考的單獨文件夾中。

先設定的AppDomain,在這裏你有一個方法:

AppDomain getAppDomainForAssembly(string assemblypath, string appdomainname) 
    { 
     //this._assembly_file = AssemblyFile; 

     string _assembly_file_name = System.IO.Path.GetFileName(assemblypath); 
     string _rootpath = System.IO.Path.GetDirectoryName(assemblypath); 

     //this._assembly_class_name = AssemblyClassNameToInstance; 
     AppDomainSetup _app_domain_info = new AppDomainSetup(); 
     _app_domain_info.ApplicationBase = _rootpath; 
     _app_domain_info.PrivateBinPath = _rootpath; 
     _app_domain_info.PrivateBinPathProbe = _rootpath; 
     _app_domain_info.ConfigurationFile = _rootpath + @"\app.config"; //Here put the path to the correct .assembly .config file 
     AppDomain _app_domain = AppDomain.CreateDomain(
      appdomainname, null, _app_domain_info); 

     return _app_domain; 
    } 

然後得到執行方法上裝配的對象的實例:

protected System.Reflection.Assembly _asm_resolve(string assemblyFile) 
    { 
     return System.Reflection.Assembly.LoadFrom(assemblyFile); 
    } 

object getInstanceFromAppDomain(ref AppDomain appDomain, 
    string assemblyPath, string className = null) 
    { 
     if (string.IsNullOrEmpty(className)) 
     { 
      System.Reflection.Assembly assembly = _asm_resolve(assemblyPath); 
      System.Reflection.MethodInfo method = assembly.EntryPoint; 

      return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name); 
     } 
     else 
     { 

      return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className); 

     } 
    } 

即使我們知道對象類型,我們可以創建一個通用類型的方法:

T getInstanceFromAppDomain<T>(ref AppDomain appDomain, 
string assemblyPath, string className = null) 
    { 
     if (string.IsNullOrEmpty(className)) 
     { 
      System.Reflection.Assembly assembly = _asm_resolve(assemblyPath); 
      System.Reflection.MethodInfo method = assembly.EntryPoint; 

      return (T)appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name); 
     } 
     else 
     { 

      return (T)appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className); 

     } 
    } 

然後,調用方法在創建的實例,至極在新的AppDomain執行:

void executeMethod(Type objecttype, string methodname, ref object instancedObject, object[] methodparams) 
    { 
     objecttype.InvokeMember(
      methodname, System.Reflection.BindingFlags.InvokeMethod, null, instancedObject, methodparams); 
    } 

您可以使用這樣的:

AppDomain newappdomain = getAppDomainForAssembly(filePath, "Loaded.exe.domain"); 
     object loadedexe_object = getInstanceFromAppDomain(ref newappdomain, 
      filePath); 

     //If you know the method name to call... 
     executeMethod(loadedexe_object.GetType(), "methodname", ref loadedexe_object, null); 

     //or get entry point... 
     executeMethod(loadedexe_object.GetType(), 
      _asm_resolve(filePath).EntryPoint.Name, ref loadedexe_object, null); 

對於第二個問題,你可以使用了NamedPipes,遠程處理,WCF ... 您需要在同一臺機器上實現進程間通信。 看看MSDN文件建立,覆蓋此方案與WCF的代碼示例 http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx

見在CodeProject這個樣本,使用Remoting的 Inter-process communication via Remoting

+0

或一些樣品http://tech.pro/tutorial/633/interprocess - 通訊 - 使用 - 命名管道功能於CSHARP –