Форум » [x]Harbour » Автообновление EXE-шника и контроль версий » Ответить

Автообновление EXE-шника и контроль версий

Softlog86: Добрый день всем ! Не нашел поиском - буду спрашивать напрямую . Нужно реализовать автообновление EXE-шника .... Есть свой сайт в Интернете - к нему могу приконнектиться по FTP(из программы на Harbour-Minigui) . Хочется использовать VERSION-нумерацию и сравнивать текущую версию с той что на сервере в сети . Если необходимо обновиться - программа как-то должна это делать ... Если есть готовые идеи - буду рад их рассмотреть. Заранее спасибо !

Ответов - 4

Andrey: http://clipper.borda.ru/?1-4-20-00000656-000-0-0-1330450165 http://clipper.borda.ru/?1-1-20-00000307-000-0-0-1320091437

PSP: 1. Запускаешь в проге отдельный поток, который периодически проверяет наличие обновления на сервере. 2. Если обновление найдено, оно сначала копируется на локальный компьютер. Модулей может быть несколько. Например, главная программа, файлы отчетов, dll-ки. 3. После того, как все нужные файлы скопированы, пользователю выдается предупреждение. 4. Дальше уже по вкусу: можно пользователя насильно заставить завершить работу, можно подождать, когда он закроет программу сам. 5. При закрытии программы запускается внешнее приложение - updater, который замещает старые файлы новыми. 6. Также не лишним будет предусмотреть автоматическое изменение структуры dbf-файлов. Но тут есть ньюансы...

Петр: А вы точно Harbour+Minigui используете? Что-то не похоже. Вот если бы вы действительно использовали Minigui, то знали бы, что в IDE есть не то чтобы какая-то идея, а и реализация обновления. А так навскидку. Есть сервер на сервере файл, version.list, типа [{ver:1.00.10,file:my_cool_app_01.rar,tstamp:2012-03-22T12:12:01+008},{ver:1.03.04,file:my_cool_app_01.rar,tstamp:2012-04-22T12:12:01+008}] т.е. понятно, формат hash конвертированый в json, для секюрити применить sha1, base64 и упаковать gz или bz2 Дальше, решила ваша программа проверить есть ли обновление. По примеру \MiniGUI\SAMPLES\BASIC\httpget скачиваем с сайта, распаковываем, по ходу проверяя целосноcть, извлекаем данные, сравниваем с тем, что есть, ломимся по ftp, забираем нужный файл и т.д.


