Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.04.2017, 20:24   #1
ApxaHGe1
 
Регистрация: 15.07.2009
Сообщений: 8
По умолчанию Модуль автообновления

Добрый вечер, горю!!! Помогите пожалуйста, завтра программу сдавать нужно на работе... Продажи "стоят" Но вот незадача, не работает модуль автообновления...
модуль писал сам, без него никуда!!! Пользователи "тяжелые" и объяснять им про обновления тяжело будет очень..

Много лишнего в нем, спору нет, но не суть... сам факт, мне нужно что бы он работал... точнее, он работает!! и прекрасно работает... но нет отображения процесса загрузки файлов обновления... прогресс бар молчит (
Сам процесс обновления соответственно в отдельном потоке ...
Код:
type
   TUpdate = class(TThread)
protected
    procedure Execute; override;
end;

var
Server:string;
FVersion:string;
FSize:string;

HTTP:TIdHTTP;
HTTP2:TIdHTTP;
UpdateForm:TForm;
Update:TUpdate;
UpdateList:TStringList;
TotalSize:integer;
i,n:Integer;
ProgressBar: TProgressBar;
Log:Tmemo;
Stream:TMemoryStream;
FCount:integer;
Timer:TTimer;
//Статус обновления
UpdStatus:integer=0;

procedure Check_Update;

implementation

uses MainForm;

procedure HTTP2Work(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Int64);
begin
 ProgressBar.Position:= AWorkCount;
end;

procedure HTTP2WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
AWorkCountMax: Int64);
begin
 ProgressBar.Position:= 0;
 ProgressBar.Max:= AWorkcountMax;
end;


procedure TimerTimer(Sender: TObject);
begin
ProgressBar.Position:=Stream.Position;
end;

//Поток обновления приложения
procedure TUpdate.Execute;
begin
//synchronize(Check_Update);
//Делаем форму видимой из за главной формы
UpdateForm.BringToFront;
//TForm(Sender).BringToFront;
HTTP2:=TIdHTTP.Create(nil);
try
Stream:=TMemoryStream.Create;
//Обрабатываем в цикле информацию о файлах и объем файлов
//для обновления
for FCount:=0 to UpdateList.Count - 1 do
begin
//Выбираем из списка имена файлов обновления
if FCount mod 2 = 0 then
begin
//Log.Lines.Add('Загрузка файла: '+UpdateList.Strings[FCount]);
//Log.Lines.Add('Размер загружаемого файла: '+UpdateList.Strings[FCount+1]);
HTTP2.Get(Server+UpdateList.Strings[FCount],Stream);
ProgressBar.Max:=StrToInt (UpdateList.Strings[FCount+1]);
Timer.Enabled:=True;
Stream.SaveToFile(ExtractFilePath(ParamStr(0))+'\'+UpdateList.Strings[FCount]+'_');
end;
Stream.Position:=0;
Timer.Enabled:=False;
end;
//Окончание обновления
UpdateForm.Canvas.Create;
Stream.Free;
Log.Lines.Add('Оновление успешно завершено!');
Log.Lines.Add('____________________________________________');
Log.Lines.Add(' =========Установка обновлений=========');
//Теперь нужно перезапустить программу, что бы запустилась обновленная версия
except
on E: Exception do
      ShowMessage (E.Message);
end;

end;

procedure Check_Update;
begin
try
HTTP:=TIdHTTP.Create(nil);
Server:='http://**********.ru/soft/' ;
//получаем версию файла на сервере
FVersion:=HTTP.Get(Server+'ver.txt');
if Form1.Vers = FVersion then
begin
  ShowMEssage ('Вы используете актуальную версию программы!');
  exit;
end;

if Form1.Vers < FVersion then
begin
//Получаем список файлов для обновления
UpdateList:=TStringList.Create;
UpdateList.Text:=HTTP.Get(Server+'FileList.txt');
//Подсчитаем общий объем файлов для скачивания
for I := 0 to UpdateList.Count-1  do
begin
if i mod 2 = 1 then
begin
TotalSize:=TotalSize + StrToInt (UpdateList.Strings[i]) ;
end;

end;
//Закончили расчет общего объема файлов
//Создаем форму и настраиваем ее
UpdateForm:=TForm.Create(nil);
UpdateForm.Position:=poDesktopCenter;
UpdateForm.Caption:='Обновление ...';
UpdateForm.Height:=275;
UpdateForm.Width:=300;
UpdateForm.BorderStyle:=bsToolWindow;
ProgressBar:=TProgressBar.Create(nil);
ProgressBar.Parent:=UpdateForm;
ProgressBar.Height:=30;
ProgressBar.Width:=295;
ProgressBar.Visible:=True;
Log:=TMemo.Create(nil);
Log.Parent:=UpdateForm;
log.Top:=40;
Log.Width:=295;
Log.Height:=200;
Log.ScrollBars:=ssVertical;
Log.ReadOnly:=True;
Log.TabOrder:=4;
//Выведем краткую информацию по обновлению
Log.Lines.Add(' ========Доступно оновление '+FVersion+'========');
Log.Lines.Add('Количество файлов для обновления: '+IntToStr (UpdateList.Count-1));
//Log.Lines.Add('Общий объем обновления: '+IntToStr(TotalSize));
Log.Lines.Add('Идет загрузка обновлений ... ');
Log.Lines.Add('____________________________________________');
Timer:=TTImer.Create(nil);
Timer.Interval:=500;
Timer.Enabled:=True;
UpdateForm.Show;
//Создадим поток
Update:= TUpdate.Create(false);
Update.Priority:= tpNormal;
Update.FreeOnTerminate:= true;
end;
UpdStatus:=1;
except
on E: Exception do ShowMessage (E.Message);
end;

end;


end.
ApxaHGe1 вне форума Ответить с цитированием
Старый 15.04.2017, 20:43   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Хорошо, что вообще поток работает. Но это временно)) Нельзя напрямую к vcl из потока обращаться. Или синхронизируй или форме сообщения посылай из потока
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 15.04.2017, 21:02   #3
ApxaHGe1
 
