2016-11-30 51 views
1

我試圖建立一個自動檢查,如果幾個32位的WPF應用程序可以打開沒有問題。在已經運行的c#過程中執行c#WPF應用程序

我不想使用Process.Start,因爲我無法確定每個程序是否會在發生問題時返回非零退出代碼(並且我將不得不關閉那些帶有進一步代碼的WPF應用程序)。

改爲我的計劃:在運行時加載程序集並觸發它們的啓動方法(連接到一些異常事件接收器以獲取有關問題的信息並關閉稍後打開的窗口)。

這是我走到這一步:

public void Check(string executablePath) 
    { 
    try 
    { 
     Assembly assembly; 
     try 
     { 
      assembly = Assembly.LoadFrom(executablePath); 
     } 
     catch (BadImageFormatException e) 
     { 
      Logger.InfoFormat("Not a 32 bit .NET application : {0}", Path.GetFileName(executablePath)); 
      return; 
     }   
     assembly.EntryPoint.Invoke(null, new object[] { }); 

     Logger.InfoFormat("OK : {0}", Path.GetFileName(executablePath)); 
    } 
    catch (Exception e) 
    { 
     Logger.Error(e); 
    } 
} 

我的問題:,只要我調用入口點方法,從裏面的應用程序中的錯誤畫面呈現在告訴我一個IOExeption發生(這是無法找到啓動畫面的資源)。

我是否必須預先加載其他程序集內的資源才能使其工作?

更新

隨着德克的回答我能夠創建一個新的應用領域和委託的入口點的調用由該域中創建一個MarshalByRefObject的後裔。

我也能Assembly.EntryAssembly感謝的值更改此網站(目前不在線)

http://webcache.googleusercontent.com/search?q=cache:6POIVfrxbAcJ:dejanstojanovic.net/aspnet/2015/january/set-entry-assembly-in-unit-testing-methods/+&cd=8&hl=en&ct=clnk&gl=de

代碼片段做的工作:

private void ModifyEntryAssembly(Assembly assembly) 
    { 
    AppDomainManager manager = new AppDomainManager(); 
    FieldInfo entryAssemblyfield = manager.GetType().GetField("m_entryAssembly", BindingFlags.Instance | BindingFlags.NonPublic); 
    if (entryAssemblyfield == null) 
    { 
     throw new Exception("Could not retrieve entryAssemblyField."); 
    } 
    entryAssemblyfield.SetValue(manager, assembly); 

    AppDomain domain = AppDomain.CurrentDomain; 
    FieldInfo domainManagerField = domain.GetType().GetField("_domainManager", BindingFlags.Instance | BindingFlags.NonPublic); 
    if (domainManagerField == null) 
    { 
     throw new Exception("Could not retrieve domainManagerField."); 
    } 
    domainManagerField.SetValue(domain, manager); 
    } 

現在,即時通訊從被調用的可執行文件獲取啓動畫面和登錄對話框,現在更進一步!

還有一個EEntryPointException拋出的問題,但這是另一個問題的另一個問題......謝謝!

回答

2

WPF的啓動畫面中搜索在進入裝配 ,它在你的情況,你是主要的可執行文件,而不是您要檢查可執行。

您可以在自己的應用程序域,那麼這將讓自己的入門組裝開始測試的應用程序解決此問題:

class Test 
{ 
    public static void Main() 
    { 
     var otherDomain = AppDomain.CreateDomain("otherDomain"); 

     otherDomain.ExecuteAssembly("MyExecutable.exe"); 
    } 
} 

但是,你應該知道,你的做法是要給你誤報,因爲被測試的應用程序在另一個環境中運行。例如,調用Assembly.GetExecutingAssembly()將在測試中的應用程序中給出不同的結果。而你的方法將無法同時測試32位和64位應用程序。

你可以從reference source看到,SplashScreen構造函數的重載之下調用Assembly.GetEntryAssembly()

public SplashScreen(string resourceName) 
    : this(Assembly.GetEntryAssembly(), resourceName) 
{ 
} 

+0

謝謝!我能夠解決入口組件的問題,查看我的問題更新。 :-) – Udontknow