Installer

== Этапы инсталляции ==
Запомните одно важное правило: инсталлировать программу можно с человеческих носителей (винчестеры, компакт-диски, ZIP-диски) и с дискет :) Если вы собираетесь написать инсталляцию с дискет, которая явно не поместиться на одну дискету, то у вас есть шанс хорошо провести время :)
Как вы знаете, Windows сбрасывает ненужную ей в данный момент информацию на диск. Это правильно, но это касается данных. Программы никогда на диск не сбрасываются, поскольку в Windows сегмент кода программы не может быть изменён. Когда Windows нужна память и ей под руку подворачивается ваша программа, она её просто выкидывает - и всё. Когда ваша программа снова становиться нужна, Windows снова загружает её из выполняемого файла.
Эта в высшей степени корректная техника перестаёт работать при инсталляции с дискет. Ваша программа, например, копирует четвёртую дискету и тут выясняется, что у неё (у программы) пропал кусок кода. Какие проблемы? - Windows пытается прочитать файл a:\setup.exe и естественно его не находит (на четвёртой-то дискете? откуда?).
Только не паникуйте! Эта проблема давно решена, иначе вы не могли бы установить на свой компьютер ни одной программы! Всё очень просто - программа инсталляции копирует себя и все необходимые файлы во временный каталог на жёсткий диск и перезапускает себя с жёсткого диска. Это и есть первый этап инсталляции. В зарубежных программах он обычно называется "Prepare to install". Ещё раз обратите внимание на то, что совсем не обязательно выполнять этот этап, если вы инсталлируетесь не с дискет, или если ваша инсталляция умещается на одну дискету.
На втором этапе программа инсталляции обычно показывает пользователю несколько страшных предупреждений; что-то типа "если вы не заплатите за эту программу, то сидеть вам в тюрьме три пожизненных срока". Я слышал, что некоторые пользователи со слабым сердцем даже умирали за компьютером от таких угроз :)
Реализация этого этапа до идиотизма тривиальна, поэтому мы и не будем на нём останавливаться подробно.
Следующий этап - третий. Здесь программа установки дотошно выспрашивает у пользователя кучу всяких важных данных: имя пользователя и его организацию, тип установки, куда будем ставить, как будет называться группа программ и так далее. На этом этапе нам встретятся некоторые технические трудности, но их несложно обойти.
Четвёртый этап - копирование. Конечно, это не очень сложно, но некоторые проблемы у нас всё-таки возникнут. Во-первых, надо проверить наличие свободного места на целевом диске. Во-вторых, надо удостовериться, что у нас есть доступ к нужному каталогу. В-третьих, надо проверять, нет ли уже такого файла...
Вы ещё не передумали писать программу инсталляции?
Следующий, пятый, этап - настройка системного реестра (registry). Достаточно тривиальная процедура, правда, при инсталляции большого продукта, записывать придётся очень много.
Предпоследний, шестой, этап, заключается в создании группы программ в меню "Пуск". Или, возможно, вы захотите вынести ярлык на рабочий стол.
Наконец, финальная часть включает демонстрацию нескольких файлов (например, readme), затем онлайновую регистрацию (подробно на ней я останавливаться не буду) и последнее сообщение "Инсталляция успешно завершена".
Теперь мы можем перейти к подробному рассмотрению этапов. Сейчас вы узнаете, как это делается :)
== Копирование программы во временный каталог ==
program Setup;
uses
 Windows,
 SysUtils;
const
 ReRunParameter = '/install_from_temp_directory';
var
 TempPath: array [0..MAX_PATH] of Char;
 SrcPath: String;
