(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Автообновление программы через MSSQL server

Источник: habrahabr
Zerpico

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

  1. Программа при включении проверяет на сервере последнюю версию.
  2. Если на сервере выше текушей то скачиваем Zip-архив c программой.
  3. Переименовываем файл приложения на другое (ради бэкапа и доступности к файлу), например с program.exe на program.backup.
  4. Распаковываем архив заменяя файлы в папке.
  5. Удаляем архив с обновлением.
  6. Перезапускам программу.


Но перед всем этим сначала создадим таблицу Updater (например) на MSSQL с полями:
name - тип varchar;
version -тип varchar;
files - тип varbinary(max) (или любое другое blob-поле).
Лучше сразу создать в таблице запись, где в поле name будет program.
Добавить эту процедуру в код для извлечения номера версии программы:

function TForm1.GetMyVersion: string;
type
  TVerInfo=packed record
    Nevazhno: array[0..47] of byte; // ненужные нам 48 байт
    Minor,Major,Build,Release: word; // а тут версия
  end;
var
  s:TResourceStream;
  v:TVerInfo;
begin
  result:='';
  try
    s:=TResourceStream.Create(HInstance,'#1',RT_VERSION); // достаём ресурс
    if s.Size>0 then begin
      s.Read(v,SizeOf(v)); // читаем нужные нам байты
      result:=IntToStr(v.Major)+IntToStr(v.Minor)+ // вот и версия...
              IntToStr(v.Release)+IntToStr(v.Build);
    end;
  s.Free;
  except; end;
end;

Теперь нам понадобится библиотека для распаковки архивов, ведь я буду хранить обновление в zip архиве, использую библиотеку SevenZip, добавляем в Delphi в library путь до исходников библиотеки.
Теперь нам надо закачать сам архив с новой версией программы в базу данных. Я сделал форму с загрузкой обновления на сервер:
image
по открытию OpenDialog думаю всё понятно переписываем путь в edit

if OpenDialog1.Execute then
cxButtonEdit1.Text:=OpenDialog1.FileName;

Номер версии лучше вписывать в MaskEdit с маской - !9.9.9.0;1;_
По кнопке сохранить закачиваем файл процедурой:

var blobF: TBlobField;
begin
if not FileExists(OpenDialog1.FileName) then
 begin
  ShowMessage('Файл не найден!');
  exit;
 end else cxButtonEdit1.Text:=OpenDialog1.FileName;

try

  ADOTable1.TableName:=Updater; //выбираем таблицу в которой будем хранить архив
  ADOTable1.Close;
  ADOTable1.Open;
  //ищем поле name с записью program
  ADOTable1.Filtered := False;
  ADOTable1.Filter := 'name='+#39+'program'+#39; 
  ADOTable1.Filtered := True;
  ADOTable1.Edit;

  blobF := ADOTable1.FieldByName('files') as TBlobField;
  blobF.LoadFromFile(OpenDialog1.FileName);
  ADOTable1.FieldByName('version').AsString:=cxMaskEdit1.Text;
  ADOTable1.Post;
except
   Showmessage('Ошибка загрузки!');
end;

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

Необходимо добавить в Uses - SevenZip и ShellAPI.
Теперь создадим самую важную процедуру обновления, назовав её Update:

Procedure TForm1.Update;
var path,fullpath,Ourversion,LastVersion:string;
blobF: TBlobField;
begin
//получем номер версии на сервере
adoquery4.Active:=false;
adoquery4.sql.text:='SELECT version FROM [dbo].[Updater] WHERE name='+#39+'program'+#39;
adoquery4.Active:=true;

//добавляем номера версии на сервере и текушей в переменые, и убираем точки
Ourversion:=GetMyVersion;

LastVersion:=adoquery4.FieldByName('version').Value;
while pos('.',LastVersion)<>0 do
delete(LastVersion,pos('.',LastVersion),1);

//сравниваем версии если текушая меньше чем на сервере то спрашиваем обновлять или нет
if strtoint(LastVersion)>strtoint(Ourversion) then
If messageBox(Handle,'Появилось свежая версия программы. Обновить?','Обновить?',
mb_YesNo or mb_iconquestion)=mrYes then

 try
  path:=ExtractFileDir(ParamStr(0));
  if  FileExists(path+'\Program.backup') then DeleteFile(path+'\Project2.backup');
  RenameFile(path+'\Program.exe', path+'\Program.backup'); //переменовываем оригинальный файл
  //фильтруем
  //ADOTable1 указывает на таблицу Updater
  ADOTable1.Close;
  ADOTable1.Open;
  ADOTable1.Filtered := False;
  ADOTable1.Filter := 'name='+#39+'program'+#39;
  ADOTable1.Filtered := True;
  ADOTable1.Active:=true;
  //скачиваем файл
  blobF := ADOTable1.FieldByName('files') as TBlobField;
  if blobF.Value = nil then Exit;
  blobF.SaveToFile(path+'\Update_ARMTitan.zip');
  ADOTable1.Active:=false;

  // Распаковывает файлы
  with CreateInArchive(CLSID_CFormatZip) do
   begin
     OpenFile(ExtractFilePath(ParamStr(0)) + 'Update_ARMTitan.zip');
     ExtractTo(ExtractFilePath(ParamStr(0)));
     Close;
   end;
    //удаляем архив который скачали
    DeleteFile(path+'\Update_ARMTitan.zip');
   //перезапуск программы
   fullpath:=path+'\Project2.exe';
   ShellExecute(0, 'open', PWideChar(fullpath), '', nil, SW_SHOW);
   //WinExec(PAnsiChar(fullpath), SW_SHOW); 
   Application.Terminate; // or: Close;
 finally
 end;
end;

Здесь тоже есть недочет, распаковывать лучше в отдельности каждый файл и проверять на наличие ошибки, а не весь архив целиком как сделал я.
Тут есть 2 мелочи которые надо соблюдать: 
1. В директории с программой должен быть файл 7z.dll, поэтому лучше сделать проверку:

if  FileExists(path+'\7z.dll') then 
begin
   ShowMessage('Отсутствует файл 7z.dll');
   exit;
end;

или еще как то по другому.
2. В архиве с обновлением не должен присутствовать файл 7z.dll, так как он используется, или же распаковать всё по отдельности как я писал выше и не распаковывать только этот файл.

Вот и всё. Главное не забыть перед компиляцией готовой программы для обновления прежде чем добавить её в архив, изменить номер версии программы.

В этом способе есть некоторые недочёты и я это знаю. Но пока что я им пользуюсь и проблем не испытывал, хотя доработать всё же следует.



 Распечатать »
 Правила публикации »
  Обсудить материал в конференции Microsoft »
Обсудить материал в конференции Дизайн, графика, обработка изображений »
Написать редактору 
 Рекомендовать » Дата публикации: 29.11.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft System Center Standard Core Sngl License/Software Assurance Pack OLP 2Licenses NoLevel CoreLic Qualified
Microsoft Visual Studio Professional w/MSDN AllLng Software Assurance OLP 1 License No Level Qualified
Microsoft Office 365 для Дома 32-bit/x64. 5 ПК/Mac + 5 Планшетов + 5 Телефонов. Подписка на 1 год.
Microsoft Office 365 Профессиональный Плюс. Подписка на 1 рабочее место на 1 год
Microsoft SQL CAL 2017 Sngl OLP 1License NoLevel UsrCAL
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Реестр Windows. Секреты работы на компьютере
Краткие описания программ и ссылки на них
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Windows 10 загружен процессор (2)
Добрый день! На рабочем ПК Windows 10, компьютер тормозит, в диспетчере задач выдает что диск...
 
Отличается ли ДрифтКазино от беттинга? (8)
Друзья, давно заметил, что на Дрифте уже несколько месяцев во всю рекламируется и предлагается...
 
ErWin to Access Relation Error (2)
Всем привет! ErWin при попытке генерации в Ассеss выдаёт: ERwinDatabase.Relations.Append...
 
Помощь по MS Access (331)
Доброе время суток. Случайно оказался на этом сайте, искал статьи по OLAP. Вижу, что...
 
Смена типа уровня модели (1)
Здравствуйте. При запуске программы выбрал уровень "Логический" вместо "Логический и...
 
 
 



    
rambler's top100 Rambler's Top100