Регистрация: 15.07.2009
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Хорошо, что вообще поток работает. Но это временно)) Нельзя напрямую к vcl из потока обращаться. Или синхронизируй или форме сообщения посылай из потока
Спасибо за чумовой помощи ответ....
А по сути ? можешь чем помочь ?
ApxaHGe1 вне форума Ответить с цитированием
Старый 15.04.2017, 21:23   #4
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

что то у вас непонятно что это
ProgressBar.Max:=StrToInt (UpdateList.Strings[FCount+1]);
наверное лучше так иначе неправильно определяет максимальное значение
ProgressBar.Max:= UpdateList.Count;
да и вообще код какой то мудреный

да и к Log.Lines лучше обращаться из потока через функцию в synchronize для правильной работы с визуальными инфо данными, как вам уже подсказали
примерно так
Код:
Procedure TUpdate.Stoped;
begin
Log.Lines.Add('Оновление успешно завершено!');
Log.Lines.Add('____________________________________________');
Log.Lines.Add(' =========Установка обновлений=========');
end;
и обратиться из потока synchronize(Stoped);

Да и это UpdateForm.Canvas.Create; для чего

Последний раз редактировалось Aliens_wolfs; 15.04.2017 в 21:40.
Aliens_wolfs вне форума Ответить с цитированием
Старый 15.04.2017, 22:02   #5
ApxaHGe1
 
Регистрация: 15.07.2009
Сообщений: 8
По умолчанию

UpdateList - список файлов обновления
ProgressBar.Max - Максимальное значение берется для каждого отдельного файла, из списка UpdateList

Код мудренный, спору нет, я сам уже начинаю в нем путаться.
Меня интересует, процесс загрузки каждого файла... поэтому
ProgressBar.Max:=StrToInt (UpdateList.Strings[FCount+1]);
ApxaHGe1 вне форума Ответить с цитированием
Старый 15.04.2017, 22:05   #6
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Я так понял что у вас в UpdateList.Strings просто список файлов, а не числовые значения, а там нужно кроме имен файлов и их размер писать потом это размер подставлять ProgressBar.Max

