2016-11-30 57 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