Скачать файл (HTTP) с FoxPro - PullRequest
       15

Скачать файл (HTTP) с FoxPro

4 голосов
/ 15 декабря 2011

Сегодня меня попросили помочь с проблемой FoxPro, о том, как загрузить файл через HTTP.

Я нашел две вещи: одна была платной ActiveX, а другая требует libcurl.

Есть ли способ сделать это без чего-либо дополнительного (VFP 8), что-то вроде HttpURLConnection в Java? Например, используя Microsoft.XMLHTTP

Ответы [ 6 ]

8 голосов
/ 16 декабря 2011

Два фрагмента, которые работают и не требуют дополнительных файлов / dll / flls / и т. Д.

Local loRequest, lcUrl, lcFilename

lcUrl = "http://example.com/foo.zip"
lcFilename = "C:\Temp\PSV.zip"

loRequest = Createobject('MsXml2.XmlHttp')
loRequest.Open("GET",lcUrl,.F.)
loRequest.Send()
StrToFile(loRequest.ResponseBody,lcFilename)

и

lox = CREATEOBJECT("inetctls.inet")
lcSuff = lox.OpenURL("http://whatever.co.uk/suff.htm")
STRTOFILE(lcStuff, "c:\data\myfile.htm")

(взято из здесь )

1 голос
/ 27 декабря 2011

Является ли мой HttpClient.prg файл (поддерживается только GET ответ):

#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4

#define REQ_STATE_UNINITIALIZED 0 && open()has not been called yet.
#define REQ_STATE_LOADING       1 && send()has not been called yet.
#define REQ_STATE_LOADED        2 && send() has been called, and headers and status are available.
#define REQ_STATE_INTERACTIVE   3 && Downloading; responseText holds partial data.
#define REQ_STATE_COMPLETED     4 && The operation is complete.

DEFINE CLASS HttpClientRequest As Custom
  readystate=REQ_STATE_UNINITIALIZED
  Protocol=NULL
  Url=NULL
  requestBody=NULL
  responseBody=NULL

  PROCEDURE Open(tcProtocol, tcUrl)
    IF this.readystate != REQ_STATE_UNINITIALIZED
      ERROR "HttpClientRequest is already opened."
    ENDIF
    IF VARTYPE(m.tcProtocol)!="C" OR VARTYPE(m.tcUrl)!="C" 
      ERROR "Invalid type or count of parameters."
    ENDIF
    IF NOT INLIST(m.tcProtocol,"GET")
      ERROR "Unsupported or currently not implemented protocol type."
    ENDIF
    this.Protocol = m.tcProtocol
    this.Url = m.tcUrl
    this.readystate = REQ_STATE_LOADING
  ENDPROC

  PROCEDURE Send(tcBody)
    IF this.readystate != REQ_STATE_LOADING
      ERROR "HttpClientRequest is not in initialized state."
    ENDIF
    IF PCOUNT()=0
      m.tcBody=NULL
    ENDIF
    IF this.Protocol=="GET" AND (NOT ISNULL(m.tcBody))
      ERROR "Invalid type or count of parameters."
    ENDIF
    this.requestBody = m.tcBody
    this.readystate = REQ_STATE_LOADED


    DECLARE integer InternetOpen IN "wininet.dll" ;
      string @ lpszAgent, ;
      integer dwAccessType, ;
      string @ lpszProxyName, ;
      string @ lpszProxyBypass, ;
      integer dwFlags
    DECLARE integer InternetCloseHandle IN "wininet.dll" ;
      integer hInternet
    DECLARE integer InternetCanonicalizeUrl IN "wininet.dll" ;
      string @ lpszUrl, ;
      string @ lpszBuffer, ;
      integer @ lpdwBufferLength, ;
      integer dwFlags
    DECLARE integer InternetOpenUrl IN "wininet.dll" ;
      integer hInternet, ;
      string @ lpszUrl, ;
      string @ lpszHeaders, ;
      integer dwHeadersLength, ;
      integer dwFlags, ;
      integer dwContext
    DECLARE integer InternetReadFile IN "wininet.dll" ;
      integer hFile, ;
      string @ lpBuffer, ;
      integer dwNumberOfBytesToRead, ;
      integer @ lpdwNumberOfBytesRead

    LOCAL m.hInternet,lcUrl,lnUrlLen,m.hInternetFile,lcBuffer,lnBufferLen,lnReaded
    m.hInternet = InternetOpen("a.k.d. HttpClientRequest for Visual FoxPro", ;
                               INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, ;
                               NULL, NULL, 0)
    this.responseBody = ""
    IF m.hInternet != 0
      m.lnUrlLen = LEN(this.Url)*8
      m.lcUrl = REPLICATE(CHR(0),m.lnUrlLen)
      InternetCanonicalizeUrl(this.Url, @lcUrl, @lnUrlLen, 0)
      m.hInternetFile = InternetOpenUrl(m.hInternet, @lcUrl, NULL, -1, 0, 0)
      IF m.hInternetFile != 0
        m.lnBufferLen = 10240
        DO WHILE .T.
           m.lcBuffer = REPLICATE(CHR(0),m.lnBufferLen)
           m.lnReaded = 0
           IF NOT (0!=InternetReadFile(m.hInternetFile, @lcBuffer, m.lnBufferLen, @lnReaded) AND m.lnReaded>0)
             EXIT
           ENDIF
          this.responseBody = this.responseBody + LEFT(m.lcBuffer,m.lnReaded)
          this.readystate = REQ_STATE_INTERACTIVE
        ENDDO
        InternetCloseHandle(m.hInternetFile)
      ENDIF
      InternetCloseHandle(m.hInternet)
    ENDIF
    this.readystate = REQ_STATE_COMPLETED
  ENDPROC
ENDDEFINE

Использование для GET запросов:

Local HttpClient
m.HttpClient = NEWOBJECT("HttpClientRequest","httpclient.prg")
m.HttpClient.Open("GET","http://servername/path/resourcename")
m.HttpClient.Send()

После выполнения приведенного выше кода ответ сервера содержится в свойстве m.HttpClient.responseBody, и вы можете сохранить значение в файл или, например, для изображений в PictureVal свойство объекта Image:

STRTOFILE(m.HttpClient.responseBody,"c:\filename");

m.myform.AddObject("myimg",""image")
m.myform.myimg.PictureVal=m.HttpClient.responseBody
0 голосов
/ 17 декабря 2011

Опция 1:

Declare Integer URLDownloadToFile In urlmon.dll As _apiURLDownloadToFile;
Integer pCaller, ;
String  szURL, ;
String  szFileName, ;
Integer dwReserved, ;
Integer lpfnCB

Просто сделайте сначала очистку файла из кэша:

Declare Integer DeleteUrlCacheEntry In wininet.dll As _apiDeleteUrlCacheEntry ;
    String  lpszUrlName

Или добавьте случайный параметр в концеURL, например «? somerandomvalue».

Опция 2:

Declare Integer InternetOpen In wininet.dll As _apiInternetOpen ;
    String  lpszAgent, ;
    Integer dwAccessType, ;
    String  lpszProxy, ;
    String  lpszProxyBypass, ;
    Integer dwFlags

Declare Integer InternetOpenUrl In wininet.dll As _apiInternetOpenUrl ;
    Integer hInternet,;
    String  lpszUrl,;
    String  lpszHeaders,;
    Integer dwHeadersLength,;
    Integer dwFlags,;
    Integer dwContext

Declare Integer InternetReadFile In wininet.dll As _apiInternetReadFile ;
    Integer hFile, ;
    String  @lpBuffer, ;
    Integer dwNumberOfBytesToRead, ;
    Integer @lpdwNumberOfBytesRead

Declare Integer InternetCloseHandle In wininet.dll As _apiInternetCloseHandle ;
    Integer hInternet

Правильное использование функций можно найти в MSDN.

PS: Вы пропустили это: http://curl.haxx.se/libcurl/foxpro/

0 голосов
/ 16 декабря 2011

Вы также можете посмотреть бесплатную библиотеку Крэйга Бойда VFPConnection , у него также есть отличная бесплатная библиотека JSON.

0 голосов
/ 16 декабря 2011

Вы можете сделать это в VFP, но для этого требуется зарегистрировать библиотеки DLL Windows, чтобы открыть дескрипторы соединений, и выполнять вызовы для получения данных.

Другим вариантом является использование автоматизации, например, с Internet Explorer. Вы можете создать объект ie из VFP и вызывать его методы, чтобы открыть заданный URL-адрес, дождаться завершения «Состояние готовности» и просмотреть содержимое. Что касается попыток получить вещи, которые требуют строк параметров URL, вы можете добавить их без проблем, но если это требует переменных POST, это немного больше усилий.

Как упоминал Джерри, инструменты West-Wind довольно мощные, и Рик Страл делал это с ... примерно 1993 года, что я помню. Другой его инструмент - это wwIPTools.DLL, который предлагает еще больше возможностей.

0 голосов
/ 16 декабря 2011

Изучите использование West Wind Web Connect.Это платформа, которая позволит вам создавать приложения VFP, доступные из Интернета.

...