PDA

Просмотр полной версии : [Статья] Делаем Updater до программы с помощью Indy. Delphi.


VeTaL_UA
18.11.2011, 21:28
Доброго времени суток!

В этой статье я попробую научить вас писать Updater для своей программы.

Что нам нужно для работы:

Delphi любой версии. Ссылки на скачку:

Delphi 7(deposit ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),torrent ([Ссылки могут видеть только зарегистрированные и активированные пользователи]));
Delphi 2010(deposit ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),torrent ([Ссылки могут видеть только зарегистрированные и активированные пользователи]));
Delphi XE(deposit ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),torrent ([Ссылки могут видеть только зарегистрированные и активированные пользователи]));

Cайт, созданный с помощью конструктора ucoz ([Ссылки могут видеть только зарегистрированные и активированные пользователи]);
Желание;


Ну что же, если все пункты присутствуют можно начать.



Updater - это вспомогательная программа, которая проверяет на наличие обновления к другой программе и загружает их;
Для примера я написал пустую программу и её "обновлённую" версию:
Скачать(1 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]*********/fd27928),2 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),3 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),4 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),5 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]));
virustotal(1 ([Ссылки могут видеть только зарегистрированные и активированные пользователи] a7116ac824ec0047311d82332bf0a-1321639442),2 ([Ссылки могут видеть только зарегистрированные и активированные пользователи] aca220fcb5f05871c23e46dfec98f-1321639704));
Создаём в папке с нашим Updater'ом файл "version.txt", где прописываем версию вашей программы. Например:
1.0.0.0
На сервере создаём точно такой же файл;
Запаковываем на сервер "обновленную" версию файла, который вы скачали, в архив "program.rar" и закидываем на сервер;

Если все пункты проделаны, можно переходить к написанию кода.


Теперь мы приступаем к написанию кода.

Запускаем делфи;
Кидаем на форму один компонент "Button" из вкладки "Standart":
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Кидаем на форму один компонент IdHTTP из вкладки "Indy Clients":
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Создаем обработчик событий OnClick на компоненте Button(два раза кликаем по Button'у);
Теперь нам нужно написать исполняемый код. Но для этого надо знать, что писать:

Для начала, обьявим переменные типов TId[Ссылки могут видеть только зарегистрированные и активированные пользователи] TFileStream, String и TStringList:
var
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Response:TFileStream;
s:string;
Version:TStringList;
Теперь создадим TIdHTTP и TStringList:
[Ссылки могут видеть только зарегистрированные и активированные пользователи](nil);
Version:=TStringList.Create;
Теперь отправим Get запрос на адрес, по которому на сервере лежит файл "version.txt", подгружая Response в переменную "s":
s:=[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]');
Теперь подгрузим содержимое файла "version.txt", который находится в папке с Updater'ом, в переменную "Version":
Version.LoadFromFile('version.txt');
Теперь проверим на наличие теста из переменной "s" в переменной "Version" и если текст присутствует, то выдаём окошко с сообщением:
Обновления не обнаружено. Текущая версия программы - последняя
Если же текст отсутствует, тогда выдаём окошко с сообщением:
Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.
Создаём TFileStream и отправляем Get запрос на адрес, по которому на сервере лежит архив с новой версией программы, подгружая Response в переменную "Response"(Собственно, предыдущее действие есть загрузкой файла с сервера на компьютер) Добавляем текст из переменной "s" в переменную "Version" и сохраняем её в файл "version.txt":
if Pos(s,Version.Text)<>0 then
begin
ShowMessage('Обновления не обнаружено. Текущая версия программы - последняя')
end
else
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
Response:=TFileStream.Create('program.rar',fmCreat e);
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Version.Add(s);
Version.SaveToFile('version.txt');
end;
Ну и под конец очищаем переменные:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Version.Free;



Полный код процедуры нажатия на кнопку:
procedure TForm1.Button1Click(Sender: TObject);
var
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Response:TFileStream;
s:string;
Version:TStringList;
begin
[Ссылки могут видеть только зарегистрированные и активированные пользователи](nil);
Version:=TStringList.Create;
try
s:=[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]');
Version.LoadFromFile('version.txt');
if Pos(s,Version.Text)<>0 then
begin
ShowMessage('Обновления не обнаружено. Текущая версия программы - последняя')
end
else
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
Response:=TFileStream.Create('program.rar',fmCreat e);
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Version.Add(s);
Version.SaveToFile('version.txt');
end;
finally
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Version.Free;
end;
end;

Чтобы проверить работоспособность программы нужно запустить программу, нажать на кнопку, потом изменить файл "version.txt" на сервере и нажать на кнопку ещё раз.


Теперь, когда мы закончили написание программы, запускаем программу и смотрим, что получилось.

Скачать исходник(1 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]*********/fd27956),2 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),3 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),4 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),5 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]));
Скачать скриншоты(1 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]*********/fd27957),2 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),3 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),4 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),5 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]));

