Как создать exe файл
Одним из современных методов разработки ПО на сегодня считается создание программных компонентов, из которых может быть сформирован 1) программный комплекс любой сложности. Он постепенно заменяет старую методику создания монолитных программ 2) .
Отличным примером среды разработки, поддерживающей указанный современный метод, является BlackBox Component Builder, которая сама построена по данной методике. См. также:
Школьная сборка — полностью русифицированая среда, дополненная набором примеров для начинающих и методическими рекомендациями.Общие принципы создания exe-файлов
Для создания exe-файлов используется команда DevLinker.LinkExe. Например, самое маленькое приложение будет выглядеть так:
Этого уже достаточно для того, чтобы писать программы с использованием Windows API , например:
Если вы хотите задать иконку для exe-файла, измените команду линковки, например, на такую:
Иконка приложения будет взята из файла applogo.ico и включена в состав MoveWin.exe.
При любом варианте линковки требуется перечислить все модули, которые необходимо включить в файл. Это касается не только модулей, решающих конкретную задачу, но и всех импортируемых ими модулей. Модули в списке должны перечисляться в том порядке, в котором они будут загружаться в память. Например, имеется модуль:
Список линкуемых модулей должен выглядеть так: Log TestExe. На самом деле, указанный список модулей неполон, потому как модуль Log сам по себе никаких действий не производит. Для того, чтобы эта программа заработала, нужно добавить модуль реализации журнала, например WinConsole: Kernel+ Log Files Dialog Math Strings WinConsole TestExe. Обратите внимание, как распух список при добавлении одного модуля - пришлось перечислить всё, что импортирует он, и всё, что импортируют остальные модули. Знак »+» после модуля Kernel обязателен, и указывает на модуль ядра. Модуль Kernel используется, если в программе создаются объекты с помощью NEW (то есть практически всегда).
Если используется русифицированная (например, школьная) версия Блэкбокса, то первым в списке нужно указывать модуль National
Для автоматического создания списка необходимых модулей можно воспользоваться подсистемами Alm01Gather, Bbt или ert0dev. Для этого их нужно установить.
Вариант первый
Создание простого исполняемого файла выполняется командой вида
Для нашего примера команда будет выглядеть так:
Параметр dos перед именем файла указывает на необходимость создания консольного приложения. Для обычной программы никаких параметров указывать не надо. Файл будет создан в рабочем каталоге блэкбокса.
Полученная нами программа при запуске не выдаст ничего. Для того, чтобы она заработала, необходимо добавить пару строк:
Это связано с тем, что при исполнении exe, созданного командой DevLinker.LinkExe, выполняются все секции BEGIN всех перечисленных модулей. После того, как последний модуль отработает, вызываются все секции CLOSE, только в обратном порядке.
См. также: Console, модуль ConsoleTest.
Вариант второй
Создание «упакованных» файлов — набор необходимых для работы файлов (произвольного типа) приписывается в конец собранного exe-файла. Во время работы программы эти файлы доступны для чтения при использовании специальной реализации Files — HostPackedFiles.
Обычно придерживаются следующей схемы:
статически линкуется минимальный exe-файл — стандартный blackbox.exe (содержит динамический загрузчик модулей StdLoader) с добавлением HostPackedFiles; кодовые файлы модулей с ресурсами и прочими файлами припаковываются к этому базовому exe; при запуске программы она работает как обычный ББ — модули, ресурсы и пр. загружаются динамически. Разница заключается только в расположении файлов.Припакованные файлы видны «под» файлами из ФС операционной системы: если в ФС и в наборе припакованных файлов содержится файл с одним и тем же именем (и путём), то читается файл из ФС. Эта схема аналогична серверной конфигурации ББ, и при её использовании добавляет «третий уровень» для чтения:
Данная схема может быть полезна при распространении и поддержке ПО, если одним из ключевых требований является минимум файлов в рабочем комплекте:
Базовая версия распространяется в виде одного exe (обычный ББ, к которому припакованы компоненты данного ПО). Промежуточные обновления распространяются в виде архивов с набором изменившихся файлов, которые распаковываются рядом с exe и перекрывают старые версии в припакованном наборе. Это позволяет существенно снизить размеры файлов обновлений для «крупного» ПО. Только при накоплении большого числа обновлений выпускается новая базовая версия в виде одного exe.Команды для создания припакованных файлов описаны в документации модуля DevPacker. Пример использования имеется в следующем разделе.
Полноценный самостоятельный exe-файл на основе BlackBox
В русифицированной школьной версии BlackBox есть подсистема «Тренинг», содержащая диалоговое окно «тренажёра по склонению числительных». Однажды по просьбе А. И. Попкова мною (Александр Ильин) был изготовлен exe-файл, который позволял запустить данный тренажёр без установки BlackBox, т.е. достаточно было получить и запустить файл Training.exe. Тренажёр сотоял из единственного модуля Тренинг\Mod\Chals.odc (фигурирует как «ТренингChals» в параметрах команды LinkExe) и единственной диалоговой формы Тренинг\Rsrc\Chals.odc. Ниже приводится последовательность команд для создания Training.exe (всегда выполняйте все команды, иначе Блэкбокс после перезапуска будет работать неправильно из-за подмены модуля Config, об этом ниже):
Для того, чтобы при запуске Training.exe сразу же отображалось окно тренажёра, перед линковкой выполняется подмена стандартного модуля Config путём компиляции модуля ТренингConfigToPack (см. ниже). После линковки стандартный модуль возвращается на место путём компиляции исходного текста оригинального Config. После этого в созданный Training.exe командой DevPacker.PackThis добавляются два файла ресурсов: диалоговая форма «Тренинг/Rsrc/Chals.odc» и файл меню «Тренинг/Rsrc/MenuToPack.odc» (см. ниже). Последний при упаковке переименовывается в «System/Rsrc/Menus.odc», чтобы заменить собой стандартное меню BlackBox.
Модуль Config, находящийся в файле «Тренинг\Mod\ConfigToPack.odc»:
Файл меню «Тренинг\Rsrc\MenuToPack.odc»:
Автоматизация компоновки
Как видно из предыдущего примера, компоновка простого приложения состоит из 4 щелчков мыши по определённой последовательности коммандеров, а ошибка в этой последовательности может обернуться временной потерей работоспособности BlackBox. К счастью, можно свести этот процесс к одному щелчку мыши, или даже нажатию горячей клавиши. Вашему вниманию предлагается следующий модуль:
можно записать так:
Обратите внимание, что завершающий символ «
» здесь не требуется.
С использованием модуля PrivMake запись команды получилась существенно длиннее, но
её можно поместить в меню и назначить клавиатурную комбинацию;Проиллюстрирую последний пункт, создав процедуру для компоновки Training.exe:
Таким образом, четыре щелчка по коммандерам заменяются на один:
rd.eot & (rd.Pos() <= end). Должно получиться так:
Нетрудно догадаться, что так же можно автоматизировать перекомпиляцию и выгрузку модулей, тестирование, сборку дистрибутивов и т.п.
Самоизоляция это отличное время приступить к тому, что требует много времени и сил. Поэтому я решил заняться тем, чем всегда хотел — написать свой компилятор.
Сейчас он способен собрать Hello World, но в этой статье я хочу рассказать не про парсинг и внутреннее устройство компилятора, а про такую важную часть как побайтовая сборка exe файла.
Начало
Хотите спойлер? Наша программа будет занимать 2048 байт.
Обычно работа с exe файлами заключается в изучении или модификации их структуры. Сами же исполняемые файлы при этом формируют компиляторы, и этот процесс кажется немного магическим для разработчиков.
Для сборки нашей программы нам потребуется любой HEX редактор (лично я использовал HxD).
Для старта возьмем псевдокод:
Первые две строки указывают на функции импортируемые из библиотек WinAPI. Функция MessageBoxA выводит диалоговое окно с нашим текстом, а ExitProcess сообщает системе о завершении программы.
Рассматривать отдельно функцию main нет смысла, так как в ней используются функции, описанные выше.
DOS Header
Для начала нам нужно сформировать корректный DOS Header, это заголовок для DOS программ и влиять на запуск exe под Windows не должен.
Более-менее важные поля я отметил, остальные заполнены нулями.
Самое главное, что этот заголовок содержит поле e_magic означающее, что это исполняемый файл, и e_lfanew — указывающее на смещение PE-заголовка от начала файла (в нашем файле это смещение равно 0x80 = 128 байт).
Отлично, теперь, когда нам известна структура заголовка DOS Header запишем ее в наш файл.
Сначала я использовал левую колонку как на скриншоте для указания смещения внутри файла, но тогда неудобно копировать исходный текст, приходится обрезать каждую строку.
Поэтому для удобства в первой скобке каждого блока указан порядок добавления в файл, а в последней смещение в файле (Offset) по которому должен располагаться данный блок.
Например, первый блок мы вставляем по смещению 0x00000000, и он займет 64 байта (0x40 в 16-ричной системе), следующий блок мы будем вставлять уже по этому смещению 0x00000040 и т.д.
Готово, первые 64 байта записали. Теперь нужно добавить еще 64, это так называемый DOS Stub (Заглушка). Во время запуска из-под DOS, она должна уведомить пользователя что программа не предназначена для работы в этом режиме.
Но в целом, это маленькая программа под DOS которая выводит строку и выходит из программы.
Запишем наш Stub в файл и рассмотрим его детальнее.
А теперь этот же код, но уже в дизассемблированном виде
Это работает так: сначала заглушка выводит строку о том, что программа не может быть запущена, а затем выходит из программы с кодом 1. Что отличается от нормального завершения (Код 0).
Код заглушки может немного отличатся (от компилятора к компилятору) я сравнивал gcc и delphi, но общий смысл одинаковый.
А еще забавно, что строка заглушки заканчивается как \x0D\x0D\x0A$. Скорее всего причина такого поведения в том, что c++ по умолчанию открывает файл в текстовом режиме. В результате символ \x0A заменяется на последовательность \x0D\x0A. В результате получаем 3 байта: 2 байта возврата каретки Carriage Return (0x0D) что бессмысленно, и 1 на перевод строки Line Feed (0x0A). В бинарном режиме записи (std::ios::binary) такой подмены не происходит.
Для проверки корректности записи значений я буду использовать Far с плагином ImpEx:
NT Header
Спустя 128 (0x80) байт мы добрались до NT заголовка (IMAGE_NT_HEADERS64), который содержит в себе и PE заголовок (IMAGE_OPTIONAL_HEADER64). Несмотря на название IMAGE_OPTIONAL_HEADER64 является обязательным, но различным для архитектур x64 и x86.
Разберемся что хранится в этой структуре:
Signature — Указывает на начало структуры PE заголовка
Далее идет заголовок IMAGE_FILE_HEADER общий для архитектур x86 и x64.
Machine — Указывает для какой архитектуры предназначен код в нашем случае для x64
NumberOfSections — Количество секции в файле (О секциях чуть ниже)
TimeDateStamp — Дата создания файла
SizeOfOptionalHeader — Указывает размер следующего заголовка IMAGE_OPTIONAL_HEADER64, ведь он может быть заголовком IMAGE_OPTIONAL_HEADER32.
Characteristics — Здесь мы указываем некоторые атрибуты нашего приложения, например, что оно является исполняемым (EXECUTABLE_IMAGE) и может работать более чем с 2 Гб RAM (LARGE_ADDRESS_AWARE), а также что некоторая информация была удалена (на самом деле даже не была добавлена) в файл (RELOCS_STRIPPED | LINE_NUMS_STRIPPED | LOCAL_SYMS_STRIPPED).
IMAGE_DATA_DIRECTORY — массив записей о каталогах. В теории его можно уменьшить, сэкономив пару байт, но вроде как все описывают все 16 полей даже если они не нужны. А теперь чуть подробнее.
У каждого каталога есть свой номер, который описывает, где хранится его содержимое. Пример:
Export(0) — Содержит ссылку на сегмент который хранит экспортируемые функции. Для нас это было бы актуально если бы мы создавали DLL. Как это примерно должно работать можно посмотреть на примере следующего каталога.
Import(1) — Этот каталог указывает на сегмент с импортируемыми функциями из других DLL. В нашем случае значения VirtualAddress = 0x3000 и Size = 0xB8. Это единственный каталог, который мы опишем.
Resource(2) — Каталог с ресурсами программы (Изображения, Текст, Файлы и т.д.)
Значения других каталогов можно посмотреть в документации.
Теперь, когда мы посмотрели из чего состоит NT-заголовок, запишем и его в файл по аналогии с остальными по адресу 0x80.
В результате получаем вот такой вид IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER64 и IMAGE_DATA_DIRECTORY заголовков:
Далее описываем все секции нашего приложения согласно структуре IMAGE_SECTION_HEADER
Name — имя секции из 8 байт, может быть любымVirtualSize — сколько байт копировать из файла в память
VirtualAddress — адрес секции в памяти выровненный по SectionAlignment
SizeOfRawData — размер сырых данных выровненных по FileAlignment
PointerToRawData — адрес секции в файле выровненный по FileAlignment
Characteristics — Указывает какие данные хранит секция (Код, инициализированные или нет данные, для чтения, для записи, для исполнения и др.)
В нашем случае у нaс будет 3 секции.
Почему Virtual Address (VA) начинается с 1000, а не с нуля я не знаю, но так делают все компиляторы, которые я рассматривал. В результате 1000 + 3 секции * 1000 (SectionAlignment) = 4000 что мы и записали в SizeOfImage. Это полный размер нашей программы в виртуальной памяти. Вероятно, используется для выделения места под программу в памяти.
I — Initialized data, инициализированные данные
U — Uninitialized data, не инициализированные данные
C — Code, содержит исполняемый код
E — Execute, позволяет исполнять код
R — Read, позволяет читать данные из секции
W — Write, позволяет записывать данные в секцию
.text (.code) — хранит в себе исполняемый код (саму программу), атрибуты CE
.rdata (.rodata) — хранит в себе данные только для чтения, например константы, строки и т.п., атрибуты IR
.data — хранит данные которые можно читать и записывать, такие как статические или глобальные переменные. Атрибуты IRW
.bss — хранит не инициализированные данные, такие как статические или глобальные переменные. Кроме того, данная секция обычно имеет нулевой RAW размер и ненулевой VA Size, благодаря чему не занимает места в файле. Атрибуты URW
.idata — секция содержащая в себе импортируемые из других библиотек функции. Атрибуты IR
Важный момент, секции должны следовать друг за другом. При чем как в файле, так и в памяти. По крайней мере когда я менял их порядок произвольно программа переставала запускаться.
Теперь, когда нам известно какие секции будет содержать наша программа запишем их в наш файл. Тут смещение оканчивается на 8 и запись будет начинаться с середины файла.
Следующий адрес для записи будет 00000200 что соответствует полю SizeOfHeaders PE-Заголовка. Если бы мы добавили еще одну секцию, а это плюс 40 байт, то наши заголовки не уложились бы в 512 (0x200) байт и пришлось бы использовать уже 512+40 = 552 байта выровненные по FileAlignment, то есть 1024 (0x400) байта. А все что останется от 0x228 (552) до адреса 0x400 нужно чем-то заполнить, лучше конечно нулями.
Взглянем как выглядит блок секций в Far:
Далее мы запишем в наш файл сами секции, но тут есть один нюанс.
Как вы могли заметить на примере SizeOfHeaders, мы не можем просто записать заголовок и перейти к записи следующего раздела. Так как что бы записать заголовок мы должны знать сколько займут все заголовки вместе. В результате нам нужно либо посчитать заранее сколько понадобиться места, либо записать пустые (нулевые) значения, а после записи всех заголовков вернуться и записать уже их реальный размер.
Поэтому программы компилируются в несколько проходов. Например секция .rdata идет после секции .text, при этом мы не можем узнать виртуальный адрес переменной в .rdata, ведь если секция .text разрастется больше чем на 0x1000 (SectionAlignment) байт, она займет адреса 0x2000 диапазона. И соответственно секция .rdata будет находиться уже не в адресе 0x2000, а в адресе 0x3000. И нам будет необходимо вернуться и пересчитать адреса всех переменных в секции .text которая идет перед .rdata.
Но в данном случае я уже все рассчитал, поэтому будем сразу записывать блоки кода.
Секция .text
Конкретно для этой программы первые 3 строки, ровно, как и 3 последние не обязательны.
Последние 3 даже не будут исполнены, так как выход из программы произойдет еще на второй функции call.
Но скажем так, если бы это была не функция main, а подфункция следовало бы сделать именно так.
А вот первые 3 в данном случае хоть и не обязательны, но желательны. Например, если бы мы использовали не MessageBoxA, а printf то без этих строк получили бы ошибку.
Согласно соглашению о вызовах для 64-разрядных систем MSDN, первые 4 параметра передаются в регистрах RCX, RDX, R8, R9. Если они туда помещаются и не являются, например числом с плавающей точкой. А остальные передаются через стек.
По идее если мы передаем 2 аргумента функции, то должны передать их через регистры и зарезервировать под них два места в стеке, что бы при необходимости функция могла скинуть регистры в стек. Так же мы не должны рассчитывать, что нам вернут эти регистры в исходном состоянии.
Так вот проблема функции printf заключается в том, что, если мы передаем ей всего 1 аргумент, она все равно перезапишет все 4 места в стеке, хотя вроде бы должна перезаписать только одно, по количеству аргументов.
Поэтому если не хотите, чтобы программа себя странно вела, всегда резервируйте как минимум 8 байт * 4 аргумента = 32(0x20) байт, если передаете функции хотя бы 1 аргумент.
Рассмотрим блок кода с вызовами функций
Сначала мы передаем наши аргументы:
rcx = 0
rdx = абсолютный адрес строки в памяти ImageBase + Sections[".rdata"].VirtualAddress + Смещение строки от начала секции, строка читается до нулевого байта
r8 = аналогично предыдущему
r9 = 64(0x40) MB_ICONINFORMATION, значок информации
А далее идет вызов функции MessageBoxA, с которым не все так просто. Дело в том, что компиляторы стараются использовать как можно более короткие команды. Чем меньше размер команды, тем больше таких команд влезет в кэш процессора, соответственно, будет меньше промахов кэша, подзагрузок и выше скорость работы программы. Для более подробной информации по командам и внутренней работе процессора можно обратиться к документации Intel 64 and IA-32 Architectures Software Developer’s Manuals.
Мы могли бы вызвать функцию по полному адресу, но это заняло бы как минимум (1 опкод + 8 адрес = 9 байт), а с относительным адресом команда call занимает всего 6 байт.
Давайте взглянем на эту магию поближе: rip + 0x203E, это ни что иное, как вызов функции по адресу, указанному нашим смещением.
Я подсмотрел немного вперед и узнал адреса нужных нам смещений. Для MessageBoxA это 0x3068, а для ExitProcess это 0x3098.
Пора превратить магию в науку. Каждый раз, когда опкод попадает в процессор, он высчитывает его длину и прибавляет к текущему адресу инструкции (RIP). Поэтому, когда мы используем RIP внутри инструкции, этот адрес указывает на конец текущей инструкции / начало следующей.
Для первого call смещение будет указывать на конец команды call это 002A не забываем что в памяти этот адрес будет по смещению Sections[".text"].VirtualAddress, т.е. 0x1000. Следовательно, RIP для нашего call будет равен 102A. Нужный нам адрес для MessageBoxA находится по адресу 0x3068. Считаем 0x3068 — 0x102A = 0x203E. Для второго адреса все аналогично 0x1000 + 0x0037 = 0x1037, 0x3098 — 0x1037 = 0x2061.
Именно эти смещения мы и видели в командах ассемблера.
Запишем в наш файл секцию .text, дополнив нулями до адреса 0x400:
Хочется отметить что всего лишь 4 строки реального кода содержат весь наш код на ассемблере. А все остальное нули что бы набрать FileAlignment. Последней строкой заполненной нулями будет 0x000003F0, после идет 0x00000400, но это будет уже следующий блок. Итого в файле уже 1024 байта, наша программа весит уже целый Килобайт! Осталось совсем немного и ее можно будет запустить.
Секция .rdata
Это, пожалуй, самая простая секция. Мы просто положим сюда две строки добив нулями до 512 байт.
(6) RAW .rdata section (Offset 0x00000400-0x00000600)Секция .idata
Ну вот осталась последняя секция, которая описывает импортируемые функции из библиотек.
Первое что нас ждет новая структура IMAGE_IMPORT_DESCRIPTOR
OriginalFirstThunk — Адрес указывает на список имен импортируемых функций, он же Import Name Table (INT)Name — Адрес, указывающий на название библиотеки
FirstThunk — Адрес указывает на список адресов импортируемых функций, он же Import Address Table (IAT)
Для начала нам нужно добавить 2 импортируемых библиотеки. Напомним:
(7) RAW IMAGE_IMPORT_DESCRIPTOR (Offset 0x00000600)У нас используется 2 библиотеки, а что бы сказать что мы закончили их перечислять. Последняя структура заполняется нулями.
Теперь добавим имена самих библиотек:
Далее опишем библиотеку user32:
Поле Name первой библиотеки указывает на 0x303C если мы посмотрим чуть выше, то увидим что по адресу 0x063C находится библиотека «user32.dll\0».
Подсказка, вспомните что секция .idata соответствует смещению в файле 0x0600, а в памяти 0x3000. Для первой библиотеки INT равен 3058, значит в файле это будет смещение 0x0658. По этому адресу видим запись 0x3078 и вторую нулевую. Означающую конец списка. 3078 ссылается на 0x0678 это RAW-строка
«00 00 4D 65 73 73 61 67 65 42 6F 78 41 00 00 00»
Первые 2 байта нас не интересуют и равны нулю. А вот дальше идет строка с названием функции, заканчивающаяся нулем. То есть мы можем представить её как "\0\0MessageBoxA\0".
При этом IAT ссылается на аналогичную таблице IAT структуру, но только в нее при запуске программы будут загружены адреса функций. Например, для первой записи 0x3068 в памяти будет значение отличное от значения 0x0668 в файле. Там будет адрес функции MessageBoxA загруженный системой к которому мы и будем обращаться через вызов call в коде программы.
И последний кусочек пазла, библиотека kernel32. И не забываем добить нулями до SectionAlignment.
Проверяем что Far смог корректно определить какие функции мы импортировали:
Отлично! Все нормально определилось, значит теперь наш файл готов к запуску.
Барабанная дробь…
Финал
Поздравляю, мы справились!
Файл занимает 2 Кб = Заголовки 512 байт + 3 секции по 512 байт.
Число 512(0x200) ни что иное, как FileAlignment, который мы указали в заголовке нашей программы.
Дополнительно:
Если хочется вникнуть чуть глубже, можно заменить надпись «Hello World!» на что-нибудь другое, только не забудьте изменить адрес строки в коде программы (секция .text). Адрес в памяти 0x00402000, но в файле будет обратный порядок байт 00 20 40 00.
Или квест чуть сложнее. Добавить в код вызов ещё одного MessageBox. Для этого придется скопировать предыдущий вызов, и пересчитать в нем относительный адрес (0x3068 — RIP).
Заключение
Статья получилась достаточно скомканной, ей бы, конечно, состоять из 3 отдельных частей: Заголовки, Программа, Таблица импорта.
Если кто-то собрал свой exe значит мой труд был не напрасен.
Думаю в скором времени создать ELF файл похожим образом, интересна ли будет такая статья?)
Обычно вы видите EXE-файл при установке нового программного обеспечения или запуске программы на вашем ПК, где используется расширение EXE. Если вы создаете собственное программное обеспечение, вы даже можете создать свой собственный исполняемый файл для запуска, установки или распространения. Если вам интересно узнать больше об исполняемых файлах и о том, как создать исполняемый файл, вот что вам нужно сделать.
Риски исполняемых файлов (EXE)
Когда вы запускаете исполняемый файл, вы даете ему разрешение на выполнение содержащихся в нем инструкций. Так работает любое программное обеспечение, от простых сценариев из нескольких строк до сложного программного обеспечения с миллионами строк кода.
Прежде чем запускать или создавать исполняемый файл, вы должны знать о потенциальных рисках. Исполняемые файлы могут содержать в исходном коде инструкции, которые могут повредить ваш компьютер.
Перед запуском любого исполняемого файла, особенно если он запрашивает административные разрешения в Контроль учетных записей пользователей всплывающее окно, вы должны просканировать файл на наличие вредоносных программ с помощью Windows Security или вашего собственного стороннего антивирусного программного обеспечения, такого как Malwarebytes. Вам также следует устанавливать или запускать программное обеспечение только из источников, которым вы абсолютно доверяете.
Если вы создаете собственное программное обеспечение для запуска, вы должны убедиться, что код не предназначен для доступа к каким-либо важным файлам. Хотя Windows обычно предотвращает несанкционированный доступ к системным файлам с помощью UAC, дважды проверьте свой код перед запуском, чтобы убедиться, что программное обеспечение не может нанести вред вашему ПК.
Открытие исполняемых файлов (EXE) в Windows
Если вы хотите открыть исполняемый файл в Windows, вы можете сделать это несколькими способами. Windows автоматически распознает формат EXE-файла как исполняемый файл, поэтому обычно вы можете открыть его со своего рабочего стола, из проводника Windows, с помощью меню «Пуск» Windows (для установленного программного обеспечения) или с помощью командного окна «Выполнить».
- Чтобы открыть EXE-файлы на рабочем столе или в проводнике Windows, дважды щелкните файл. Это проинструктирует Windows открыть его.
- Список установленного программного обеспечения в меню «Пуск» Windows представляет собой ярлыки EXE-файлов для этого программного обеспечения (например, Chrome.exe для Google Chrome). Нажмите значок меню «Пуск» (или нажмите клавишу Windows на клавиатуре), затем нажмите одну из записей, чтобы запустить программное обеспечение.
- Чтобы использовать командное окно «Выполнить» для запуска EXE-файла, нажмите клавиши Windows + R на клавиатуре. Либо щелкните правой кнопкой мыши значок меню «Пуск» и выберите «Выполнить».
- В поле команды «Выполнить» найдите исполняемый файл, нажав кнопку «Обзор», или введите расположение файла напрямую. Если вы хотите запустить EXE-файл, нажмите ОК.
- Если EXE-файл запрашивает административный доступ, вам необходимо разрешить его запуск во всплывающем окне UAC. Нажмите Да, чтобы разрешить это.
Как создать исполняемый файл в Windows
Если вы хотите создать свои собственные исполняемые файлы в Windows, вы можете, но это не так просто, как переименовать файл и добавить .exe в его конец.
Вам нужно будет закодировать программное обеспечение, которое вы хотите запустить, на выбранном вами языке программирования, а затем скомпилировать его как файл, который можно будет выполнить. Однако большинство пользователей захотят создать более простые исполняемые файлы, такие как файлы установщика для установки программного обеспечения.
EXE-файл, созданный с помощью 7-Zip, на самом деле является файлом архива SFX. Этот архивный файл в формате EXE автоматически извлекает все включенные файлы на ваш компьютер, что делает его идеальным для простого развертывания программного обеспечения.
Если вы хотите поделиться файлами с несколькими пользователями, не беспокоясь о том, что у них установлено правильное программное обеспечение, создание такого файла будет хорошим вариантом.
- Чтобы создать EXE-файл с помощью 7-ZIP, поместите файлы в папку в проводнике Windows. Щелкните папку правой кнопкой мыши, затем нажмите 7Zip> Добавить в архив.
- В поле «Параметры» установите флажок «Включить архив SFX». Вы также захотите установить формат архива на 7z, метод сжатия на LZMA2 и уровень сжатия на нормальный. Нажмите ОК, чтобы создать файл.
Хотя это не настоящий EXE-файл, он выглядит и действует как один, что упрощает создание исполняемого файла, который может распространять программное обеспечение или файлы, созданные вами вместе с другими.
В противном случае, если вы хотите создать «настоящий» исполняемый файл, вам потребуется научиться программировать.
Запуск исполняемых файлов на Mac или Linux
То, как исполняемые файлы работают в Windows, полностью отличается от того, как программы работают на других платформах, таких как Linux или macOS. На этих платформах есть исполняемые файлы, но они не в формате EXE.
В Linux, например, любой файл может быть исполняемым, но для его запуска в качестве программы с использованием chmod требуется специальный флаг разрешений. Например, команда chmod + x file предоставит файлу с именем file разрешение на выполнение.
В macOS есть несколько иной метод запуска программного обеспечения. Если приложение не было установлено из App Store, и оно не от разработчика, которого он знает или которому доверяет, то приложение не будет запущено. Вам нужно будет разрешить это в меню «Системные настройки»> «Безопасность и конфиденциальность».
Однако как система на основе Unix macOS поддерживает команду chmod, что позволяет выполнять больше базовых сценариев с помощью приложения Terminal. Если вы, например, разработали сценарий Python, вы можете использовать команду chmod + x для его запуска.
Вы также можете использовать эмулятор WINE для Linux и macOS для запуска и установки EXE-файлов Windows на этих платформах. Разработанный для эмуляции определенных инструкций и библиотек Windows, использование WINE для запуска EXE-файла будет иметь разный уровень успеха.
Вы можете проверить, насколько популярное программное обеспечение будет работать с WINE, проверив База данных WineHQ.
Запуск исполняемых файлов в Windows 10
Ничто не мешает вам создавать собственное программное обеспечение, особенно если вы объедините его с пакетами установщика Windows, чтобы упростить установку. Однако для большинства пользователей Windows 10 файлы EXE нужно запускать, а не создавать. Пока вы запускаете программное обеспечение только из источников, которым доверяете, исполняемые файлы должны быть относительно безопасными.
Убедитесь, что вы регулярно выполняете сканирование на наличие вредоносных программ, и, если вы действительно не уверены в том, безопасно ли запускать исполняемый файл, вы можете использовать режим песочницы Windows 10 для запуска программного обеспечения в изолированном контейнере, чтобы проверить его. Если EXE опасен, он не повредит вашу основную установку Windows.
Что вы делаете, когда создаете какое-то новое программное обеспечение Windows — от простого средства диагностики о сложной видеоигре для ПК — и вы хотите поделиться этим с миром? Ну, вы можете сжать файлы в один ZIP-файл и распространять его.
Или вы можете быть модным и вместо этого создать установщик EXE.
В этом посте мы рассмотрим три различных метода: самораспаковывающийся пакет, простой установщик, использующий встроенный IExpress, и расширенный установщик, использующий настраиваемую установку Inno.
Быстрый метод: использование 7-Zip
Вы, вероятно, уже используете 7-Zip для извлечения всех видов архивных файлов. извлечь , и вы, вероятно, уже знаете, что 7-Zip может создавать архивные файлы, но знаете ли вы, что вы также можете использовать его для создания EXE-файла, который действует как установщик?
Он называется SFX-архивом («самораспаковывающийся») и работает, сжимая все ваши конечные файлы вместе, а затем встраивая в архив специальный EXE-файл, который знает, как извлечь все. Другими словами, получатель может извлечь архив SFX (который выглядит как сам файл EXE), даже если у него нет подходящего программного обеспечения, что может случиться с такими форматами, как 7Z, RAR, TAR и ZIP.
Как создать свой собственный SFX-архив с 7-Zip:
- Подготовьте все свои файлы и каталоги в пределах одного основного каталога и назовите каталог как хотите.
- Щелкните правой кнопкой мыши каталог и выберите 7-Zip> Добавить в архив …
- В разделе « Параметры» включите « Создать архив SFX» и выберите следующие параметры…
> Формат архива: 7z
> Уровень сжатия: Нормальный
> Метод сжатия: LZMA2
> Размер словаря: 16 МБ
> Размер слова: 32
> Размер блока: 2 ГБ - Нажмите ОК . Выполнено!
Обратите внимание, что SFX-архивы не являются настоящими установочными файлами. Они не помещают извлеченные файлы в назначенный целевой каталог. Они не изменяют реестр Windows. Они не создают журналы установки и не отображаются как «установленное программное обеспечение» в приложении удаления. Это буквально архивные файлы, наряженные в EXE-файлы.
Загрузить — 7-Zip (бесплатно)
Простой метод: использование IExpress
IExpress — это утилита, которая поставляется в комплекте с версиями Windows, начиная с Windows XP и выше. Утилита поставляется с интерфейсным графическим интерфейсом (называемым IExpress Wizard), но вы также можете создавать установочные файлы, используя файлы SED, написанные от руки. Мы рекомендуем мастера.
Как и в 7-Zip выше, этот метод создает самораспаковывающийся архив, но с двумя основными отличиями: во-первых, конечный пользователь будет использовать многостраничный мастер установки, а во-вторых, конечный пользователь может указать целевой каталог, в котором находится инструмент распакует файлы
Как создать свой собственный установщик EXE с помощью IExpress:
Обратите внимание, что у IExpress есть некоторые странности и проблемы. Это не позволяет включать пустые каталоги. Если в вашей установке есть подкаталоги, подкаталоги не будут включены. Если у вас есть несколько файлов с одинаковыми именами, даже в разных каталогах, создание установщика завершится неудачно.
Из-за этих странностей мы рекомендуем использовать метод ниже.
Рекомендуемый метод: использование Inno Setup
Inno Setup — это утилита с открытым исходным кодом. с открытым исходным Это активно развивается с 1997 года. Он был создан частично в ответ на актуальный неподходящий InstallShield Express. С тех пор он стал создателем инсталляторов для тех, кто не хочет исследовать собственные опции.
Его самая большая ничья — это гибкость. Inno Setup использует файлы сценариев с расширением ISS («Inno Setup Script») для настройки различных аспектов программы установки: какие файлы включены, где происходит установка, создавать ли ярлыки и т. Д. Файлы ISS используют форматирование, подобное формату файлов INI. и может быть создан с помощью мастера установки Inno.
Как создать свой собственный установщик с помощью Inno Setup:
- Запустите приложение Inno Setup Compiler.
- В окне приветствия выберите « Создать новый файл сценария с помощью мастера сценариев» .
- Введите имя приложения и версию приложения. При желании вы также можете указать сведения об издателе приложения и веб-сайте приложения. Нажмите Далее .
- Выберите базовую папку Destination , которая по умолчанию имеет значение Program Files. Введите имя папки приложения , которая является именем основного каталога, куда будут идти ваши установочные файлы. Нажмите Далее .
- В качестве основного исполняемого файла приложения найдите и выберите основной EXE-файл, который запустит ваше приложение. Если вы не устанавливаете приложение, включите. У приложения нет основного исполняемого файла . Затем добавьте файлы и папки в вашу установку с помощью кнопок Добавить файлы… и Добавить папки… . Нажмите Далее .
- На странице «Ярлыки приложений» оставьте значения по умолчанию или измените их в соответствии со своими предпочтениями. Они все говорят сами за себя. Нажмите Далее .
- На странице документации приложения вы можете указать до трех файлов TXT, которые будут отображаться в процессе установки конечного пользователя. Обычно это LICENSE.TXT, INSTALL.TXT и README.TXT, но они могут быть любыми. Нажмите Далее .
- На странице «Настройка языков» сохраняйте английский, но не стесняйтесь добавлять столько языков, сколько пожелаете. Нажмите Далее .
- На странице настроек компилятора вы можете настроить EXE-файл установщика:
> Выходная папка пользовательского компилятора, в которой будет находиться полученный EXE-файл установщика.
> Имя выходного базового файла компилятора — это имя файла EXE. Значением по умолчанию является setup.exe .
> Файл значков пользовательской настройки — это значок, который будет использоваться для установочного EXE-файла. Это должен быть файл ICO, который можно загрузить или преобразовать из PNG. - Установочный пароль защитит неавторизованных пользователей от использования вашего установщика. Оставьте это поле пустым, чтобы отключить эту функцию.
- Нажмите Готово . Когда будет предложено скомпилировать новый скрипт, нажмите « Да» . Когда будет предложено сохранить сценарий, выберите « Нет», если это файл однократной установки, или « Да», если вы планируете изменить или обновить его позже. Выполнено!
Загрузить — Inno Setup (бесплатно)
Какой метод подходит вам?
Если ваша программа чрезвычайно проста или вы собираетесь распространять ее среди ограниченного числа людей, используйте метод 7-Zip. Это просто, быстро и практически не требует технических знаний.
Если ваше программное обеспечение несколько простое и вы хотите представить конечного пользователя настоящий мастер установки, воспользуйтесь методом IExpress.
Если у вас сложное программное обеспечение и у вас за плечами большой технический опыт, воспользуйтесь методом Inno Setup. Он самый гибкий, самый мощный и не страдает от проблем, которые мешают IExpress.
Какой метод вы будете использовать? Есть ли другие методы, которые мы пропустили? Дайте нам знать в комментариях ниже!
Или вы можете пофантазировать и вместо этого создать установщик EXE.
В этом посте мы рассмотрим три различных способа создания EXE: самораспаковывающийся пакет, простой установщик с использованием встроенного IExpress и расширенный установщик с помощью настраиваемой Inno Setup.
1. Создайте быстрый EXE-файл с помощью 7-Zip.
Вероятно, вы уже используете 7-Zip для извлечения всех видов архивных файлов и знаете, что 7-Zip может создавать архивные файлы, но знаете ли вы, что вы также можете использовать его для создания EXE-файла, который действует как установщик?
Он называется SFX-архивом (самораспаковывающимся) и работает, сжимая все ваши конечные файлы вместе, а затем встраивая в архив специальный EXE-файл, который знает, как все распаковать.
Другими словами, получатель может извлечь SFX-архив (который выглядит как EXE-файл), даже если у него нет нужного программного обеспечения, что может случиться с такими форматами, как 7Z, RAR, TAR и ZIP.
Вот как создать SFX-архив с помощью 7-Zip:
Обратите внимание, что SFX-архивы не являются настоящими файлами установщика. Они не помещают извлеченные файлы в назначенный целевой каталог. Они не изменяют реестр Windows. Кроме того, они не создают журналы установки и не отображаются как установленное программное обеспечение в приложении «Удалить». Это буквально архивные файлы, оформленные как EXE-файлы.
2. Как использовать IExpress для простого создания EXE
Как и 7-Zip, описанный выше, этот метод создает самораспаковывающийся архив, но с двумя основными отличиями: во-первых, конечный пользователь будет проходить через многостраничный мастер установки, а во-вторых, конечный пользователь может указать целевой каталог для куда инструмент извлечет файлы.
И вот как вы создаете свой установщик EXE с помощью IExpress:
Ваш пакет будет создан через несколько минут. Обратите внимание, что у IExpress есть некоторые особенности и проблемы:
Из-за этих странностей мы рекомендуем вместо этого использовать метод, описанный ниже.
Связанный: Что такое GUI (графический интерфейс пользователя)?
3. Лучший способ создать EXE: используйте Inno Setup.
Теперь выполните следующие действия, указанные ниже:
На странице настроек компилятора вы можете настроить EXE-файл установщика:
После настройки параметров нажмите Готово. Когда будет предложено скомпилировать новый сценарий, нажмите Да. Когда будет предложено сохранить сценарий, выберите Нет, если это одноразовый файл установщика. Выберите Да, если вы планируете изменить или обновить его позже.
Подождите, пока процесс завершится, и вуаля, у вас будет с собой исполняемый файл.
Какой метод лучше всего подходит для создания установщика EXE?
Если у вас базовое программное обеспечение или вы собираетесь распространять его среди ограниченного числа людей, используйте метод 7-Zip. Это просто, быстро и практически не требует технических знаний.
Если ваше программное обеспечение несколько простое, и вы хотите предоставить конечным пользователям настоящий мастер установки, воспользуйтесь методом IExpress. Наконец, выберите приложение Inno, если у вас сложное программное обеспечение и вы знаете, что делаете.
Читайте также: