![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
||||
|
||||
|
Добрый день!
Нужно написать утилиту, которая будет при нажатии кнопки устанавливать программы по списку из ini-файла. Пример содержания файла: [soft] 7zip=7zip\7z.exe WinRAR=winrar\setup.exe При нажатии кнопки установки, утилита должна читать ini-файл, а затем, следуя списку, запускать по очереди инсталляторы. При этом хочется, чтобы это происходило в отдельном потоке, основная программа была бы доступна, и имелась возможность прервать процесс установки по нажатию соответствующей кнопки. Собственно, вопрос: как правильно считать значения ключей из секции ini-файла и запихнуть их в CreateProcess, снабдив все это отдельным потоком? Последний раз редактировалось nerZEROn, 23.12.2013 в 13:25. |
|
#2
|
||||
|
||||
|
Цитата:
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
|
||||
|
||||
|
А можно поподробнее по поводу цикла и считывания через ReadString? Я не особо хорошо в этом разбираюсь
Нужно ведь сделать считывание по порядку из списка значений... но как это сделать и избавиться от бесконечного цикла? |
|
#4
|
||||
|
||||
|
Цитата:
Код:
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
|
||||
|
||||
|
Цитата:
На этом этапе получаю сообщения типа 'Для установки "7Zip" запускаем "???"'. Выходит, Value не считывается? А нет, нашел свой косяк Все нормально работает! Спасибо!Последний раз редактировалось nerZEROn, 26.12.2013 в 13:22. |
|
#6
|
||||
|
||||
|
Итак, я пришел к такому обработчику кнопки "Установить":
Код:
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. Поскольку приложение будет выполнять у меня по несколько функций сразу, жизненно необходимо, чтобы основная форма была доступна во время инсталляции сторонних программ. |