On-line: gfilatov2002, гостей 1. Всего: 2 [подробнее..]
АвторСообщение



Пост N: 1
Зарегистрирован: 21.02.13
ссылка на сообщение  Отправлено: 21.02.13 07:40. Заголовок: ?Консольная утилита на базе МИниГУИ дистрибутива


попробовал консольную утилиту сделать на Харборе из дистрибутива МиниГУИ
вот такой строкой (пути в 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


Каких-то инклюдов и либов не находит?


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 16 [только новые]





Пост N: 725
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 21.02.13 09:31. Заголовок: SadStar55 пишет: по..


SadStar55 пишет:

 цитата:
попробовал консольную утилиту сделать на Харборе из дистрибутива МиниГУИ
вот такой строкой (пути в compile.bat исправлены)

Для этого есть hbmk2 и раздел harbour. И меня интересует, почему многие уверенны что harbour это minigui?

Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 559
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 21.02.13 09:44. Заголовок: SadStar55 пишет: SE..


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-> ставить, то же самое и в Клиппере было...


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 2
Зарегистрирован: 21.02.13
ссылка на сообщение  Отправлено: 22.02.13 00:12. Заголовок: первый мой косяк - н..


первый мой косяк - не вставил строку
#include <minigui.ch>

исправил - исчезла ругань компилятора на
SET CODEPAGE TO RUSSIAN

Но ругань линковщика осталась на
'_HB_FUN_HB_SETCODEPAGE'
'_HB_FUN_GETEXEFILENAME'

в каких либах они находятся?


AlexMyr пишет:

 цитата:
И меня интересует, почему многие уверенны что harbour это minigui?


Откуда вы это взяли?
MiniGUI это Харбор+....
т.к. МиниГУИ без Харбора не бывает, а наоборот бывает.

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


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 727
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 22.02.13 00:25. Заголовок: SadStar55 пишет: В ..


SadStar55 пишет:

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

используйте просто harbour и просто утилиту hbmk2.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 383
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 22.02.13 01:03. Заголовок: SadStar55 пишет: В ..


SadStar55 пишет:

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

Мне помогало (при создании консольного EXE, но в Harbour+MiniGUI) заменить "/С" на "/CG" (console mixed mode).

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 728
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 22.02.13 09:25. Заголовок: SadStar55 пишет: Al..


SadStar55 пишет:

 цитата:
AlexMyr пишет:

цитата:
И меня интересует, почему многие уверенны что harbour это minigui?


Откуда вы это взяли?

Из таких сообщений как это.
SadStar55 пишет:

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


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

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 3
Зарегистрирован: 21.02.13
ссылка на сообщение  Отправлено: 25.02.13 03:52. Заголовок: AlexMyr пишет: Запу..


AlexMyr пишет:

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



harbour.exe делает готовые EXE-шки?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 384
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 25.02.13 07:19. Заголовок: SadStar55 , не попро..


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

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 729
Зарегистрирован: 11.06.10
ссылка на сообщение  Отправлено: 25.02.13 09:13. Заголовок: SadStar55 пишет: ha..


SadStar55 пишет:

 цитата:
harbour.exe делает готовые EXE-шки?

Нет.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2698
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 25.02.13 23:47. Заголовок: AlexMyr пишет: И ме..


AlexMyr пишет:

 цитата:
И меня интересует, почему многие уверенны что harbour это minigui?


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

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 4
Зарегистрирован: 21.02.13
ссылка на сообщение  Отправлено: 26.02.13 00:38. Заголовок: gustow пишет: SadSt..


gustow пишет:

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


Так и сделал по первому вашему совету. Работает нужным образом. Спасибо.



Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 5
Зарегистрирован: 21.02.13
ссылка на сообщение  Отправлено: 26.02.13 01:07. Заголовок: Что получилось в рез..


Что получилось в результате. (может кому пригодится)
Консольная утилита. Запускается шедьюлером на сервере.
Можно запустить и вручную на раб.столе в "визуальном режиме".
Загружает из интернета заданную ХТМЛ-страницу на которой каждый день обновляются ссылки на некоторые файлы нужные одному отделу.
Находит эти ссылки.
Загружает файлы немного переделывая имена.

Это сделано по заданию админа т.к. существуют жесткие ограничения на доступ в Сеть.
А фильтрануть средствами шлюза админ не смог.

Функционал закачки взят отсюда
http://clipper.borda.ru/?1-1-0-00000307-000-0-0-1320091437
Спасибо SkyNET-у
только обрезал ГУЕвый "обвес"

Код не идеален. Видны следы последовательной разработки и отладки.
Т.е. можно еще оптимизировать.

 
#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

Инишка выглядит так
 
[OldParameters]
cUrl=www.ampvanino.ru
cTargetFolder="\\Pdc-trb\exchange.box\ShipPosition\"


Кусок лог-файла

 

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 !!!


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 385
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 26.02.13 08:37. Заголовок: Andrey пишет: где н..


Andrey пишет:

 цитата:
где на русском языке прочитать про МиниГуи ?

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

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 386
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 26.02.13 08:39. Заголовок: SadStar55 пишет: Чт..


SadStar55 пишет:

 цитата:
Что получилось в результате. (может кому пригодится)

А что? Вполне неплохой "шаблон" для подобных задач, я-так-думаю! ;)

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2699
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 26.02.13 11:26. Заголовок: SadStar55 пишет: Чт..


SadStar55 пишет:

 цитата:
Что получилось в результате. (может кому пригодится)


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

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 6
Зарегистрирован: 21.02.13
ссылка на сообщение  Отправлено: 13.03.13 06:26. Заголовок: По опыту эксплуатаци..


По опыту эксплуатации немного "расширил и углубил"


ИНИшка теперь выглядит так

 цитата:
[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 ); в последней строке?
Если делать - то что получит Харбор?
Если не делать - то когда делать? Сделает ли это Харбор автоматом?
#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


Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 624
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет