2009-02-27 3 views
1

У меня есть приложение для пользовательского интерфейса, которое находится в панели задач пользователя, написанной на C#. EXE для инструмента проверяется в нашей системе управления версиями на ряде проектов, которые используют его, поэтому мы можем обновить версию, с которой они работают, путем проверки обновленного EXE.Как запустить программу из памяти на C#?

Проблема заключается в том, что, когда пользователи получают последнюю версию exe, программа часто работает, а синхронизация выходит из строя на их машине. Я хочу исправить это, поэтому программа не блокирует exe и любые зависимые DLL, когда они запускаются, поэтому они могут синхронизироваться без необходимости выключать программу.

В настоящее время у меня есть программа, которая принимает исполняемый файл в качестве параметра и запустит его из памяти, предварительно прочитав содержимое сборки в памяти. К сожалению, это полностью терпит неудачу, когда дело доходит до DLL, что требуется программе.

код я прямо сейчас выглядит примерно так:

public class ExecuteFromMemory 
{ 
    public static void Main(string[] args) 
    { 
     //Figure out the name of the EXE to launch and the arguments to forward to it 
     string fileName = args[0]; 
     string[] realArgs = new string[args.Length - 1]; 
     Array.Copy(args, 1, realArgs, 0, args.Length - 1); 

     //Read the assembly from the disk 
     byte[] binary = File.ReadAllBytes(fileName); 

     //Execute the loaded assembly using reflection 
     Assembly memoryAssembly = null; 
     try 
     { 
      memoryAssembly = Assembly.Load(binary); 
     } 
     catch (Exception ex) 
     { 
      //Print error message and exit 
     } 

     MethodInfo method = memoryAssembly.EntryPoint; 
     if (method != null && method.IsStatic) 
     { 
      try 
      { 
       method.Invoke(null, new object[] { realArgs }); 
      } 
      catch(Exception ex) 
      { 
       //Print error message and exit 
      } 
     } 
     else 
     { 
      //Print error message and exit 
     } 
    } 
} 

Мой вопрос, я делаю что-то совершенно глупое? Есть ли лучший способ справиться с этим? Если нет, что мне делать, чтобы поддерживать обработку внешних зависимостей?

Например, приведенный выше код не может загрузить любые зависимые файлы, если вы пытаетесь запустить «Foo.exe», который использует функции из «Bar.dll», «Foo.exe» будет переписываться, но «Bar». dll 'по-прежнему заблокирован и не может быть перезаписан.

Я попытался получить список ссылочных ассемблеров из метода GetReferencedAssemblies() на загруженном assmebly, но это, похоже, не дает никаких указаний, где сборки должны быть загружены из ... Нужно ли искать для них самого? Если да, то каков наилучший способ сделать это?

Похоже, что раньше люди сталкивались с этим, и я не хочу изобретать колесо.

- Обновление: EXE проверяется, потому что это то, как мы распространяем наши собственные инструменты для команд, которые их используют. Это не оптимально для этого варианта использования, но у меня нет возможности изменить эту политику.

+0

И почему вы хотите выполнить из памяти? Это хороший способ заставить вашу программу выглядеть живым вирусом. – Migol

ответ

1

Нужно ли продолжать работать при обновлении?

Обычно для обновления программы, которая выполняется, вы копируете любой из файлов, которые должны быть заменены во временную папку. Затем выключите старый экземпляр, удалите его и переместите новые файлы в нужные места, а затем запустите его.

Это позволяет минимальное время простоя приложения, так как самая длинная часть обычно является копией, и перемещение файла происходит очень быстро, если временная папка находится на одном логическом диске.

4

Отказ от ответственности: Я не использую Windows, хотя я знаком со своим странным способом блокировки вещей.

Чтобы обновить приложение во время его работы, вам, вероятно, потребуется два процесса: сам исполняемый файл и приложение-помощник обновления, которое завершит процесс обновления. Предположим, что ваше приложение - ProcessA.exe, а ваш помощник обновления - Updater.exe. Ваша основная программа загрузит новую копию исполняемого файла, сохранив его со случайным именем. Затем вы запускаете программу обновления, которая следит за завершением текущего процесса. Когда ваш процесс завершается, он отображает быстрое окно, показывающее статус обновления, перемещение нового исполняемого файла в место старого и перезапуск этой программы.

Было бы более элегантно уметь эмулировать семантику файловой системы POSIX и удалять текущий образ диска процесса и заменять его новым файлом, но я не знаю, возможно ли это на Окна. В системе POSIX вы можете удалить исполняемый файл, и он фактически не будет удален до тех пор, пока все оставшиеся дескрипторы файлов не будут закрыты, хотя вы можете повторно использовать имя файла.

Возможно, вы захотите проверить статью, написанную в CodeProject, что talks about this. Он также имеет follow-up article.

Удачи вам!

0

Хотя ответ Майкла является одним из способов сделать это, есть инструменты, которые явно предназначены для управления установленными на рабочем столе.

Что вы делаете с exe, проверяемым в источнике, не является нормальным. Если у вас есть контроллер домена Windows, вы можете использовать групповую политику, чтобы нажимать программы на клиента. Кроме того, вы можете использовать что-то вроде Altiris для его обработки.

Если вы должны продолжить свой путь, у вас есть два варианта. Один, используя приложение helper/loader, которое выполняет проверку версии при запуске. Это похоже на то, как работает firefox.

Второй способ состоит в том, чтобы создать вспомогательную службу, которая сидит в памяти и опросает все так часто для обновлений. Так работают Google Chrome, Adobe и т. Д.