Delphi как программе обновить саму себя
Перейти к содержимому

Delphi как программе обновить саму себя

  • автор:

Обновление программы

Author24 — интернет-сервис помощи студентам

Вот стартовые параметры:
Есть оболочка, при загрузке получаю с базы данных значение «ЕстьОбноваИлиНет», если True ( 1 ) то показываю кнопку для получения обновления.

Вот, на сайте, на хостинге, лежит файл: Update.exe (или какой? Предложите)
Вопрос 1: Как его скачать программой, запустить (ну это ладно, наверно как-то так)

ShellExecute(0, 'open', PWideChar(Pwidestring(s)), nil, nil, SW_SHOW);

Вопрос 2: Может вообще велосипед, есть что-то готовое хорошее?
Ну или как вообще это делается?))
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Обновление программы
Подскажите пожалуйста, как можно сделать обновление программы с сервера, version.tvt и .exe лежит.

Обновление программы
Написал код: procedure updater; var m: TMemoryStream; begin Application.ProcessMessages;.

Обновление программы, версия
Ребят как можно реализовать так, чтобы рядом не было файлика типа ver.txt, а все было прямо в.

Авто обновление программы
Допустим я с помощью get запроса получил ссылку с хостинга,как мне её скачать и заменить на текущую.

Native x86

Эксперт Hardware

5333 / 3138 / 905
Регистрация: 13.02.2013
Сообщений: 10,030

Лучший ответ

Сообщение было отмечено vino0s как решение

Решение

ЦитатаСообщение от vino0s Посмотреть сообщение

Как его скачать программой
См. TIdHTTPClient
5707 / 4467 / 1411
Регистрация: 14.04.2014
Сообщений: 19,962
Записей в блоге: 20

решение №1
php скрипт вполне может посмотреть какая дата у файла и вернуть вам и ее и версию и еще массу всего в том виде, который вы придумаете
решение №2
положить рядом еще один файл, где будет написано все то же самое, и скачивать, его

Регистрация: 26.03.2014
Сообщений: 400

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

ЦитатаСообщение от krapotkin Посмотреть сообщение

php скрипт

это как альтернатива Базы данных? Думаю ваш вариант гораздо правильнее! Как делать именно скачивание с заменой в самой делфи? На крайний случай я могу даже открывать эту страницу в самой оболочке: тут вопрос тогда такой — скрипт сможет скачать файл с заменой?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
function DownloadFile(aUrl: string; aFileName: string): boolean; var AStream: TMemoryStream; begin AStream := TMemoryStream.Create; try aIdHTTP.Get(aUrl, AStream); aStream.SaveToFile(aFileName); Result := True; except Result := False; Application.HandleException(Self); end; AStream.Free; end;

Вот нашел скачивание. В принципе как решение норм.
Но про php скрипт пожалуйста больше инфы)

ЦитатаСообщение от krapotkin Посмотреть сообщение

php скрипт
Добавлено через 27 минут

ЦитатаСообщение от vino0s Посмотреть сообщение

DownloadFile

Скачивает с заменой))

Добавлено через 1 минуту
Скачать файл:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
function TForm1.DownloadFile(aIdHTTP: TIdHTTP; aUrl: string; aFileName: string): boolean; var AStream: TMemoryStream; begin AStream := TMemoryStream.Create; try aIdHTTP.Get(aUrl, AStream); aStream.SaveToFile(aFileName); Result := True; except Result := False; Application.HandleException(Self); end; AStream.Free; end;

Открыть файл:

1 2 3 4 5
function ExecuteFile(const FileName, Params, DefaultDir: string; ShowCmd: Integer): THandle; begin Result := ShellExecute(Application.MainForm.Handle, nil, PChar(FileName), PChar(Params), PChar(DefaultDir), ShowCmd); end;

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

1) Вообще — это нормально делать так обновление?
2) И как всё таки сделать скачивание файла file.exe в момент работы файла file.exe ?

пофигист широкого профиля
4721 / 3156 / 858
Регистрация: 15.07.2013
Сообщений: 18,186

ЦитатаСообщение от vino0s Посмотреть сообщение

Вообще — это нормально делать так обновление?

