Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

INSTALL'им программы по списку

Автор: Панков Константин
17 октября 2005 года

Предисловие

Просмотрев комментарии к своей прошлой статье о создании оболочки для диска, я обратил внимание на слова Abigor'а, процитирую: "Вот если бы ты описал, для широкого круга, возможность создания списка программ на установку и запуском их в соответствии с очередностью в списке, это было бы уже другое дело." Так как подробностей о том, какая же она все-таки должна быть здесь немного, то пришлось написать что-то похожее, но идея я думаю была полностью реализована.

Постановка задачи. Подготовка

Писать будем на Delphi. Исходя из идеи, мы должны создать список программ, которые будут видны в нашей программе, и предоставить возможность выбора(какие программы устанавливать), после чего начать устанавливать их по очереди, не отвлекаясь на поиск setup'ного файла в папках. Список программ будет создан заранее и ручками. Хранить названия программ, путь доступа к ним, относительно нашего exe'шника, и краткое описание, будем в ini файле. Структура ini файла:

[Название программы]
Path=путь к программе
Text=краткое описание

Например:

[winamp.exe]
Path=soft\winamp.exe
Text=плейер

К тому же наша программа будет сохранять введенные пользователем данные, в случае перезагрузки компьютера (что часто бывает после установки драйверов), и запускать после неё для продолжения операций. Для хранения настроек будем использовать спецкаталог для временных файлов. На этом, пожалуй, подготовительный этап закончен.

Реализация

Нам естественно понадобится форма, назовем её installform. Также бросить на неё компоненты: ChtckListBox, 4 Button'a , Memo ( по желанию добавьте, что-нибудь что будет пояснять что для чего). Присвоим имена в том же порядке, в котором положили на форму компоненты: filelist, startbutton, closebutton, allbutton, nonebutton, textlist. После старта программы сразу должны отображаться доступные программы, для этого пишем следующее:

procedure TInstallForm.FormCreate(Sender: TObject);
var s:string;
    f:textfile;
    i:integer;
    res:word;
begin
// определяем местоположение папки Temp
temppath := StrAlloc(255);
res:= gettemppath(255,temppath);
// ассоциируем переменную inifile типа TIniFile с нашим ini файлом
INIFile:=TIniFile.Create(extractfilepath(application.ExeName)+'installlist.ini');
// создаем tstr:TStringList для хранения названия программ
tstr:=TStringList.Create;
// считываем названия прог в tstr
inifile.ReadSections(tstr);
// отображаем в filelist'е
filelist.Items.AddStrings(tstr);
// проверяем были ли до этого сохранены какие-нибудь данные (в случае
//перезагрузки компа или его отключения до окончания операции установки)
if fileexists(temppath+'\installlist.txt')=true then
    begin
      assignfile(f,temppath+'\installlist.txt');
      reset(f);
      readln(f,s);
      while not eof(f) do
        begin
          readln(f,s);
          for i:=0 to filelist.count-1 do
            if filelist.Items.Strings[i]=s then
               filelist.Checked[i]:=true;
        end;
      closefile(f);
    end;

end;

Как видно, данные о предшествующей загрузке будем хранить в txt файле. Если файл существует, то применяем соответствующие настройки. Теперь рассмотрим случай, когда понадобится сбросить выбор всех программ или же наоборот поставить в очередь сразу все проги. Вот для этого мы будем использовать allbutton и nonebutton: при нажатии на первую будут устанавливаться флажки, а на вторую сниматься. Пишем этот код:

procedure TInstallForm.AllButtonClick(Sender: TObject);
var i:integer;
begin
for i:=0 to filelist.Count-1 do
 filelist.Checked[i]:=true;
end;

procedure TInstallForm.NoneButtonClick(Sender: TObject);
var i:integer;
begin
for i:=0 to filelist.Count-1 do
 filelist.Checked[i]:=false;
end;

Несложно, правда. Теперь займемся отображением описания каждой программы. Для этого код вот этот:

procedure TInstallForm.FileListClick(Sender: TObject);
var def:string;
begin
textlist.Clear;
textlist.LineS.add(
   inifile.ReadString(filelist.Items.strings[filelist.itemindex],'Text',def));
end;

Кстати, переменная inifile распространяется на всю нашу прогу. Здесь мы просто выводим в textlist, то что считали из ini файла (это происходит при клике по надписи выбранной строки). Ну, теперь опишем кнопку closebutton:

procedure TInstallForm.CloseButtonClick(Sender: TObject);
var
    reg:tregistry;
begin
reg:=tregistry.Create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
 if reg.openkey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',false)=true then
   begin
     reg.DeleteValue('AutoInstall') ;
   end;
reg.CloseKey;
reg.Destroy;
deletefile(temppath+'\installlist.txt');
application.Terminate;
end;

А что так много спросите вы? Казалось бы application.terminate и все, но не так все просто, а вот почему: дело в том, что если выход из программы корректен, то нам нужно удалить из реестра следы нами оставленные (оставим мы их только при незавершенных операция установки), или просто удостовериться, что их там нет(и рам и пользователю спокойно). Также удаляем файл с настройками. Почему application.terminate, а не installform.close, потому что мне полгода твердили в институте, что так правильнее (хотя кто как хочет). переходим к самому сложному в коде - описанию кнопки startbutton. Хотя если хоть немного читать и иметь под рукой MSDN и это несложно (сам проверял). Итак, пишем вот это:

procedure TInstallForm.StartButtonClick(Sender: TObject);
var k,i:integer;
    def:string;
    f:textfile;
    reg:tregistry;
    pres:string;
begin
// сохраняем себя в реестре (на всякий случай)
reg:=tregistry.Create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
 if reg.openkey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',false)=true then
   begin
     pres:=reg.ReadString('AutoInstall');
     if (pres='')or(pres<>application.exename) then
             if reg.CreateKey('AutoInstall')=true then
                     reg.WriteString('AutoInstall',application.exename);
   end;
reg.CloseKey;
reg.Destroy;
// минимизируемся
showwindow(installform.Handle,2);
// обрабатываем все отмеченные флаги по очереди
for k:=0 to tstr.count-1 do
 begin
// предварительно сохраняем настройки в installlist.txt
  assignfile(f,temppath+'\installlist.txt');
  rewrite(f);
  for i:=0 to filelist.count-1 do
    if filelist.Checked[i]=true then
       writeln(f,filelist.items.strings[i]);
  closefile(f);
  if filelist.Checked[k]=true then
   begin
    filelist.Checked[k]:=false;
    StartAndWaitEnd(extractfilepath(application.ExeName)+
          inifile.ReadString(tstr.Strings[k],'Path',def));
   end;
 end;
// после окончания операции устраняем себя из реестра
reg:=tregistry.Create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
 if reg.openkey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',false)=true then
   begin
     reg.DeleteValue('AutoInstall') ;
   end;
reg.CloseKey;
reg.Destroy;
// возвращаем окно к исходному виду и положению
showwindow(installform.Handle,1);
// убиваем файл с настройками
deletefile(temppath+'\installlist.txt');
end;

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

function TInstallForm.StartAndWaitEnd(cmdline:string):boolean;
var  si:TSTARTUPINFO;
     pi:TPROCESSINFORMATION;
begin
ZeroMemory(@si,sizeof(si));
si.cb:=SizeOf(si);
si.dwFlags := startf_UseShowWindow;
si.wShowWindow:=1;
if not CreateProcess( nil,PChar(cmdline),nil,nil,False,0,nil,nil,si,pi ) then
        begin
         StartAndWaitEnd:=false;
        end
else
        StartAndWaitEnd:=true;
    application.ProcessMessages;
    WaitForSingleObject( pi.hProcess, INFINITE );
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
end;

Здесь CreatePorcess запускает выбранное приложение, а WaitForSingleObject ожидает, пока процесс завершится. Кто хочет знать больше - читайте MSDN, есть еще много всякой литературы по этому поводу. Вот теперь все!

Заключение

Это вроде все, но если кто знает способ по-лучше с удовольствием ознакомлясь. Не забудьте подключить модули Registry и IniFiles. Кстати, сама наша прога будет недоступна пока работает запущенное с помощью неё приложение (много пытался не получилось "оживить"), а так все работает корректно, а нажимать "да", "далее", "готово" придется все равно самому. Пишите комментарии, почитаю. Если у кого-то есть предложения (например, как и Abigor'а оставьте сообщение kosfiz'у или в комментарии опишите). Если у кого есть вопросы, то пишите мне на ящик, обязательно отвечу. Прошу прощение за возможные опечатки.

P.S. Abigor, ну как получилось?

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
Аноним
Мне нравитсяМне не нравится
6 декабря 2005, 11:51:18
Для того, чтобы форма не "замораживалась", покаместь работает процесс, запущенный с помощью CreateProcess можно пользовать либо WaitForMultipleObjects или MsgWaitForMultipleObjects (вторая обрабатывает и сообщения от окон).
Примеры использования этих функций именно в сочетании с CreateProcess можно найти в том же Яндексе, набрав имя этой функции.
Описание доступнов MSDN.
2.
Аноним
Мне нравитсяМне не нравится
22 октября 2005, 03:29:07
В который раз убедился, что не зря не учился в институте!
Как всё круто, клёво, и ... сложно.
А зачем?
Я решил эту задачу примерно так:
MyInstal.bat

@echo off
echo УСТАНОВКА Power DVD 'это выводится на экран
del C:\WINDOWS\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1\7DVD.pif
REM удаление ярлыка со ссылкой на этот .bat из автозагрузки
copy C:\MYINSTAL\Programs\8Aditor.pif C:\WINDOWS\ГЛАВНО~1\ПРОГРА~1\АВТОЗА~1
REM ярлык в автозагрузку на следующий .bat , на случай если понадобится перезагрузка
D:\DVD\POWERD~5.062\setup.exe
pause После завершения установки Power DVD,
REM ожидание окончания установки проги

И ВСЁ!!!
в .pif стоит галка закрыть окно по завершению...
если прога установки однозначно выходит на рестарт, строка "pause После завершения установки..." не нужна. Если рестарт не нужен - аналогичный текст для следующей проги
если какую-то из программ не надо ставить - в ней самой есть кнопка "Отмена".
Тем более, что "нажимать "да", "далее", "готово" придется все равно самому"
3.
Аноним
Мне нравитсяМне не нравится
18 октября 2005, 12:29:45
а ветку в реестре для кого придумали???

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
4.
Аноним
Мне нравитсяМне не нравится
18 октября 2005, 04:04:14
>"а нажимать "да", "далее", "готово" придется все равно самому"

Вот в этом вся проблема. Зачем она нужна тогда?
5.
Аноним
Мне нравитсяМне не нравится
18 октября 2005, 02:39:24
там в ини файле забыта строка
crack_or_keygen =
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог