Форум » GUI » ?Консольная утилита на базе МИниГУИ дистрибутива » Ответить

?Консольная утилита на базе МИниГУИ дистрибутива

SadStar55: попробовал консольную утилиту сделать на Харборе из дистрибутива МиниГУИ вот такой строкой (пути в compile.bat исправлены) call D:\MiniGUI217\BATCH\compile.bat GetShipPosition /C /E /P /ND выдает ошибки на следующие строки (других там почти нет) SET CODEPAGE TO RUSSIAN Error E0030 Syntax error "syntax error at 'CODEPAGE'" hb_SetCodepage( "RU1251" ) Error: Unresolved external '_HB_FUN_HB_SETCODEPAGE' GetExeFileName() Error: Unresolved external '_HB_FUN_GETEXEFILENAME' И кучу предупреждений например такое GetShipPosition.prg(20) Warning W0001 Ambiguous reference 'CINIFILE' хотя в строке 7 есть public cIniFile а в строке 20 cIniFile:=GetExeFileName() или такое GetShipPosition.prg(24) Warning W0001 Ambiguous reference 'GETLIST' на строку 24 @ 2,10 say "?: press any key ..." get a Каких-то инклюдов и либов не находит?

Ответов - 16

AlexMyr: SadStar55 пишет: попробовал консольную утилиту сделать на Харборе из дистрибутива МиниГУИ вот такой строкой (пути в compile.bat исправлены) Для этого есть hbmk2 и раздел harbour. И меня интересует, почему многие уверенны что harbour это minigui?

alkresin: SadStar55 пишет: SET CODEPAGE TO RUSSIAN Error E0030 Syntax error "syntax error at 'CODEPAGE'" Наверное, эта команда определена в каком-то include файле от Минигуи, в Харборе такой нет. hb_SetCodepage( "RU1251" ) Эта функция теперь (c 3 версии ) называется по-другому: hb_cdpSelect() GetExeFileName() Error: Unresolved external '_HB_FUN_GETEXEFILENAME' Такой функции в Харборе нет, может, она из Минигуи. GetShipPosition.prg(20) Warning W0001 Ambiguous reference 'CINIFILE' хотя в строке 7 есть public cIniFile а в строке 20 cIniFile:=GetExeFileName() Чтобы не было таких предупреждений, надо MEMVAR еще объявлять, или префих m-> ставить, то же самое и в Клиппере было...

SadStar55: первый мой косяк - не вставил строку #include <minigui.ch> исправил - исчезла ругань компилятора на SET CODEPAGE TO RUSSIAN Но ругань линковщика осталась на '_HB_FUN_HB_SETCODEPAGE' '_HB_FUN_GETEXEFILENAME' в каких либах они находятся? AlexMyr пишет: И меня интересует, почему многие уверенны что harbour это minigui? Откуда вы это взяли? MiniGUI это Харбор+.... т.к. МиниГУИ без Харбора не бывает, а наоборот бывает. В Compile.bat из дистрибутива МиниГУИ есть параметр /С = Create console EXE чем я и пытаюсь попользоваться.


AlexMyr: SadStar55 пишет: В Compile.bat из дистрибутива МиниГУИ есть параметр /С = Create console EXE чем я и пытаюсь попользоваться. используйте просто harbour и просто утилиту hbmk2.

gustow: SadStar55 пишет: В Compile.bat из дистрибутива МиниГУИ есть параметр /С = Create console EXE чем я и пытаюсь попользоваться. Мне помогало (при создании консольного EXE, но в Harbour+MiniGUI) заменить "/С" на "/CG" (console mixed mode).

AlexMyr: SadStar55 пишет: AlexMyr пишет: цитата: И меня интересует, почему многие уверенны что harbour это minigui? Откуда вы это взяли? Из таких сообщений как это. SadStar55 пишет: В Compile.bat из дистрибутива МиниГУИ есть параметр /С = Create console EXE чем я и пытаюсь попользоваться. Запустите harbour.exe, Вы найдете там такой ключ? Правильно, НЕТ. Все это реализация minigui.

