我试图建立一个自动检查,如果几个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感谢的值更改此网站(目前不在线)
代码片段做的工作:
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抛出的问题,但这是另一个问题的另一个问题......谢谢!
谢谢!我能够解决入口组件的问题,查看我的问题更新。 :-) – Udontknow