А вообще. О какой программе идёт речь? Хотя бы в общих чертах озвучьте.
Если эта программа уже существует, конечно.

5707 / 4467 / 1411
Регистрация: 14.04.2014
Сообщений: 19,962
Записей в блоге: 20

если раскрывать тему подробнее, то «программа» на самом деле это обычно целый набор файлов, каждый из которых может обновиться, поэтому апдейтер обычно считывает список файлов с датами и / или версиями и сравнивает с тем, что имеется на месте. после этого файлы скачиваются на клиента и оригиналы заменяются новыми копиями
т.к. заменить exe «сам из себя» не получается, то мы должны либо иметь отдельный updater либо создавать bat файл, запускать его и выходить из программы. дальше bat все обновляет и запускает новую копию

про php
если вы пишете http://myserver.ru/updates/file1.txt
то на самом деле ваш запрос попадает на web-сервер myserver.ru с просьбой предоставить ответ на запрос ресурса /updates/file1,txt
веб сервер может сделать с этим запросом все что угодно в зависимости от настроек
самое простое — посмотреть в папку updates и переслать вам в ответ file1.txt
но это совершенно необязательно

если сервер настроен на выполнение скриптов (любых вообще, в том числе php)
то в скрипте может быть написано
при запросе «updates/file1.txt» срочно послать email директору ЦРУ
а может быть
просмотреть все файлы в папке updates и выслать текст, содержащий их даты и размер
при этом никакого файла file1.txt нет не было и не будет никогда

чаще всего при простых настройках веб сервер NGINX или Apache при запросе xxxxxxx.php запускает обработчик скриптов php, который и возвращает текст ответа.

php достаточно простой язык, и несколько строчек для решения вашей задачи вы вполне сможете написать
но это уже выходит за рамки раздела Delphi

Регистрация: 26.03.2014
Сообщений: 400

Теперь более менее понятно: резюмирую: Я смогу сделать так? Пользователь по кнопке «Войти» в Оболочке или при запуске Оболочки каким-то образом (TWebBrowser ?) отправляется на определенную ссылку, с параметрами свежести его файлов, там обрабатывается скрипт и если есть свежие файлы, то происходит их скачивание, прям куда надо, а не в папку загрузки?
=)

5707 / 4467 / 1411
Регистрация: 14.04.2014
Сообщений: 19,962
Записей в блоге: 20
не надо WebBrowser
надо TidHTTP
или THttpClient, если делфи более менее свежая
Регистрация: 26.03.2014
Сообщений: 400
Ну тогда может сейчас все получится проще:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
function TForm1.DownloadFile(aIdHTTP: TIdHTTP; aUrl: string; aFileName: string): boolean; var AStream: TMemoryStream; begin AStream := TMemoryStream.Create; try aIdHTTP.Get(aUrl, AStream); aStream.SaveToFile(aFileName); Result := True; except Result := False; Application.HandleException(Self); end; AStream.Free; end;

Вот выше я писал, скачивает файл. Могу ли я уже здесь определить свежесть файла? Не выходя из делфи так сказать? )

Добавлено через 1 минуту

ЦитатаСообщение от krapotkin Посмотреть сообщение

Как сделать автоматическое обновление программы на новую версию?

У меня программа автоматически проверяется на версию. Возможно ли такое, чтоб в случае новой версии она автоматически скачивала бы новую и заменялась на неё? Если да, то как? Подскажите, пожалуйста.

Отслеживать
371 1 1 золотой знак 5 5 серебряных знаков 13 13 бронзовых знаков
задан 9 июл 2012 в 10:07
9,204 4 4 золотых знака 24 24 серебряных знака 47 47 бронзовых знаков

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Это, конечно же, возможно. Раз это вопрос новичка в Delphi, то постараюсь ответить доходчиво, как такое реализовать.

  • Для начала вам нужно завести хостинг или аккаунт на каком-л. облачном хранилище. Это необходимо для того, чтобы программа имела в сети «свой уголок», откуда могла бы проверять новую версию и самообновляться в случае появления новой. Лично я вам советую заводить именно хостинг, нежели пользоваться услугами «облаков», так как у этих облачных хранилищ очень ограничена пропускная способность канала, а если пользователей у вашей «программы» будет очень много, то аккаунт забанят из-за большого трафика. Пользуйтесь хостингом.
  • Далее вам надо создать на этом хостинге файлик, в котором будет лежать текущая(последняя) версия вашего «продукта». Например, 1.72.. И еще, конечно же, на хостинг надо поместить «свежую» версию вашего «продукта», чтобы можно было её скачать.
  • Далее в самой программе вы должны каждый раз при запуске проверять версию из того файла на хостинге, который содержит версию. В самой программе, естественно, должна быть константа, содержащая номер версии программы. Это можно сделать с помощью TIdHttp с панели IndyClients. Если версия больше, то качаем новую(расположена на нашем хостинге.
  • Качать новую версию лучше всего из «вспомогательной» програмки, прилагаемой к основному файлу вашего «приложения». В случае обнаружения новой версии запускаем updator и он уже все сам сделает.
  • Что будет делать апдейтор? Он, в случае обнаружения новой версии, будет закрывать основное «приложение», скачивать новое(Как? Это вам должно быть известно.) и копировать его вместо старого. Скачанный файл потом надо будет удалить.

Отслеживать
371 1 1 золотой знак 5 5 серебряных знаков 13 13 бронзовых знаков
ответ дан 9 июл 2012 в 10:21
13.6k 13 13 золотых знаков 62 62 серебряных знака 122 122 бронзовых знака

@Yura Ivanov, ну большинство этих «вещиц» можно сделать «динамически изменяемыми». Так, например, можно на хостинге создать файл параметров, где будет вся инфа по подключению к БД, прочим серверам, если надо и т.д. — А вообще, раз уж так может понадобиться обновлять апдейтор, то можно просто «схитрить» и сделать «взаимное обновление». То есть, например, при надобности основное приложение обновит тот апдейтор, а тот, в свою очередь, будет обновлять само приложение. Вариант здесь не один, на самом деле =)

9 июл 2012 в 11:42

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

9 июл 2012 в 11:50

Судя по вопросам, ТС пишет не вирус, а что-то типа «калькулятор», но со всеми возможными и невозможными примочками — и автообновление и прятание в трей, скоро появятся вопросы про круглую форму/кнопку, таскание формы за любую область окна и т.д. В итоге программа будет скорее всего бесполезной, но в ней будет все остальное.

9 июл 2012 в 12:11
@Хэшкод, Опять кто-то мои комментарии потер. О чем речь теперь можно только догадываться.
11 июл 2012 в 10:50

@Yura Ivanov, этим занимается Asen, потому как критика сильно уязвляет нашего специалиста по безопасности. Например, нельзя смеяться над след. волшебной фразой: > Mozilla FireFox, например, умеет обходить UAC, используя один из его многочисленных багов — переполнение буфера

Delphi как программе обновить саму себя

Как правильно выполнить перезапуск программы?
Цель такая: нужно обновить программу.
Алгоритм такой: программа скачивает обновление, проверяет на валидность, обозначает как-то что доступно обновление (например пишет ключ в реестр) и перезапускает себя (как firefox, например). При запуске программа проверяет ключ в реестре, и, если доступно обновление — заменяет файлы новыми и дальше работает в штатном режиме.

Остается два узких места: как обновить сам exe-шник?
и как организовать перезагрузку?

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

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

Re: Перезапуск программы, обновление программы

От: misha_irpen
Дата: 28.04.08 11:29
Оценка:

Системы семейства NT позволяют переименовать исполняемый файл даже если он сейчас загружен. Можно плясать от этого (простейший способ потребует записи ключика в RunOnce и перезагрузки машины).

А вообще я бы написал маленький екзешничек без использования VCL, сжал его UPX-ом и вложил в ресурс оновного исполняемого файла программы (добавит всего килобайт 10 к размеру). После загрузки обновления, отпочковываем от себя этот файлик, запускаем его с нужными параметрами, а сами завершаемся. Файлик же, дожидается нашего завершения, выполняет обновление всего что нужно, снова запускает программу с «секретным» параметром и тихо завершается. Программа при запуске с этим параметром первым делом дожидается завершения загрузчика, удаляет его и дальше работает как обычно.

Можно ничего не прятать, а просто держать этот загрузчик все время в каталоге программы, но тогда его самого обновить будет сложнее (это должна будет сделать сама программа перед его запуском).

Re: Перезапуск программы, обновление программы

От: BDEsoft
Дата: 28.04.08 11:29
Оценка:

Здравствуйте, bsigr, Вы писали:

Я бы сделал следующим образом.
Первый exe (лоадер) запускает основную программу, и не закрывается, ожидает сообщения. Сама программа, уловив, что нужно обновление, выдает сообщение об этом, посялает сообщение лоадеру (типа мол нужно обновить) и сама закрывается. Лоадер, же скачивает обновления и заного запускает программу. Просто и ясно.

Re: Перезапуск программы, обновление программы

От: Rius
Дата: 28.04.08 14:38
Оценка:

Здравствуйте, bsigr, Вы писали:

B>Как правильно выполнить перезапуск программы?
B>Цель такая: нужно обновить программу.
B>Алгоритм такой: программа скачивает обновление, проверяет на валидность, обозначает как-то что доступно обновление (например пишет ключ в реестр) и перезапускает себя (как firefox, например). При запуске программа проверяет ключ в реестре, и, если доступно обновление — заменяет файлы новыми и дальше работает в штатном режиме.

B>Остается два узких места: как обновить сам exe-шник?
B>и как организовать перезагрузку?

B>но если первую проблему можно как-то обойти: сам exe-шник представляет из себя лоадер, который умеет обновлять основную программу и загружать ее и сам не обновляется. А во-вторых, его можно переименовать во время работы и записать новую версию (не знаю только всегда и везде ли это будет работать?),
B>то со второй что-то никак не справиться.

B>Подскажите пожалуйста, как решить данную проблему или укажите как правильно делают обновления программ. Не обязательно подробно объяснять, главное дать пинок в нужном направлении
B>Заранее благодарен.
У меня работало так:

прога (exe), запускаясь, смотрит из какого каталога она запущена или в каком домене. если не из временного и не в домене, то копирует свой exe во временный каталог и запускает его, сама закрывается (это безоконная прога).

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

загрузившись в домене, прога создаёт класс, создающий уже основное окно приложения из dll. таким образом exe’шнику не требуются остальные dll до этого момента, он имеет минимум кода и малый объём.
этот класс также ждёт здесь выхода из программы, после выхода проверяет, не установлен ли флаг перезапуска программы, и если установлен — вызывает функцию Application.Restart().

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

p.s. что-то здесь явно можно упростить.

Delphi как программе обновить саму себя

Евгений Бабенко
дата публикации 31-05-2005 04:41

Обновление программы самой программой Условия работы: Локальная сеть(Win2000, WinNt4), сервер СУБД (Oracle, SQL Server . ), множество клиентов, работающих с базой. Постановка задачи: Автоматическое обновление программы клиента при внесении каких либо изменений в эти программы.

У администраторов — программистов, которые впервые сталкиваются с подобной проблемой, первое желание — заставить программу саму себя обновлять. Это законное желание. Нет промежуточного программного обеспечения, которое, в свою очередь, необходимо администрировать. Проблема в том, что программа не может удалить сама себя. В свое время, столкнувшись с этой проблемой, мы у себя на предприятии решили эту проблему стандартным способом — скриптами. А недавно я обнаружил интересную особенность ОСей и сделал это способом, максимально приближенным к «идеалу».

В обоих случаях, для ускорения закачки файла с сервера, программы были перекомпилированы с использование Runtime Packages и после этого упакованы упаковщиком Exe — файлов. В итоге размеры полученных файлов не превышал 300 К.

Способ №1. Обновление с помощью VB скрипта.