SadStar55: AlexMyr пишет: Запустите harbour.exe, Вы найдете там такой ключ? Правильно, НЕТ. Все это реализация minigui. harbour.exe делает готовые EXE-шки?

gustow: SadStar55 , не попробовали делать консольку с ключом "/CG" вместо "/C"? (в MiniGUI\Batch\Compile.bat "/CG - Create mixed console and GUI EXE"; см.также MiniGUI\Samples\Basic\MixedMode\Compile.bat)

AlexMyr: SadStar55 пишет: harbour.exe делает готовые EXE-шки? Нет.

Andrey: AlexMyr пишет: И меня интересует, почему многие уверенны что harbour это minigui? В этом многие уверены ! Из-за того что нет описания в 5-6 строчек, у нас на главной странице ! Может там дать там комментарии, что такое Harbour и MiniGui - прямо на главной странице ? Или ссылку дать: [x]Harbour - подробнее читайте http://ru.wikipedia.org/wiki/Harbour GUI в Clipper-е - подробнее читайте про МиниГуи здесь ! А кстати где на русском языке прочитать про МиниГуи ?

SadStar55: gustow пишет: SadStar55 , не попробовали делать консольку с ключом "/CG" вместо "/C"? (в MiniGUI\Batch\Compile.bat "/CG - Create mixed console and GUI EXE"; см.также MiniGUI\Samples\Basic\MixedMode\Compile.bat) Так и сделал по первому вашему совету. Работает нужным образом. Спасибо.

SadStar55: Что получилось в результате. (может кому пригодится) Консольная утилита. Запускается шедьюлером на сервере. Можно запустить и вручную на раб.столе в "визуальном режиме". Загружает из интернета заданную ХТМЛ-страницу на которой каждый день обновляются ссылки на некоторые файлы нужные одному отделу. Находит эти ссылки. Загружает файлы немного переделывая имена. Это сделано по заданию админа т.к. существуют жесткие ограничения на доступ в Сеть. А фильтрануть средствами шлюза админ не смог. Функционал закачки взят отсюда http://clipper.borda.ru/?1-1-0-00000307-000-0-0-1320091437 Спасибо SkyNET-у только обрезал ГУЕвый "обвес" Код не идеален. Видны следы последовательной разработки и отладки. Т.е. можно еще оптимизировать. [pre2] #include <minigui.ch> #define CRLF HB_OsNewLine() REQUEST HB_CODEPAGE_RU1251 //REQUEST HB_CODEPAGE_RUWIN FUNCTION Main() local t:='', a, aFiles:={} public cIniFile, cLogFile, nLogMax:=1024*50 public cTargetFolder:="" public cURL:="" PUBLIC nBytesDownloaded := 0 SET DELETED ON SET DATE GERMAN SET CENTURY ON SET EXCLUSIVE off //SET LANGUAGE TO RUSSIAN //=> _HMG_LANG_ID := ' ' ; REQUEST HB_LANG_RUWIN ; HB_LANGSELECT( "RUWIN" ) ; InitMessages() //HB_LANGSELECT( "RUWIN" ) SET CODEPAGE TO RUSSIAN //=> REQUEST HB_CODEPAGE_RU1251 ; HB_SETCODEPAGE( "RU1251" ) hb_SetCodepage( "RU1251" ) cIniFile:=GetExeFileName() cIniFile:=substr(cIniFile,1,rAt('.',cIniFile))+'ini' cLogFile:=substr(cIniFile,1,rAt('.',cIniFile))+'log' AddToLog( replicate("-",20)) AddToLog( "Start" ) //начало процесса в лог BEGIN INI FILE cIniFile GET cURL SECTION "OldParameters" ENTRY "cUrl" DEFAULT '' GET cTargetFolder SECTION "OldParameters" ENTRY "cTargetFolder" DEFAULT '' END INI ? "cURL="+cURL ? "cTargetFolder="+cTargetFolder AddToLog("cURL="+cURL ) AddToLog("cTargetFolder="+cTargetFolder ) if empty(cURL); AddToLog("Не задан URL"); return Nil; endif if empty(cTargetFolder); AddToLog("Не задана папка-приемник"); return Nil; endif if !hb_DirExists(cTargetFolder); AddToLog("Папка-приемник <"+cTargetFolder+"> не найдена"); return Nil; endif //--------------- //получить страницу и извлечь список файлов //--------------- oSock := THttp():New() //oSock:SetReceiveTimeout( 5000 ) //5sec if !oSock:Connect( cURL, 80 ); AddToLog("Облом соединения с сайтом"); return Nil; endif txt := oSock:Get('/') if empty(txt); AddToLog("Ответ - пустой"); return Nil; endif //--------------------- tg1:="<li class='pdf'>" tg2:="</li>" pos1:=0 do while .t. pos1:=hb_at(tg1,txt,pos1) // искать tg1 в txt начиная с pos1 if pos1=0; exit; endif // конец поискам pos2:=hb_at(tg2,txt,pos1) // искать tg2 в txt начиная с pos1 if pos2=0; exit; endif // конец поискам - ошибка структуры файла pos3:=hb_at(">",txt,pos1+len(tg1)) // конец тэга <a href= ....... > if pos3>0 s:=substr(txt,pos1+len(tg1),pos3-pos1-len(tg1)) //убрать <a href= s:=substr(s,9) s:="/"+substr(s,2,len(s)-2) aAdd(aFiles,s) endif pos1:=pos2 enddo oSock:Close() //Найденые имена файлов for i:=1 to len(aFiles) ? aFiles[ i] AddToLog(aFiles[ i]) next //-------------------------- //получить файлы SITE_URL:=cURL if len(aFiles)>0 for i:=1 to len(aFiles) FILE_URL:=aFiles[ i] SavedFile:=substr(FILE_URL,rat("/",FILE_URL)+1) //изменение имени с SCHEDULE-22022013.pdf на 20130222-SCHEDULE.pdf и т.п. t:=token(SavedFile,,2) t:=right(t,4)+substr(t,3,2)+left(t,2) // ddmmyyyy => yyyymmdd t:=t+"-"+token(SavedFile,,1)+right(SavedFile,4) //-------------------------------------------------------------------- SavedFile:=cTargetFolder+t cRequest := "GET " + FILE_URL + " HTTP/1.1" + CRLF + ; "Host: "+SITE_URL + CRLF + ; "User-Agent: Mozilla/5.0" + CRLF + ; "Connection: close" + CRLF + ; CRLF cResponse := SendPacket(SITE_URL,cRequest,80,SavedFile) next endif //-------------------------- //short-cut the LogFile to nLogMax if File(cLogFile) nLogSize:=FILESIZE(cLogFile) if nLogSize>nLogMax //short-cut the LogFile n:=nLogSize-nLogMax txt:=MEMOREAD(cLogFile) p:=hb_at(CRLF,txt,n) if p>0 MEMOWRIT(cLogFile, substr(txt,p)) ? "short-cut the LogFile to max "+str(nLogMax)+"B OK" AddToLog("short-cut the LogFile to max "+alltrim(str(nLogMax))+"B OK" ) endif endif endif AddToLog("End !!!"+CRLF ) RETURN NIL //----------------------------------- function AddToLog(s) //добавляет сообщение в Лог-файл set alternate to (cLogFile) additive set alternate on SET CONSOLE OFF ?? HB_TSTOSTR(HB_DATETIME())+': '+ s + hb_eol() set alternate off set alternate to SET CONSOLE ON /* local fh:=if( file(cLogFile), ; FOpen( cLogFile, FO_DENYNONE + FO_WRITE ), ; hb_FCreate( cLogFile, FC_NORMAL, FO_DENYNONE + FO_WRITE ) ) If Ferror() # 0 Return .f. EndIf FSEEK(fh, 0, FS_END) //встать в конец файла FWrite( fh, HB_TSTOSTR(HB_DATETIME())+': '+ s + hb_eol() ) //записать с таймштампом и концом строки FClose( fh ) */ return .t. //---------------------------- // Функция прямого взаимодействия с сокетами FUNCTION SendPacket(cURL,cRequest,nPort, SavedFile) LOCAL cBuffer, cResponse, nBytes, oSocket, lNoError LOCAL nFile LOCAL nI,cI, nKolvo, cTemp := "", cTempText :="" LOCAL nLen, lHaveLen := .F. // Буфер Загрузки - 4 КилоБайта LOCAL nBuffer := 4096 // Создаём новый сокет-объект oSocket := TSocket():New() // Пытаемя подключиться к серверу lNoError := oSocket:Connect(cUrl,nPort) // При ошибке IF lNoError == .F. AddToLog("No socket Connect to "+cURL) ::oSocket:Close() ELSE nFile := CreateFile(SavedFile) ? SavedFile+" " AddToLog(SavedFile) // Если удалось отправить данные IF oSocket:SendString(cRequest) // Пока истина WHILE .T. // Получаем линию заголовка HTTP cI := oSocket:ReceiveLine() // Если здесь содержится информация о длине IF RAt(LOWER("content-length:"),LOWER(cI)) != 0 // Получаем конечную длину загружаемого файла nLen := Substr(cI,At(": ",cI)+2) nLen := VAL(nLen)+1 // Записываем в глобальную переменную M->nBytesTotal := nLen lHaveLen := .T. ENDIF // Если эта линия последния IF (cI == "") // и если не нашли длину файла IF lHaveLen == .F. AddToLog("Отсутствуют данные о размере загружаемого файла !") ENDIF // ВЫХОДИМ ИЗ ПРОЦЕДУРЫ ЦИКЛА EXIT ENDIF END // Определяем дальнейший способ работы с данными IF lHaveLen == .T. // Если у нас есть длина файла // Получаем все части файла DO WHILE .T. // Получаем очередную часть файла cTemp := oSocket:ReceiveChar(nBuffer) // Записываем фрагмент в файл WriteFile(nFile,cTemp) ?? "#" // Прибавляем к уже скачанному M->nBytesDownloaded += LEN(cTemp) // Если пришёл пустой пакет IF LEN(cTemp) == 0 // И если мы скачали файл (+1 байт) IF M->nBytesDownloaded + 1 >= M->nBytesTotal ELSE // Если произошла ошибка //DownloadError() ENDIF EXIT ENDIF ENDDO ELSE // Если длина файла неизветсна // Получаем весь файл целиком без вопросов cTemp := oSocket:ReceiveString() WriteFile(nFile,cTemp) ENDIF oSocket:Close() CloseFile(nFile) AddToLog("Ok") ENDIF ENDIF RETURN cResponse // Функция создания файла FUNCTION CreateFile(SAVE_NAME) LOCAL nFileHandler // Пытаемся создать файл nFileHandler := FCreate(SAVE_NAME) // Если есть оишбка IF FError() <> 0 AddToLog("Ошибка при создание файла: "+SAVE_NAME+" !") AddToLog(FError()) // Возвращаем значение -1 nFileHandler := -1 ENDIF RETURN nFileHandler // Функция записи в файл, хэндлер принимается в параметрах FUNCTION WriteFile(nFileHandler,cText) LOCAL nSuccess nSuccess := FWrite(nFileHandler,cText) IF nSuccess <> LEN(cText) AddToLog("Ошибка при записи в файл:"+FError()) ENDIF Return nSuccess // Функция закрытия файла по хэндлеру из параметров FUNCTION CloseFile(nFileHandler) LOCAL lClosed lClosed := FClose(nFileHandler) IF lClosed := .F. AddToLog("Ошибка при закрытии файла:"+FError()) ENDIF Return lClosed [/pre2] Инишка выглядит так [pre2] [OldParameters] cUrl=www.ampvanino.ru cTargetFolder="\\Pdc-trb\exchange.box\ShipPosition\"[/pre2] Кусок лог-файла [pre2] 2013-02-26 08:52:48.031: -------------------- 2013-02-26 08:52:48.031: Start 2013-02-26 08:52:48.031: cURL=www.ampvanino.ru 2013-02-26 08:52:48.046: cTargetFolder=\\Pdc-trb\exchange.box\ShipPosition\ 2013-02-26 08:52:48.968: /assets/files/oper2/2013/02/POSITION-26022013.pdf 2013-02-26 08:52:48.968: /assets/files/oper2/2013/02/ICESTATE-25022013.pdf 2013-02-26 08:52:48.968: /assets/files/oper2/2013/02/STEERING-25022013.pdf 2013-02-26 08:52:48.968: /assets/files/oper2/2013/02/SCHEDULE-26022013.pdf 2013-02-26 08:52:49.093: \\Pdc-trb\exchange.box\ShipPosition\20130226-POSITION.pdf 2013-02-26 08:52:51.140: Ok 2013-02-26 08:52:51.250: \\Pdc-trb\exchange.box\ShipPosition\20130225-ICESTATE.pdf 2013-02-26 08:56:09.218: Ok 2013-02-26 08:56:09.343: \\Pdc-trb\exchange.box\ShipPosition\20130225-STEERING.pdf 2013-02-26 08:56:09.375: Ok 2013-02-26 08:56:09.500: \\Pdc-trb\exchange.box\ShipPosition\20130226-SCHEDULE.pdf 2013-02-26 08:56:09.515: Ok 2013-02-26 08:56:09.531: short-cut the LogFile to max 51200B OK 2013-02-26 08:56:09.531: End !!! [/pre2]