Статья писалась VeTaL_UA для Zhyk.RU. При копировании указывать ссылку на данную тему.

Dimedrol1536
10.12.2011, 21:11
Во время загрузки файла программа как-бы подвисает. Вот вывести бы сообщение типа "Подождите, идёт скачивание файла". Как это реализовать?

VeTaL_UA
10.12.2011, 21:30
Как это реализовать?
Кидаешь на форму Panel и вместо этого:
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
Response:=TFileStream.Create('program.rar',fmCreat e);
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Version.Add(s);
Version.SaveToFile('version.txt');
end;
Ставим это:
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
Panel1.Caption:='Выполняется загрузка файла. НЕ ТЫКАЙТЕ ПО ПРОГРАММЕ!!!';
Response:=TFileStream.Create('program.rar',fmCreat e);
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Version.Add(s);
Version.SaveToFile('version.txt');
Panel1.Caption:='Файл загружён';
end;

Mebius
11.12.2011, 10:57
Кидаешь на форму Panel и вместо этого:
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
Response:=TFileStream.Create('program.rar',fmCreat e);
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Version.Add(s);
Version.SaveToFile('version.txt');
end;
Ставим это:
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
Panel1.Caption:='Выполняется загрузка файла. НЕ ТЫКАЙТЕ ПО ПРОГРАММЕ!!!';
Response:=TFileStream.Create('program.rar',fmCreat e);
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Version.Add(s);
Version.SaveToFile('version.txt');
Panel1.Caption:='Файл загружён';
end;


не верно, кидаем на форму IdAntiFreeze который эмулирует работу не блокирующих сокетов, прога будет дергаться, но подвисать наглухо не будет

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

что бы форма совсем не висла, используем класс TThread.


uses Id[Ссылки могут видеть только зарегистрированные и активированные пользователи]

type
TUpdater = class(TThread)
protected
procedure Execute; override;
end;

procedure TUpdater.Execute;
var
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
File:TMemoryStream;
Ver:TStringList;
s:string;
begin
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
File:=TMemoryStream.Create;
Ver:=TStringList.Create;

try
s:=[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]');
if FileExists('version.txt') then
Ver.LoadFromFile('version.txt')
else
exit;
if Pos(s,Version.Text)<>0 then
begin
ShowMessage('Обновления не обнаружено. Текущая версия программы - последняя')
end
else
begin
ShowMessage('Обнаружено обновление. Сейчас начнётся загрузка новой версии программы.');
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',File);
Ver.Add(s);
Ver.SaveToFile('version.txt');
File.SaveToFile('update.rar');
end;
finally
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
File.Free;
Ver.Free;
end;

end;

код чуть не дописан и на работоспособность не проверен тк писал прямо тут

ну и что б народ тупо не копировал готовый код, это не есть хорошо, тк задача тривиальна

З.Ы. веталь все равно молодец)

VeTaL_UA
11.12.2011, 12:22
веталь, дык тут только скачка новой версии, это не апдейтер же, а просто авто качалка новой версии, а для апдейта надо это дело еще все распаковать с заменой, а скачать в ту же папку файл с тем же именем не прокатит тк винда не даст заменить запущеный процесс.
Скачка в архиве была сделана из-за того, что инди не хочет качать exe файл, а желания расписывать, как скачать файл через сокеты вообще не было /horror
используем класс TThread
Если бы я начал рассказывать ещё и о работе с класом TThread, то статья увеличилась бы, как минимум, в два раза...
кидаем на форму IdAntiFreeze
А вот про него забыл :brberbrb:
веталь все равно молодец)
Спасибо :reddy:

Mebius
11.12.2011, 12:49
Скачка в архиве была сделана из-за того, что инди не хочет качать exe файл, а желания расписывать, как скачать файл через сокеты вообще не было /horror

Если бы я начал рассказывать ещё и о работе с класом TThread, то статья увеличилась бы, как минимум, в два раза...

А вот про него забыл :brberbrb:

Спасибо :reddy:

как то отказывается, я качал, на первых парах когда инди изучал, компонент конечно фиговый.

а про потоки, там просто все)))