Создаем на сервере папку с доступом для группы пользователей, использующих наши программы. Например \\Server1\ExeLib$ (приставка с $ позволит скрыть папку из сетевого окружения. Для того, чтобы не привязываться к конкретному имени сервера, мы создали линк с помощью Distributed File System (Dfs) : \\VirtualServer\ExeLib. Теперь физическое местоположение программ не имеет значение. При падении сервера мы просто копируем папку на другой сервер и делаем соответствующие изменения в Active Directory. Или это делает наш администратор домена. В папку ExeLib складываем exe-файлы. Там же создаем папку VBS, в которую поместим наши скрипты. Для каждого exe — файла свой скрипт. Вот пример скрипта:

Dim fs, f1, f2 Dim WshShell const SPatch = "\\VirtualServer\ExeLib\" const DPatch = "C:\Client\" const SExe = "Prog1.Exe" Set fs = CreateObject("Scripting.FileSystemObject") Set f1 = fs.getfile(SPatch+SExe) Set WshShell = WScript.CreateObject("WScript.Shell") If fs.FileExists(DPatch+SExe) Then Set f2 = fs.getfile(DPatch+SExe) If f1.DateLastModified > f2.DateLastModified Then fs.CopyFile SPatch+SExe, DPatch, True End If Else fs.CopyFile SPatch+SExe, DPatch, True End If WshShell.Run (DPatch+SExe)

Скрипт проверяет дату последнего изменения exe — файла. Если файл локально не существует или на сервере лежит более новый файл, скрипт копирует файл на клиентский компьютер. После этого программа запускается на выполнение. На клиенте все наши программы должны лежать в одной папке. Желательно на диске C:, т.к. в домене могут встречаться машины с дисками малого размера. Для WinNt4 необходимо проверить наличие WScript.exe. У клиентов должны быть права на запуск WScript.exe. Скрипт запускается из папки \\VirtualServer\ExeLib\VBS, т.е. сервера. Это позволит нам легко модифицировать скрипт и не заботиться об обновлении самого скрипта. Например, добавить код для вызова другого скрипта, в котором мы прописываем обновление bpl — файлов.

Способ №2. Обновление программы самой программой.

Если вы запустите программу и после этого попытаетесь переименовать exe — файл, никаких возражений со стороны операционный системы не последует. Программа после такой операции продолжает работать без видимых проблем. Я, во всяко случае, проблем не обнаружил. Этот факт и используется в коде, приведенном ниже.

unit uUpdateApp; interface uses Classes, Windows, SysUtils, Forms; type TUpdateApp=class(TThread) protected procedure Execute; override; end; implementation procedure TUpdateApp.Execute; var iFileName: String; iFileNameBak: String; iFileNameR: String; iLDate, iRDate: TDateTime; begin Sleep(100); iFileName:=Application.ExeName; iFileNameBak:=iFileName+'.bak'; if FileExists(iFileNameBak) then DeleteFile(iFileNameBak); if FileExists(iFileNameBak+'1') then DeleteFile(iFileNameBak+'1'); iFileNameR:='\\VirtualServer\ExeLib\+ExtractFileName(iFileName); if not FileExists(iFileNameR) then Exit; iLDate:=FileDateToDateTime(FileAge(iFileName)); iRDate:=FileDateToDateTime(FileAge(iFileNameR)); if iLDate>=iRDate then Exit; if not CopyFile(PChar(iFileNameR),PChar(iFileNameBak),false) then Exit; Sleep(1000); if not MoveFile(PChar(iFileName),PChar(iFileNameBak+'1')) then Exit; Sleep(100); if not MoveFile(PChar(iFileNameBak),PChar(iFileName)) then Exit; Sleep(100); if not MoveFile(PChar(iFileNameBak+'1'),PChar(iFileNameBak)) then Exit; end; initialization TUpdateApp.Create(false); end.

  1. Проверяем наличие bak файла, который мог остаться от предыдущего обновления и если находим — удаляем.
  2. Сравниваем дату изменения локального файла и файла, находящегося на сервере.
  3. Если необходимо обновление — копируем файл с сервера в файл «bak1». Еще один промежуточный файл используется для уменьшения вероятности нарваться на сбой в программе, когда у нас не окажется в папке файла с оригинальным названием.
    1. Переименовываем оригинал в файл с расширением «bak» .
    2. Восстанавливаем оригинал из файла «bak1»

    Далее — на любителя. Можно попытаться предупредить пользователя и заставить его перезапустить программу. Или оставить все, как есть. Этот способ проверен на WinNt4 и Win2000. Прав особых пользователям не надо.

    Обсуждение материала [ 29-08-2008 07:23 ] 21 сообщение

    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *