2011-12-15 103 views
4

今天,我被問及如何通過HTTP下載文件的FoxPro問題的幫助。使用FoxPro下載文件(HTTP)

我發現了兩件事:一個是付費的ActiveX,而other one需要libcurl。

有沒有辦法做到這一點,沒有任何額外的(VFP 8),類似於Java中的HttpURLConnection?例如通過使用Microsoft.XMLHTTP

回答

0

使用West Wind Web Connect進行研究。這是一個框架,可以讓您編寫可從Web訪問的VFP應用程序。

0

您可以在VFP中做到這一點,但它需要註冊Windows DLL才能打開連接句柄,並調用以獲取數據。

另一種選擇是使用自動化,如使用Internet Explorer。您可以從VFP中創建一個ie對象,並調用其方法來打開給定的URL,等到它的「就緒狀態」完成,然後查看內容。至於嘗試獲取需要URL參數字符串的東西,您可以添加這些沒有問題,但如果它需要POST變量,這是多一點努力。

正如傑瑞所說,西風工具非常強大,裏克斯特拉爾自從1993年以來一直這樣做,我記得。他的另一個工具是wwIPTools.DLL,它提供了更多的功能。

8

兩個片段可以工作,並且不需要額外的文件/ dlls/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") 

(從here拍攝)

0

你也可以看看克雷格博伊德的免費VFPConnection庫,他也有一個很好的免費的JSON庫。

+0

這就是我在我原來的問題粘貼的鏈接。唉,最新的版本不起作用。 – Bozho 2011-12-16 09:34:50

0

選項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/

1

是一個我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() 

後上面的代碼被執行包含在中的服務器響應財產,你可以值保存到文件或例如用於圖片到圖片對象PictureVal屬性:

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

m.myform.AddObject("myimg",""image") 
m.myform.myimg.PictureVal=m.HttpClient.responseBody