• Программинг

Нужны источники бесперебойного питания?

Источники бесперебойного питания от дизельстор

Запуск исполняемого файла из памяти. Часть 1 (из 3-х)

Приветствую вас, друзья! Сегодня я расскажу как запустить исполняемый файл (exe) не с жесткого диска, а из памяти. Для чего это может понадобиться – конкретно непонятно. Но иметь ввиду, что так можно сделать, нужно. Что нам необходимо для работы: две программы написанные на C#. Одна программа служит лаунчером, а вторая запускаться этим лаунчером из памяти.

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

Теперь нам неоходимо приложение-лаунчер. Его задача – побайтно считать файл в память, определить точку входа и записать его.

Создайте еще один проект. Первое, что мы должны сделать – отказаться от файла Program.cs и метода Main, который в нем описан. Т.е. нам необходимо описать новую точку входа и назначить ее. Создайте новый файл StartUpApplicationю.cs со следующим содержимым:

1 class StartUpApplication
2 {
3     public static void Main()
4     {
5         var frm = new frmMain();
6         if (frm.ShowDialog() == DialogResult.OK)
7         {
8             //определяем путь к файлу на диске
9             //каким образом выбираете, не имеет значения. Можно передать и в командной строке
10             string pathToFile = frm.lstMain.SelectedItem.ToString();
11             //создаем поток для чтения
12             var fs = new FileStream(pathToFile, FileMode.Open);
13             //создаем побитовую читалку
14             var br = new BinaryReader(fs);
15             //bin содержит побайтово весь exe-файл
16             byte[] bin = br.ReadBytes((int)(fs.Length));
17             //закрываем поток
18             fs.Close();
19             //закрываем читалку
20             br.Close();
21  
22             //загружаем байты в сборку
23             Assembly a = Assembly.Load(bin);
24             //ищем точку входа в приложение
25             MethodInfo method = a.EntryPoint;
26             //если найдена точка входа
27             if (method != null)
28             {
29                 //создаем экземпляр главной формы
30                 object o = a.CreateInstance(method.Name);
31                 //запускаем приложение через точку входа
32                 method.Invoke(o, null);
33             }
34         }
35     }
36 }

Как видите, здесь описан запуск главной формы приложения. Его нельзя было описать стандартным способом, т.к. при вызове method.Invoke(o, null) будет вываливаться ошибка. Это связано с тем, что Visual Studio по-умолчанию добавляет строку Application.SetCompatibleTextRenderingDefault для использования новых библиотек GDI+, которая должна вызваться перед созданием IWin32Window объектов.

Когда все будет готово к компиляции, заходим в свойство проекта и точкой входа выбираем наш новый класс StartUpApplication.

Компилируйте лаунчер. Рядом с созданным запускаемым файлом положите файл с первого проекта. Запустите лаунчер и выберите файл для запуска.

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