【问题标题】:Download file (HTTP) with FoxPro使用 FoxPro 下载文件 (HTTP)
【发布时间】:2011-12-15 18:51:53
【问题描述】:

今天有人向我寻求有关 FoxPro 问题的帮助,关于如何通过 HTTP 下载文件。

我发现了两个东西:一个是付费的 ActiveX,而other one 需要 libcurl。

有没有办法做到这一点而无需任何额外的 (VFP 8),比如 Java 中的HttpURLConnection?例如使用Microsoft.XMLHTTP

【问题讨论】:

    标签: foxpro visual-foxpro


    【解决方案1】:

    两个可以工作的 sn-ps,不需要额外的文件/dlls/flls/etc。

    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

    【讨论】:

      【解决方案2】:

      是我的 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 属性中:

      STRTOFILE(m.HttpClient.responseBody,"c:\filename");
      
      m.myform.AddObject("myimg",""image")
      m.myform.myimg.PictureVal=m.HttpClient.responseBody
      

      【讨论】:

        【解决方案3】:

        考虑使用 West Wind Web Connect。这是一个框架,可让您编写可从 Web 访问的 VFP 应用程序。

        【讨论】:

          【解决方案4】:

          您可以在 VFP 中执行此操作,但它需要注册 Windows DLL 以打开连接句柄并调用以获取数据。

          另一种选择是使用自动化,例如使用 Internet Explorer。您可以在 VFP 中创建一个 ie 对象,并调用它的方法来打开给定的 URL,等到它的“就绪状态”完成,然后查看内容。至于尝试获取需要URL参数字符串的东西,你可以添加那些没有问题,但如果它需要POST变量,那就更努力了。

          正如 Jerry 所提到的,West-Wind 工具非常强大,Rick Strahl 从……我记得大约是 1993 年就一直在这样做。他的另一个工具是专门提供更多功能的 wwIPTools.DLL。

          【讨论】:

            【解决方案5】:

            您还可以查看 Craig Boyd 的免费 VFPConnection 库,他还有一个出色的免费 JSON 库。

            【讨论】:

            • 这是我在原始问题中粘贴的链接。唉,最新版本不行。
            【解决方案6】:

            选项 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/

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-12-20
              • 1970-01-01
              • 2012-10-10
              • 1970-01-01
              • 2019-10-06
              • 2016-03-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多