Список должен быть примерно такого содержания
ИмяФайла size=1267
Код:
SS:= UpdateList.Strings[FCount+1];
ProgressBar.Max:=StrToInt (Copy(SS, Pos('size=', SS) + 5,  maxint));
Timer.Enabled:=True;
HTTP2.Get(Server+UpdateList.Strings[FCount],Stream);
а для сохранения файла сделать так
Код:
SS:= UpdateList.Strings[FCount+1];
Stream.SaveToFile(ExtractFilePath(ParamStr(0))+'\'+Copy(SS, 1, Pos('size=', SS) -1)+'_');

Последний раз редактировалось Aliens_wolfs; 16.04.2017 в 10:43.
Aliens_wolfs вне форума Ответить с цитированием
Старый 16.04.2017, 11:26   #7
ApxaHGe1
 
Регистрация: 15.07.2009
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Я так понял что у вас в UpdateList.Strings просто список файлов, а не числовые значения, а там нужно кроме имен файлов и их размер писать потом это размер подставлять ProgressBar.Max

Список должен быть примерно такого содержания
ИмяФайла size=1267
Код:
SS:= UpdateList.Strings[FCount+1];
ProgressBar.Max:=StrToInt (Copy(SS, Pos('size=', SS) + 5,  maxint));
Timer.Enabled:=True;
HTTP2.Get(Server+UpdateList.Strings[FCount],Stream);
а для сохранения файла сделать так
Код:
SS:= UpdateList.Strings[FCount+1];
Stream.SaveToFile(ExtractFilePath(ParamStr(0))+'\'+Copy(SS, 1, Pos('size=', SS) -1)+'_');
Список такого формата
123.exe
7777 // размер файла
ApxaHGe1 вне форума Ответить с цитированием
Старый 16.04.2017, 11:35   #8
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

У вас тогда в потоке последовательность неправильная нужно так

ProgressBar.Max:=StrToInt (UpdateList.Strings[FCount+1]);
Timer.Enabled:=True;
HTTP2.Get(Server+UpdateList.Strings[FCount],Stream); // Она работает в ожидании, все что за ней отработает после получения данных
Stream.SaveToFile(ExtractFilePath(P aramStr(0))+'\'+UpdateList.Strings[FCount]+'_');

Последний раз редактировалось Aliens_wolfs; 16.04.2017 в 11:38.
Aliens_wolfs вне форума Ответить с цитированием
Старый 16.04.2017, 19:28   #9
ApxaHGe1
 
Регистрация: 15.07.2009
Сообщений: 8
По умолчанию

Спасибо,но почему то
Код:
procedure TimerTimer(Sender: TObject);
begin
ProgressBar.Position:=Stream.Position;
end;
не работает вообще ( т.е. сам таймер

Так... все идет как надо.. пока не скачается файл, надпись о заказчке следующег оне появляется... но вот не отображается и все (((

Последний раз редактировалось ApxaHGe1; 16.04.2017 в 19:31.
ApxaHGe1 вне форума Ответить с цитированием
Старый 16.04.2017, 19:51   #10
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

У вас HTTP2WorkBegin и HTTP2Work объявлены, но не соединены с компонентом.
Во-первых их надо сделать членами класса. А во вторых пописать в событиях.

Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
IdHTTP1.OnWorkBegin:=IdHTTP1WorkBegin;
IdHTTP1.OnWork:=IdHTTP1Work;

end;

procedure TForm1.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
begin
 ProgressBar1.Position := 0;
 ProgressBar1.Max := AWorkcountMax;
end;

procedure TForm1.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
begin
 ProgressBar1.Position := AWorkCount;
end;
И ещё рекомендуют применять компонент IdAntiFreeze1.

Что касается потока. Антивирус обычно ругается когда программа себя обновляет. Поэтому программы стоит разделять одна основная другая для скачки. Сами понимаете при такой схеме потоки не нужны.

Что касается таймера, то он работать он не будет. Пока всё не скачаете. Тут только если антифриз поможет. Или если допустимо то внутри IdHTTP1Work сделать Application.ProcessMessages;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 16.04.2017 в 19:54.
Pavia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создать собственный модуль и программу, использующую этот модуль. Oraner Паскаль, Turbo Pascal, PascalABC.NET 2 02.12.2012 13:15
Модуль Graph или графический модуль Seferus Паскаль, Turbo Pascal, PascalABC.NET 0 11.12.2011 13:15
Скрипт автообновления Glavar PHP 1 08.01.2011 14:06
Типизированные файлы, модуль Crt, Модуль Graph Kate_Fleur Помощь студентам 1 06.05.2010 17:43
Автообновления xap4o PHP 5 13.02.2010 22:37