Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.12.2013, 13:03
Аватар для nerZEROn
nerZEROn nerZEROn вне форума
Прохожий
 
Регистрация: 23.12.2013
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Установка программ по списку из ini-файла

Добрый день!
Нужно написать утилиту, которая будет при нажатии кнопки устанавливать программы по списку из ini-файла.

Пример содержания файла:

[soft]
7zip=7zip\7z.exe
WinRAR=winrar\setup.exe

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

Собственно, вопрос: как правильно считать значения ключей из секции ini-файла и запихнуть их в CreateProcess, снабдив все это отдельным потоком?

Последний раз редактировалось nerZEROn, 23.12.2013 в 13:25.
Ответить с цитированием
  #2  
Старый 23.12.2013, 14:00
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от nerZEROn
Собственно, вопрос: как правильно считать значения ключей из секции ini-файла и запихнуть их в CreateProcess, снабдив все это отдельным потоком?
В модуле IniFiles есть класс TMemIniFile - открываешь с его помощью свой ini-файл, методом ReadSection читаешь из секции 'soft' имена ключей и потом в цикле методом ReadString считываешь каждый параметр и отдаёшь его в CreateProcess.

CreateProcess используешь примерно так:
Код:
var
  SI: TStartupInfo;
  PI: TProcessInformation;
.....
begin
.....
  FillChar(SI, SizeOf(SI), 0);
  SI.cb := SizeOf(SI);
  SI.wShowWindow := SW_NORMAL;
  SI.dwFlags := STARTF_USESHOWWINDOW;

  if CreateProcess('Запускаемое приложение', nil, nil, nil, False, 0, nil, nil, SI, PI) then
  try
    while True do
    begin
      if (WaitForSingleObject(PI.hProcess, 100) <> WAIT_TIMEOUT) or Terminated then Break;
    end;
  finally
    CloseHandle(PI.hProcess);
    CloseHandle(PI.hThread);
  end;
.....
end;

Для создания отдельного потока, используй BeginThread или создавай своего потомка от TThread или можешь использовать дополнительные компоненты - просто бросаешь такую компоненту на форму и задаёшь ей нужные обработчики событий. Например в библиотеке RxLib есть такая компонента, или вот здесь есть подобная (TBMDThread).
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
nerZEROn (23.12.2013)
  #3  
Старый 26.12.2013, 11:17
Аватар для nerZEROn
nerZEROn nerZEROn вне форума
Прохожий
 
Регистрация: 23.12.2013
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

А можно поподробнее по поводу цикла и считывания через ReadString? Я не особо хорошо в этом разбираюсь Нужно ведь сделать считывание по порядку из списка значений... но как это сделать и избавиться от бесконечного цикла?
Ответить с цитированием
  #4  
Старый 26.12.2013, 11:33
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от nerZEROn
А можно поподробнее по поводу цикла и считывания через ReadString? Я не особо хорошо в этом разбираюсь Нужно ведь сделать считывание по порядку из списка значений... но как это сделать и избавиться от бесконечного цикла?
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  ini: TMemIniFile;
  sl: TStringList;
  i: Integer;
  Ident, Value: String;
begin
  ini := TMemIniFile.Create('ИмяФайла.ini');
  try
    sl := TStringList.Create;
    try
      ini.ReadSection('soft', sl);
      for i := 0 to sl.Count - 1 do
      begin
        Ident := sl[i];
        Value := ini.ReadString('soft', Ident, '???');
        ShowMessageFmt('Для установки "%s" запускаем "%s"', [Ident, Value]);
      end;
    finally
      sl.Free;
    end;
  finally
    ini.Free;
  end;
end;
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
nerZEROn (26.12.2013)
  #5  
Старый 26.12.2013, 13:09
Аватар для nerZEROn
nerZEROn nerZEROn вне форума
Прохожий
 
Регистрация: 23.12.2013
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Код:
        Value := ini.ReadString('soft', Ident, '???');
        ShowMessageFmt('Для установки "%s" запускаем "%s"', [Ident, Value]);
      end;
    finally
      sl.Free;
    end;
  finally
    ini.Free;
  end;
end;

На этом этапе получаю сообщения типа 'Для установки "7Zip" запускаем "???"'. Выходит, Value не считывается?

А нет, нашел свой косяк Все нормально работает! Спасибо!

Последний раз редактировалось nerZEROn, 26.12.2013 в 13:22.
Ответить с цитированием
  #6  
Старый 26.12.2013, 19:03
Аватар для nerZEROn
nerZEROn nerZEROn вне форума
Прохожий
 
Регистрация: 23.12.2013
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Итак, я пришел к такому обработчику кнопки "Установить":

Код:
procedure TForm1.btn_instClick(Sender: TObject);
var
   ini: TMemIniFile;
   sl: TStrings;
   i: Integer;
   Ident, Value: String;
   SI: TStartupInfo;
   PI: TProcessInformation;
begin
   ini := TMemIniFile.Create('install.ini');
   FillChar(SI, SizeOf(SI), 0);
   SI.cb := SizeOf(SI);
   SI.wShowWindow := SW_NORMAL;
   SI.dwFlags := STARTF_USESHOWWINDOW;
   try
    sl := TStringList.Create;
    try
      ini.ReadSection('soft', sl);
      for i := 0 to sl.Count - 1 do
      begin
        Ident := sl[i];
        Value := ini.ReadString('soft', Ident, '');       
        if CreateProcess(PChar(Ident), PChar(' ' + Value), nil, nil, False, 0, nil, nil, SI, PI) then
          try
           while True do
            begin
             if (WaitForSingleObject(PI.hProcess, 100) <> WAIT_TIMEOUT) then Break;
            end;
           finally
            CloseHandle(PI.hProcess);
            CloseHandle(PI.hThread);
        end;
      end;
    finally
      sl.Free;
    end;
  finally
    ini.Free;
  end;
end;

В целом программа работает исправно: читает ini и запускает по порядку дистрибутивы программ с параметрами.
Но снова столкнулся с проблемой. Гуглил пол дня, копался в примерах и исходниках, но так и не понял, как вывести это все в отдельный поток. Также, я не смог найти никакой документации к компоненту BMDThread. Поскольку приложение будет выполнять у меня по несколько функций сразу, жизненно необходимо, чтобы основная форма была доступна во время инсталляции сторонних программ.
Ответить с цитированием
  #7  
Старый 26.12.2013, 19:26
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от nerZEROn
Но снова столкнулся с проблемой. Гуглил пол дня, копался в примерах и исходниках, но так и не понял, как вывести это все в отдельный поток. Также, я не смог найти никакой документации к компоненту BMDThread. Поскольку приложение будет выполнять у меня по несколько функций сразу, жизненно необходимо, чтобы основная форма была доступна во время инсталляции сторонних программ.
Что же там сложного - BMDThread идёт полностью в исходниках.
В событии OnExecute у BMDThread пиши то, что должно выполняться в отдельном потоке (thread), а для запуска потока просто вызови например по нажатию кнопки метод Start:
Код:
procedure TForm1.btn_instClick(Sender: TObject);
begin
  BMDThread1.Start;
end;
Ответить с цитированием
  #8  
Старый 26.12.2013, 19:51
Аватар для nerZEROn
nerZEROn nerZEROn вне форума
Прохожий
 
Регистрация: 23.12.2013
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Что же там сложного - BMDThread идёт полностью в исходниках.
В событии OnExecute у BMDThread пиши то, что должно выполняться в отдельном потоке (thread)
А можно подробнее? Я не совсем понимаю потоки, а уж компонент этот тем более) Может, есть какой-то исходник, показывающий работу компонента или какой-то пример... Мне проще разобраться, когда вижу, как это работает.
Ответить с цитированием
  #9  
Старый 27.12.2013, 00:06
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от nerZEROn
А можно подробнее? Я не совсем понимаю потоки, а уж компонент этот тем более) Может, есть какой-то исходник, показывающий работу компонента или какой-то пример... Мне проще разобраться, когда вижу, как это работает.
Вместе с компонентом в папке Demo идёт пример использования. Тот что для D5 прекрасно работает и в D7.
Ответить с цитированием
  #10  
Старый 27.12.2013, 22:12
Аватар для nerZEROn
nerZEROn nerZEROn вне форума
Прохожий
 
Регистрация: 23.12.2013
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Вместе с компонентом в папке Demo идёт пример использования. Тот что для D5 прекрасно работает и в D7.
Пытался сделать, опираясь на исходник этот - почему-то не запускает поток. Ну и ладно. Создал своими руками вот так:

Код:
TMyThread = class(TThread)
    private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

Запихнул в процедуру код на инсталляцию и ура! Приложение не виснет во время выполнения
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 06:38.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter