2016-11-30 15 views
1

Я пытаюсь создать автоматическую проверку, если несколько 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 благодаря этому сайту (в настоящее время не в сети)

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