можно не сокетами, есть synapse))) сокеты конечно для начала дико тяжко))) особенно если на винсок

З.Ы. тоже чтоль статейку какую нить написать, есть идеи?)

З.Ы.Ы. а как мастера света получить?)))

VeTaL_UA
11.12.2011, 13:28
сокеты конечно для начала дико тяжко))) особенно если на винсок
Я как раз на wisock и качаю файлы :)
тоже чтоль статейку какую нить написать, есть идеи?)
Я про инди пять написал(1 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),2 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),3 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),4 ([Ссылки могут видеть только зарегистрированные и активированные пользователи]),5 ([Ссылки могут видеть только зарегистрированные и активированные пользователи])) :)
а как мастера света получить?)))
Подполье Perfect World ;)

VortexWhy
12.12.2011, 13:51
Веталь, я сделал но,у меня он часто весит, и не понимаю, что делать?

VeTaL_UA
12.12.2011, 14:19
Веталь, я сделал но,у меня он часто весит, и не понимаю, что делать?
Весит, вероятно из-за того, что идёт скачка файла и нужно просто подождать.
я в него встроил Валлхак чтобы продавать,нажимаю чтоб выдал ключ у меня подвисает.
А эту фразу я вообще не понял /horror

iLnes
13.12.2011, 14:50
Веталь, я сделал но,у меня он часто весит, и не понимаю, что делать?
Если используешь стандартную Delphi, то обнови инди на самую последнюю, она работает куда быстрее и программы будет зависать при скачке на 1-1.5 секунд.

VeTaL_UA
13.12.2011, 17:29
Если используешь стандартную Delphi, то обнови инди на самую последнюю, она работает куда быстрее и программы будет зависать при скачке на 1-1.5 секунд.
Время зависания зависит только от величины файла и скорости интернета. Не думаю, что версия инди сильно влияет...

iLnes
14.12.2011, 14:52
Время зависания зависит только от величины файла и скорости интернета. Не думаю, что версия инди сильно влияет...

Проверена на личном опыте, поверь)
Я тоже думал, что бредовая идея, но все таки помогло сократить на 1-1.5 секунды, что порой очень нужно)

VeTaL_UA
14.12.2011, 15:14
Проверена на личном опыте, поверь)
Я тоже думал, что бредовая идея, но все таки помогло сократить на 1-1.5 секунды, что порой очень нужно)
В любом случае, эта статья только пример реализации. Я вообще никогда бы не грузил файлы через Indy...

blad56
15.12.2011, 17:20
А что если при запуске делать проверку и если есть обновления, то закрывать программу и открывать отдельный модуль и с помощью него производить загрузку основной программы с заменой файлов? как такое реализовать?)

iLnes
15.12.2011, 17:38
А что если при запуске делать проверку и если есть обновления, то закрывать программу и открывать отдельный модуль и с помощью него производить загрузку основной программы с заменой файлов? как такое реализовать?)

Эм.
Делаешь еще одну форму, пишешь проверку if ... then
Form2.Show;
else
ExitProcess();
Потом уже сделать самоудаление овновной программы и юзверу уже только останется запустить новую :)

VeTaL_UA
15.12.2011, 20:29
А что если при запуске делать проверку и если есть обновления, то закрывать программу и открывать отдельный модуль и с помощью него производить загрузку основной программы с заменой файлов? как такое реализовать?)
Используй динамические библиотеки...

Mebius
16.12.2011, 23:05
Используй динамические библиотеки...

веталь, читай внимательней, отдельный модуль запускать, как ты дллку запустишь?)

VeTaL_UA
17.12.2011, 10:49
веталь, читай внимательней, отдельный модуль запускать, как ты дллку запустишь?)
Тогда модуль создавать для проверки :)

Mebius
17.12.2011, 12:41
Тогда модуль создавать для проверки :)

а чего его создавать? простейший поток, постоянно проверяющий подключен ли юзверь с ником и вывод этого всего дела на экран, там мало работы как мне кажется)))

V.I.R.U.S.
17.12.2011, 20:52
Вообще проще всего использовать для этого отдельную программу, типа Updater. При этом апдейтер обновляет файлы основной программы, а программа в свою очередь обновляет сам апдейтер если это нужно.

iLnes
18.12.2011, 10:59
Вообще проще всего использовать для этого отдельную программу, типа Updater. При этом апдейтер обновляет файлы основной программы, а программа в свою очередь обновляет сам апдейтер если это нужно.
Вот это хорошая идея.
Правда не вижу смысла делать обновления Updater'а через основную программу, когда можно сделать все через веб-сервер. Неужто требуется обновлять updater? Я думаю нет :)

VeTaL_UA(1)
19.12.2011, 21:23
Люди добрые, вы хоть бы статью прочитали, или хотя бы название темы. Эта статья и учит создавать апдейтер до основной программы...

3jhlty3
18.01.2012, 19:50
Так вот это мне нравится больше)) Но можно ли проверку делать не так как у вас? Ну я изменил по своему вроде всё робит, но большое но если делать архивом как вы написали, то пользователю придётся распаковывать, а можно сделать что-бы сразу файлы заменялись?
И что-бы были проценты загрузки? Очень прошу помогите)))

VeTaL_UA
18.01.2012, 22:05
Так вот это мне нравится больше)) Но можно ли проверку делать не так как у вас? Ну я изменил по своему вроде всё робит, но большое но если делать архивом как вы написали, то пользователю придётся распаковывать, а можно сделать что-бы сразу файлы заменялись?
И что-бы были проценты загрузки? Очень прошу помогите)))
Тут я показал только очень примитивный метод. Загружать файлы лучше через низкоуровневые сокеты, тем же и процент выводить. Через сокеты можно сразу екзешник скачать :)

3jhlty3
19.01.2012, 14:58
Тут я показал только очень примитивный метод. Загружать файлы лучше через низкоуровневые сокеты, тем же и процент выводить. Через сокеты можно сразу екзешник скачать
Можно поподробней и если можно, то дайте код плз... я так понял за скачивание отвечает вот эта страка?
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);

VeTaL_UA
19.01.2012, 17:16
я так понял за скачивание отвечает вот эта страка?
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Да.
Поподробнее можно почитать в гугле, вбив в него запрос "Скачивание файле через WinSock Delphi ([Ссылки могут видеть только зарегистрированные и активированные пользователи] D%D0%B8%D0%B5+%D1%84%D0%B0%D0%B9%D0%BB%D0%B5+%D1%8 7%D0%B5%D1%80%D0%B5%D0%B7+WinSock+Delphi)". :)

3jhlty3
19.01.2012, 19:28
Да.
Поподробнее можно почитать в гугле, вбив в него запрос "Скачивание файле через WinSock Delphi ([Ссылки могут видеть только зарегистрированные и активированные пользователи] D%D0%B8%D0%B5+%D1%84%D0%B0%D0%B9%D0%BB%D0%B5+%D1%8 7%D0%B5%D1%80%D0%B5%D0%B7+WinSock+Delphi)". :)

А можете полностью создать новую тему, где всё подробно описать? :wow: Умаляю, очень прошу))):z: ну или хотя-бы как сделать проценты, я попробывал сделать ну тай строчкой, но не понятно когда скачается если рано закрыть, то ошибка вылетает....

VeTaL_UA
19.01.2012, 20:33
А можете полностью создать новую тему, где всё подробно описать?
Не знаю. Позже. Сейчас занят.
если рано закрыть, то ошибка вылетает....
Это ошибка исчезнет, если запускать программу с екзешника, а не компилировать в среде :)

3jhlty3
20.01.2012, 14:36
я так понял за скачивание отвечает вот эта страка?
[Ссылки могут видеть только зарегистрированные и активированные пользователи]('[Ссылки могут видеть только зарегистрированные и активированные пользователи]',Response);
Да.
Хм я тут заметил, ну может это только у меня, но он больше 500килобайт не качает........
У меня программа весит 2 мигабайта... как мне их скачать?

VeTaL_UA
05.02.2012, 22:28
В Mozilla Firefox так и сделано. Там отдельный апдейтер есть. Это лучший вариант.
Люди добрые, вы хоть бы статью прочитали, или хотя бы название темы. Эта статья и учит создавать апдейтер до основной программы...
/facepalm

VeTaL_UA
09.04.2012, 20:20
Mallobar, если бы ты внимательно прочитай тему, то увидел бы, что файл version.txt обновляется ;)

VeTaL_UA
09.04.2012, 22:51
Mallobar, в исходнике отсутствует эта строка:
Version.SaveToFile('version.txt');

Awesome58
03.06.2012, 16:11
В коде не хватает строки

Version.Clear;

т.к. без нее файл version.txt не обновляется, а дополняется, т.е. номер новой версии не переписывает номер
старой, а дописывается снизу

VeTaL_UA
03.06.2012, 17:06
Awesome58, так и должно быть. Тоесть получается что-то типо истории обновлений.