Andrey: Можно еще и по другому, но принцип все равно такой же. На Web-сервере размещаем обновление программы (просто закачивает по ftp zip-файл обновления), Web-сервер создает динамический файл с последним номером обновления программы. Юзер запускает свою программу, получает ТЕКУЩИЙ номер версии, проверяем доступ в интернет ( пример \MiniGUI\SAMPLES\Advanced\INET_CHECKER) далее программа посылает запрос Web-серверу, Web-сервер отвечает какая есть у него версия программы, далее программа сравнивает Текущую версию программы с ответом Web-сервера и принимает решение на скачку. Если есть новая программа, то запускает программу на МиниГуи скачки обновления и выход из программы. Скачка файла с сайта см. пример \MiniGUI\SAMPLES\Advanced\Downloader туда еще нужно встроить проверку на МД5. Функции из МиниГуи перевер в хHarbour. Часть функций по запросу к Web-серверу: /////////////////////////////////////////////////////////// // Проверка доступности версии программы в Инете FUNCTION CheckVersionХХХХХ(nVerNetLocal,nPort) LOCAL cBuffer, cRequest, cResponse, nBytes, pSocket LOCAL nTime1 := SECONDS(), nTime2, nSeconds LOCAL RegStatus := "<status>([^<]+)<\/status>" LOCAL RegMessage := "<message>([^<]+)<\/message>" LOCAL RegVersion := "<version>([^<]+)<\/version>" LOCAL RegLink := "<link>([^<]+)<\/link>" LOCAL cStatus,cVersion,cLink,cMessage LOCAL aRet := { "","","" } LOCAL cType IF nVerNetLocal == 1 cType := "net" ELSEIF nVerNetLocal == 2 cType := "local" ENDIF // send HTTP request to server cRequest := "GET /check?type="+cType+" HTTP/1.1" + CRLF + ; "Host: "+SITE_URL + CRLF + ; "User-Agent: ХХХХХUpdater (Version 0.0.5)" + CRLF + ; "Connection: close" + CRLF + ; CRLF cResponse := SendPacket(SITE_URL,cRequest,nPort) MyALERT(";Заголовки запроса: ") MyALERT(cRequest) MyALERT(";Заголовки ответа:") MyALERT(cResponse) IF cResponse HAS RegStatus .AND. cResponse HAS RegMessage cStatus := HB_RegEx( RegStatus,cResponse) cMessage := HB_RegEx(RegMessage,cResponse) MyALERT("Найдено поле <status>: "+cStatus[1]) MyALERT("Найдено поле <message>: "+cMessage[1])    IF VAL(cStatus[2])==200 IF cResponse HAS RegVersion .AND. cResponse HAS RegLink cVersion := HB_RegEx(RegVersion,cResponse) aRet[2] := cVersion[2] // Номер версии на сервере MyALERT("Найден номер версии <version>: "+cVersion[2]) cLink := HB_RegEx(RegLink,cResponse) cLink[2] := StrTran(cLink[2],".zip","") aRet[3] := cLink[2] // Ссылка на файл MyALERT("Найдена ссылка на файл <link>: "+cLink[2]) ELSE aRet[1] := "Отсутствует номер версии или ссылка на файл на САЙТе !" ENDIF ELSE aRet[1] := "Внутренняя ошибка САЙТа !;Номер ошибки:"+cStatus[2]+";САЙТ сообщает: "+cMessage[2] ENDIF ELSE aRet[1] := "Не удаётся прочитать ответ САЙТа !" ENDIF MyALERT("Сообщение об ошибке: "+aRet[1]) RETURN aRet /////////////////////////////////////////////////////////// ////// Общение с Веб-сервером FUNCTION SendPacket(cURL,cRequest,nPort) LOCAL cBuffer, cResponse, nBytes, pSocket LOCAL nTime1, nTime2 // initialize sockets system and connect to server INetInit() pSocket := INetConnect( cUrl,nPort ) IF INetErrorCode( pSocket ) <> 0 ALERT( "Ссылка: "+cURL+";;Socket error:;"+ INetErrorDesc( pSocket ) + ";" ) INetCleanUp() ENDIF nBytes := INetSend( pSocket, cRequest ) cBuffer := Space(1024) cResponse:= "" // get HTTP response from server DO WHILE ( nBytes > 0 ) nBytes := INetRecv( pSocket, @cBuffer ) cResponse += Left( cBuffer, nBytes ) cBuffer := Space(1024) ENDDO // disconnect and cleanup memory INetClose( pSocket ) INetCleanUp() RETURN cResponse /////////////////////////////////////////////////////// FUNCTION WAITRUN( cRun ) Local hIn, hOut, nRet, hProc // "Launching process", cProc hProc := HB_OpenProcess( cRun , @hIn, @hOut, @hOut ) // "Reading output" // "Waiting for process termination" nRet := HB_ProcessValue( hProc ) FClose( hProc ) FClose( hIn ) FClose( hOut ) Return nRet /////////////////////////////////////////////////////////// #define DC_CALL_STD 0x0020 #define INTERNET_CONNECTION_MODEM 1 #define INTERNET_CONNECTION_LAN 2 #define INTERNET_CONNECTION_PROXY 4 #define INTERNET_RAS_INSTALLED 16 #define INTERNET_CONNECTION_OFFLINE 32 #define INTERNET_CONNECTION_CONFIGURED 64 // Flag for InternetCheckConnection #define FLAG_ICC_FORCE_CONNECTION 1 FUNCTION IsConnectedInet() local nFlags := 0 local lRet := .f. if DllCall( "WININET.DLL", DC_CALL_STD, "InternetGetConnectedState", @nFlags, 0 ) == 1 if DllCall( "WININET.DLL", DC_CALL_STD, "InternetCheckConnection", "http://www.google.com", FLAG_ICC_FORCE_CONNECTION, 0 ) == 1 lRet := .t. endif endif Return lRet



полная версия страницы