begin
 if ParamStr(1) = ReRunParameter then
 SrcPath := ParamStr(2)
 else
 if GetDriveType(PChar(ParamStr(0)[1] + ':\')) = DRIVE_REMOVABLE then
 begin
 // Если программа была запущена без ключа и с дискеты, то
 // копируем её во временный каталог и перезапускаем
 // Текущее приложение завершаем.
 GetTempPath(MAX_PATH, TempPath);
 // Добавляем к пути временного каталога символ '\', если его там нет
 if (StrLen(TempPath) > 0) and (TempPath[StrLen(TempPath)] <> '\') then
 StrCat(TempPath, '\');
 // Копируем файл через вызов функции CopyFile из WinAPI
 CopyFile(PChar(ParamStr(0)), PChar(String(TempPath) + ExtractFileName(ParamStr(0))), False);
 // Запускаем файл с двумя параметрами
 WinExec(PChar(String(TempPath) + ExtractFileName(ParamStr(0)) + ' ' +
 ReRunParameter + ' ' + ExtractFilePath(ParamStr(0))), CmdShow);
 Exit;
 end
 else
 SrcPath := ExtractFilePath(ParamStr(0));
 // Здесь начинается программа инсталляции
 // Переменная SrcPath показывает нам, откуда надо копировать файлы
end.
Есть две грабли, на которые можно наступить в приведённом примере. Первые лежат в вызове функции GetTempPath. Если у вас нет переменных окружения TMP и TEMP, то временным каталогом станет текущий каталог программы, то есть, фактически, ваша дискета.
Вы можете проверять, не находится ли временный каталог на сменном диске (с помощью вызова GetDriveType), и, если находиться, считать временным каталогом C:\TEMP (если его нет - создайте самостоятельно).
Вторые грабли заключаются в том, что после завершения инсталляции программу из временного каталога желательно удалить, но сделать этого вы не сможете, поскольку программа в этот момент выполняется. Вспомните, что в Windows 95 и Windows NT выполняющуюся программу удалять нельзя
В общем случае, решения этой проблемы я не знаю. Собственно, поскольку файл останется во временном каталоге, он будет одним из первых кандидатов на удаление (если пользователь хоть когда-нибудь чистит свой временный каталог :) Тем не менее, есть один хитрый способ удаления этого файла, о котором я расскажу ниже, в параграфе о деинсталляции.
Примечание: Если для вас важен размер вашей инсталляции, вы можете взять только тот кусочек, который приведён выше, и сделать из него отдельную программу (которая будет очень небольшого объёма). Саму программу инсталляции вы предварительно сжимаете, а перед запуском распаковываете её во временный каталог (а не копируете, как это сделано здесь). Обратите внимание, что в этом случае программа должна распаковываться в любом случае, а не только если она запущена с дискеты.
== Запугивание пользователя законами об авторских правах ==
Да, есть и такой этап. Если вам всё равно придётся вывести небольшое окно и поставить пользователя в известность о том, что вы не отвечаете за все неприятности, которые могут с ним произойти во время использования вашей программы.
Как это делается? Если вы не знаете, как сделать диалоговое окно, то, по моему, вам ещё рано писать инсталляции. Если знаете, то выведите окно и поместите в нём нужный текст.
== Как получить важные системные данные ==
На четвёртом этапе нам потребуются некоторые системные данные: имя пользователя и организация, путь, куда потребуется инсталлировать программу и некоторые другие. Сейчас мы разберёмся, как и откуда эти данные можно получить.
=== Имя пользователя и организация ===
Во время инсталляции, программы иногда запрашивают имя пользователя и его организацию. Возможно, для работы вашей программы эти данные не понадобятся, но если они вам нужны, вы должны их запросить. Как правило, программа инсталляции берёт эти данные из Windows (поскольку при установке Windows пользователь их уже вводил) и просит всего лишь изменить их, если это необходимо. Наш вопрос звучит так: где Windows хранит имя пользователя и организацию? Я, правду сказать, не знаю. Но, пробежавшись по реестру, я обнаружил всего лишь два подходящих места, содержащих эту информацию.
 HKEY_LOCAL_MACHINE\Software\Microsoft NT\Windows\CurrentVersion\
 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\
 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\
 
 RegisteredOwner = 'Имя'
 RegisteredOrganization = 'Организация'
В доступной мне версии Windows 95, эти значения хранятся в ветке HKEY_LOCAL_MACHINE, а в Windows NT - HKEY_CURRENT_USER (в подветках Windows или Windows NT). Поскольку в этом вопросе нет ясности :) я предлагаю проверять обе ветки. Версию операционной системы можно узнать с помощью функции GetVersionEx.
=== Куда копировать программу ===
Можно сформулировать наш вопрос и по другому: где находиться каталог Program Files? Некоторые инсталляции считают, что это C:\Program Files. В действительности, конечно, он может находиться на другом диске, поэтому мы попробуем поискать его по другому... в реестре.
 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ ProgramFilesDir = 'D:\Program Files'
Можно воспользоваться функцией SHGetSpecialFolderLocation (это даже более корректно с точки зрения Microsoft). Пример использования этой функции вы обнаружите несколькими файлами позже. Для изменения каталога вы можете вызывать функции SelectDirectory или SHBrowseForFolder. Можно также создать собственное окно диалога "Выбор каталога" с помощью компонента DirectoryListBox. Подробнее о выборе каталога мы поговорим позднее, когда будем рассматривать тонкости процесса инсталляции.
=== Сколько осталось свободного места на диске ===
Программа инсталляции перед копированием файлов обязана проверить, сколько на целевом диске осталось свободного дискового пространства. Это делается при помощью функции GetDiskFreeSpace (из модуля Windows) или функции DiskFree (из модуля SysUtils). Вторая функция - это надстройка Delphi над Win API (в смысле, она вызывает GetDiskFreeSpace), но у неё значительно меньше параметров.
== Группы программ ==
Обычно программа инсталляции создаёт для новой программы новую группу. Как правило, когда вы вводите название группы, рядом присутствует список, в котором перечислены все существующие группы. Получить такой список можно двумя способами. Один из них - работа с DDE-сервером, который называется Program Manager. Этот способ мы подробно рассмотрим чуть позже. Второй способ не очень сложен и
основан на том факте, что всё меню "Программы" находиться в одном из каталогов вашего диска. Все подменю являются на самом деле подкаталогами, а пункты - обычными ссылками (файлами с расширением .lnk). Путь к папке, содержащей меню "Программы", вы можете найти в реестре:
 HKEY_CURRENT_USER\Software\Microsoft\Windows\ CurrentVersion\Explorer\Shell Folders\Programs = 'D:\WINNT\Profiles\mark\Главное меню\Программы'
Не очень сложно прочитать содержимое этого каталога с помощью функций FindFirst/FindNext. Ниже мы и об этом поговорим подробнее, поскольку чтение содержимого каталогов потребуется нам при написании универсальной процедуры копирования файлов.
Author: Неизвестен
Source: www.delphi.agava.ru
Source: http://blackman.wp-club.net/
ID: 04538
Category:Разработка приложений