gustow: Andrey пишет: где на русском языке прочитать про МиниГуи ? Ну, в "примитивном виде" (хоть каком-то) можно у меня в так-и-не-дойдут-никак-руки-продолжить "курсе молодого МиниГУИ-бойца" (http://gustow.narod.ru/harbour/MiniGUI_help/welcome.htm)

gustow: SadStar55 пишет: Что получилось в результате. (может кому пригодится) А что? Вполне неплохой "шаблон" для подобных задач, я-так-думаю! ;)

Andrey: SadStar55 пишет: Что получилось в результате. (может кому пригодится) Классная утилитка ! Спасибо за код ! Может быть причесать код (дать коментарии на английском/русском) и отдать Григорию в примеры ? Всем будет интересно !

SadStar55: По опыту эксплуатации немного "расширил и углубил" ИНИшка теперь выглядит так [OldParameters] cUrl=www.ampvanino.ru/operative.html cTargetFolder="D:\MiniGUI_Projects\GetShipPosition2\" cTag1=<li class='pdf'><a href=' cTag2='> nMaxFileNum=4 Т.е. За ссылку на файл принимается то, что расположено между cTag1 и cTag2 cUrl теперь может ссылаться не только на корневую страницу сайта nMaxFileNum задает максимальное количество файлов которое можно закачать при nMaxFileNum=0 качаются все найденные файлы Лог выглядит так 2013-03-13 13:57:04.635: -------------------- 2013-03-13 13:57:04.635: Start 2013-03-13 13:57:04.635: cURL=www.ampvanino.ru/operative.html 2013-03-13 13:57:04.635: cTargetFolder=D:\MiniGUI_Projects\GetShipPosition2\ 2013-03-13 13:57:04.635: cTag1=<li class='pdf'><a href=' 2013-03-13 13:57:04.651: cTag2='> 2013-03-13 13:57:04.651: nMaxFileNum=4 2013-03-13 13:57:04.651: cSite=www.ampvanino.ru 2013-03-13 13:57:04.651: cPage=/operative.html 2013-03-13 13:57:06.979: /assets/files/oper2/2013/03/SCHEDULE-13032013.pdf 2013-03-13 13:57:06.979: /assets/files/oper2/2013/03/ICESTATE-13032013.pdf 2013-03-13 13:57:06.995: /assets/files/oper2/2013/03/POSITION-13032013.pdf 2013-03-13 13:57:06.995: /assets/files/oper2/2013/03/STEERING-13032013.pdf 2013-03-13 13:57:08.198: D:\MiniGUI_Projects\GetShipPosition2\20130313-SCHEDULE.pdf 2013-03-13 13:57:08.260: Ok 2013-03-13 13:57:11.526: Failed connect to www.ampvanino.ru / ErrorCode=10051:Сделана попытка выполнить операцию на сокете при отключенной сети. 2013-03-13 13:57:12.964: D:\MiniGUI_Projects\GetShipPosition2\20130313-POSITION.pdf 2013-03-13 13:57:13.042: Ok 2013-03-13 13:57:14.636: D:\MiniGUI_Projects\GetShipPosition2\20130313-STEERING.pdf 2013-03-13 13:57:14.714: Ok 2013-03-13 13:57:14.714: End !!! Пришлось в очередной раз изобретать велосипед - не нашел как получить код ошибки на сокете и ее описание. См. ssGetLastSysErrorCode() и ssGetLastSysErrorText() внизу текста. Сильно вспотели мозги когда я пытался найти и модернизировать подходящие куски Си-кода. Не уверен в правильности - нужно ли делать LocalFree( lpMsgBuf ); в последней строке? Если делать - то что получит Харбор? Если не делать - то когда делать? Сделает ли это Харбор автоматом? [pre2]#include <minigui.ch> #define CRLF HB_OsNewLine() REQUEST HB_CODEPAGE_RU1251 //REQUEST HB_CODEPAGE_RUWIN FUNCTION Main() local t:='', a, aFiles:={} public cIniFile, cLogFile, nLogMax:=1024*50 //Макс размер Лог-файла public cTargetFolder:="" public cURL:="", cSite:="", cPage:="" public nMaxFileNum:=0 // Макс количество загружаемых файлов. Если 0 то все найденные файлы public cTag1:="", cTag2:="" PUBLIC nBytesDownloaded := 0 SET DATE GERMAN SET CENTURY ON hb_SetCodepage( "RU1251" ) cIniFile:=GetExeFileName() cIniFile:=substr(cIniFile,1,rAt('.',cIniFile))+'ini' cLogFile:=substr(cIniFile,1,rAt('.',cIniFile))+'log' AddToLog( replicate("-",20)) AddToLog( "Start" ) //начало процесса в лог //получение параметров BEGIN INI FILE cIniFile GET cURL SECTION "OldParameters" ENTRY "cUrl" DEFAULT '' GET cTargetFolder SECTION "OldParameters" ENTRY "cTargetFolder" DEFAULT '' GET cTag1 SECTION "OldParameters" ENTRY "cTag1" DEFAULT '' GET cTag2 SECTION "OldParameters" ENTRY "cTag2" DEFAULT '' GET nMaxFileNum SECTION "OldParameters" ENTRY "nMaxFileNum" DEFAULT 0 END INI //индикация параметров t:="cURL="+cURL AddToLog(t ); ? t t:="cTargetFolder="+cTargetFolder AddToLog(t ); ? t t:="cTag1="+cTag1 AddToLog(t ); ? t t:="cTag2="+cTag2 AddToLog(t ); ? t t:="nMaxFileNum="+str(nMaxFileNum) AddToLog(t ); ? t //проверка параметров if empty(cURL); AddToLog("Не задан URL"); return Nil; endif if empty(cTargetFolder); AddToLog("Не задана папка-приемник"); return Nil; endif if !hb_DirExists(cTargetFolder); AddToLog("Папка-приемник <"+cTargetFolder+"> не найдена"); return Nil; endif if empty(cTag1); AddToLog("Не задан cTag1"); return Nil; endif if empty(cTag2); AddToLog("Не задан cTag2"); return Nil; endif //разделить URL на Site и Page например такой www.ampvanino.ru/operative.html if (pos1:=hb_at("/",cURL))>0 cSite:=left(cURL,pos1-1) cPage:=substr(cURL,pos1) else cSite:=cURL cPage:="/" endif t:="cSite="+cSite AddToLog(t ); ? t t:="cPage="+cPage AddToLog(t ); ? t //--------------- //получить страницу и извлечь список файлов //--------------- oSock := THttp():New() //oSock:SetReceiveTimeout( 5000 ) //5sec if !oSock:Connect( cSite, 80 ) t:="Облом соединения с сайтом <"+cSite+">" AddToLog(t); ? t return Nil endif txt := oSock:Get(cPage) if empty(txt) t:="Получена пустая страница!???" AddToLog(t); ? t return Nil endif //--------------------- pos1:=0 do while .t. pos1:=hb_at(cTag1,txt,pos1) // искать cTag1 в txt начиная с pos1 if pos1=0; exit; endif // конец поискам pos2:=hb_at(cTag2,txt,pos1+len(cTag1)) // искать cTag2 в txt начиная с после cTag1 if pos2=0; exit; endif // конец поискам - ошибка структуры файла //извлечь ссылки на файл s:=substr(txt,pos1+len(cTag1),pos2-pos1-len(cTag1)) if left(s,1)#"/"; s:="/"+s; endif aAdd(aFiles,s) pos1:=pos2+len(cTag2) //ограничение на количество файлов if nMaxFileNum>0 .and. len(aFiles)>=nMaxFileNum; exit; endif enddo oSock:Close() ?"Найденые ссылки на файлы" for i:=1 to len(aFiles) AddToLog(aFiles[ i ]) ? aFiles[ i ] next //-------------------------- //получить файлы ?"Загрузка" if len(aFiles)>0 for i:=1 to len(aFiles) FILE_URL:=aFiles[ i ] SavedFile:=substr(FILE_URL,rat("/",FILE_URL)+1) //изменение имени с SCHEDULE-22022013.pdf на 20130222-SCHEDULE.pdf и т.п. t:=token(SavedFile,,2) t:=right(t,4)+substr(t,3,2)+left(t,2) // ddmmyyyy => yyyymmdd t:=t+"-"+token(SavedFile,,1)+right(SavedFile,4) SavedFile:=cTargetFolder+t //-------------------------------------------------------------------- GetInetFile(cSite,FILE_URL,80,SavedFile) next endif //-------------------------- //short-cut the LogFile to nLogMax if File(cLogFile) nLogSize:=FILESIZE(cLogFile) if nLogSize>nLogMax //short-cut the LogFile n:=nLogSize-nLogMax txt:=MEMOREAD(cLogFile) p:=hb_at(CRLF,txt,n) if p>0 MEMOWRIT(cLogFile, substr(txt,p)) ? "short-cut the LogFile to max "+str(nLogMax)+"B OK" AddToLog("short-cut the LogFile to max "+alltrim(str(nLogMax))+"B OK" ) endif endif endif AddToLog("End !!!"+CRLF ) ? "End !!!" RETURN NIL //----------------------------------- function AddToLog(s) //добавляет сообщение в Лог-файл set alternate to (cLogFile) additive set alternate on SET CONSOLE OFF ?? HB_TSTOSTR(HB_DATETIME())+': '+ s + hb_eol() set alternate off set alternate to SET CONSOLE ON return .t. //---------------------------- // Функция получения файла //---------------------------- FUNCTION GetInetFile(cSite, FILE_URL, nPort, SavedFile) LOCAL cBuffer, nBytes, oSocket, lNoError, t LOCAL nFile LOCAL nI,cI, nKolvo, cTemp := "", cTempText :="" LOCAL nLen, lHaveLen := .F. LOCAL nBuffer := 4096 // Буфер Загрузки - 4 КилоБайта local cRequest := "GET " + FILE_URL + " HTTP/1.1" + CRLF + ; "Host: "+cSite + CRLF + ; "User-Agent: Mozilla/5.0" + CRLF + ; "Connection: close" + CRLF + ; CRLF oSocket := TSocket():New() // Создаём новый сокет-объект lNoError := oSocket:Connect(cSite,nPort) // Пытаемся подключиться к серверу // При ошибке IF lNoError == .F. t:="Failed connect to "+cSite+" / ErrorCode="+alltrim(str(ssGetLastSysErrorCode()))+":"+ssGetLastSysErrorText() AddToLog(t) ?t oSocket:Close() return .f. endif nFile := CreateFile(SavedFile) if nFile<0 oSocket:Close() RETURN .f. endif ? SavedFile+" " AddToLog(SavedFile) // Если удалось отправить данные IF oSocket:SendString(cRequest) // Перебор полученного заголовка и поиск длины файла WHILE .T. // Получаем строку заголовка HTTP cI := oSocket:ReceiveLine() // Если здесь содержится информация о длине IF RAt(LOWER("content-length:"),LOWER(cI)) != 0 // Получаем конечную длину загружаемого файла nLen := Substr(cI,At(": ",cI)+2) nLen := VAL(nLen)+1 // Записываем в глобальную переменную M->nBytesTotal := nLen lHaveLen := .T. ENDIF // Если эта строка последния IF (cI == "") // и если не нашли длину файла IF lHaveLen == .F. AddToLog("В заголовке ответа отсутствуют данные о размере загружаемого файла !") ENDIF // ВЫХОДИМ ИЗ ПРОЦЕДУРЫ ЦИКЛА EXIT ENDIF END // Определяем дальнейший способ работы с данными IF lHaveLen == .T. // Если у нас есть длина файла // Получаем все части файла DO WHILE .T. // Получаем очередную часть файла cTemp := oSocket:ReceiveChar(nBuffer) // Записываем фрагмент в файл WriteFile(nFile,cTemp) ?? "#" // Прибавляем к уже скачанному M->nBytesDownloaded += LEN(cTemp) // Если пришёл пустой пакет IF LEN(cTemp) == 0 // И если мы скачали файл (+1 байт) IF M->nBytesDownloaded + 1 >= M->nBytesTotal ELSE // Если произошла ошибка AddToLog("Ошибка в процессе загрузки файла !") ENDIF EXIT ENDIF ENDDO ELSE // Если длина файла неизветсна // Получаем весь файл целиком без вопросов cTemp := oSocket:ReceiveString() WriteFile(nFile,cTemp) ENDIF oSocket:Close() CloseFile(nFile) AddToLog("Ok") ENDIF RETURN .t. // Функция создания файла FUNCTION CreateFile(SAVE_NAME) LOCAL nFileHandler // Пытаемся создать файл nFileHandler := FCreate(SAVE_NAME) // Если есть оишбка IF FError() <> 0 AddToLog("Ошибка при создание файла: "+SAVE_NAME+" !") AddToLog(FError()) // Возвращаем значение -1 nFileHandler := -1 ENDIF RETURN nFileHandler // Функция записи в файл, хэндлер принимается в параметрах FUNCTION WriteFile(nFileHandler,cText) LOCAL nSuccess nSuccess := FWrite(nFileHandler,cText) IF nSuccess <> LEN(cText) AddToLog("Ошибка при записи в файл:"+FError()) ENDIF Return nSuccess // Функция закрытия файла по хэндлеру из параметров FUNCTION CloseFile(nFileHandler) LOCAL lClosed lClosed := FClose(nFileHandler) IF lClosed := .F. AddToLog("Ошибка при закрытии файла:"+FError()) ENDIF Return lClosed //========================================================================== #pragma BEGINDUMP #include <windows.h> //---------------------------------- HB_FUNC ( SSGETLASTSYSERRORCODE ) // ssGetLastSysErrorCode() { hb_retni( GetLastError() ); } //---------------------------------- HB_FUNC ( SSGETLASTSYSERRORTEXT ) // ssGetLastSysErrorText() { LPVOID lpMsgBuf; DWORD dwError = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); hb_retc( lpMsgBuf ); // Free the buffer //LocalFree( lpMsgBuf ); } #pragma ENDDUMP[/pre2]



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