Я пытаюсь создать автоматическую проверку, если несколько 32-битных приложений WPF могут быть открыты без проблем.Выполнение приложения WPF C# внутри уже запущенного процесса C#
Я не хочу использовать 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);
}
}
Моя проблема: Как только я вызвать метод EntryPoint, экран ошибки из приложения внутри представлено говорил мне по электронной IOExeption произошло (это было не удалось найти ресурс для экрана заставки).
Должен ли я предварительно загружать эти ресурсы внутри других сборок, чтобы заставить их работать?
Update
С Dirks ответом я был в состоянии создать новый домен приложения и делегирование вызова точки входа потомка 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