Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

access a file on the web 2

Status
Not open for further replies.

rickesilaw

Programmer
Jun 24, 2002
154
CA
I want to read a file stored on our web site and if newer than file I have I want to download it. Has anyone got simple example of how to get a file from the web.

Also, when I go into VFP8 Taskpane to publish an XML service I get error that IIS services not installed and need at least IIS 5.0 - I am on 6.0.26
 
rickesilaw,

As far as simple goes check out my FAQ:

Add Download Ability to Your App in 2 Seconds
faq184-3838

Slighthaze = NULL

[ul][li]FAQ184-2483
An excellent guide to getting a fast and accurate response to your questions in this forum.[/li][/ul]
 
Thanks Slighthase (aren't all programmers in that!) I am going to test this shortly - will let you know.

Did you expand on this in any way to allow users to update exes (I know West Wind has a product but.....)
 
rickesilaw

FTP? Create a directory of the files on the FTP site in an array, use a table on your system to check if you already downloaded it, otherwise download it. Here is what I use in one of my applications to download zipped files.
Code:
#DEFINE ERROR_FTP_TRANSFER_IN_PROGRESS  12110
#DEFINE INTERNET_OPEN_TYPE_DIRECT     1
#DEFINE INTERNET_SERVICE_FTP          1
#DEFINE INTERNET_INVALID_PORT_NUMBER  0
SET DELETED ON
PUBLIC llSuccess
USE C:\FTA\DATA\track.DBF SHARED AGAIN
SET ORDER TO TAG shrtfile
PUBLIC oSession
DO DECL
objFtp = CREATEOBJECT("TFtpDir", "222.222.222.222","anonymous", "ano@nymous.com")
IF TYPE("objFtp") = "O"
   objFtp.ScanFiles
ENDIF
* end of main

DEFINE CLASS TFtpDir AS CUSTOM
   hInternet=0
   hConnect=0

   PROCEDURE INIT(lcHost, lcUser, lcPwd)
      THIS.hInternet = InternetOpen("VfpFtp", INTERNET_OPEN_TYPE_DIRECT, 0,0,0)
      IF THIS.hInternet <> 0
         THIS.hConnect = InternetConnect(THIS.hInternet, lcHost,;
            INTERNET_INVALID_PORT_NUMBER, lcUser, lcPwd,;
            INTERNET_SERVICE_FTP, 0, 0)
         oSession= THIS.hConnect
      ENDIF
      IF THIS.hConnect = 0
         RETURN .F.
      ENDIF

   PROCEDURE DESTROY
      InternetCloseHandle(THIS.hConnect)
      InternetCloseHandle(THIS.hInternet)

   PROCEDURE ScanFiles
      THIS.EnumFiles

      WITH THIS
         DO WHILE .T.
            lnResult = .NextNode()
            DO CASE
               CASE lnResult = 0
                  LOOP
               CASE lnResult = 1
                  .EnumFiles
               CASE lnResult = -1
                  EXIT
            ENDCASE
         ENDDO
      ENDWITH

   FUNCTION NextNode
      * returns next unprocessed remote folder
      SELECT csResult
      LOCATE ALL FOR NOT processed

      IF FOUND()
         IF FtpSetCurrentDirectory(THIS.hConnect, ALLTRIM(csResult.fpath)) <> 1
            REPLACE processed WITH .T., accesserr WITH .T.
            RETURN 0
         ELSE
            RETURN 1
         ENDIF
      ELSE
         RETURN -1
      ENDIF

   PROTECTED FUNCTION GetCurrentDir
      DECLARE INTEGER FtpGetCurrentDirectory IN wininet;
         INTEGER hFtpSession, STRING @lpszDir, INTEGER @lpdwCurDir
      LOCAL lcDirectory, lnLen, lnResult
      lcDirectory = SPACE(250)
      lnLen = LEN(lcDirectory)
      lnResult = FtpGetCurrentDirectory(THIS.hConnect, @lcDirectory, @lnLen)
      RETURN IIF (lnResult=1, LEFT(lcDirectory, lnLen), &quot;#error#&quot;)

   PROCEDURE EnumFiles
      #DEFINE FILE_ATTR_DIR   16
      #DEFINE MAX_PATH        260
      #DEFINE MAX_DWORD       4294967296  && 0xffffffff + 1
      #DEFINE FIND_DATA_SIZE  318
      #DEFINE INTERNET_FLAG_NEED_FILE  16

      LOCAL lcFPath
      lcFPath = THIS.GetCurrentDir()

      CREATE CURSOR csResult (fpath C(250),;
         fileattr  I,;
         filecount I,;
         dircount  I,;
         filesize  N(12),;
         isfile    L,;
         processed L,;
         accesserr L;
         )
      LOCAL hFind, lcFBuff, lnFileattr, lcFilename, lnFileCount, lnDirCount,;
         lnFileSize, lProcessed, lIsFile

      STORE 0 TO lnDirCount, lnFileCount, lnFileSize
      lcFBuff = REPLI(CHR(0), FIND_DATA_SIZE)

      hFind = FtpFindFirstFile(THIS.hConnect, lcFPath + &quot;/*.*&quot;,;
         @lcFBuff, INTERNET_FLAG_NEED_FILE, 0)

      IF hFind <> 0
         DO WHILE .T.
            lcFilename = SUBSTR(lcFBuff, 45,MAX_PATH)
            lcFilename = LEFT(lcFilename, AT(CHR(0),lcFilename)-1)
            lnFileattr = buf2dword(SUBSTR(lcFBuff, 1,4))
            lnFileSize = buf2dword(SUBSTR(lcFBuff, 29,4)) * MAX_DWORD +;
               buf2dword(SUBSTR(lcFBuff, 33,4))

            IF BITAND(lnFileattr, FILE_ATTR_DIR) = FILE_ATTR_DIR
               * for a directory
               lnDirCount = lnDirCount + 1
               lProcessed = (lcFilename == &quot;..&quot; OR lcFilename == &quot;.&quot;)
               lIsFile = .F.
            ELSE
               * for a regular file
               lnFileCount = lnFileCount + 1
               lProcessed = .T.
               lIsFile = .T.
            ENDIF

            lcFullpath = lcFilename
            INSERT INTO csResult VALUES (lcFullpath,;
               lnFileattr, 0, 0, lnFileSize, lIsFile, lProcessed, .F.)

            IF InternetFindNextFile(hFind, @lcFBuff) = 0
               EXIT
            ENDIF
         ENDDO
      ENDIF
      UPDATE csResult SET dircount = m.lnDirCount,;
         filecount = m.lnFileCount, filesize = m.lnFileSize,;
         processed = .T.
      SELECT csResult
      SCAN
         SCATTER MEMVAR
         LOCAL lcFile
         lcFile= ALLTRIM(csResult.fpath)
         SELECT track
         IF !SEEK(lcFile)
            lcPath = &quot;\\MISSERV\D$\CDRDOWNLOAD\&quot;
            downloads(lcFile,lcPath)
            IF llSuccess = .T.
               SELECT track
               GO BOTTO
               APPEND BLANK
               GATHER MEMVAR
               REPLACE DOWNLOADED WITH DATETIME()
               REPLACE shrtfile WITH m.fpath
               lcPath = &quot;\\MISSERV\D$\CDRDOWNLOAD\&quot;
               *           WAIT WINDOW NOWAIT &quot;Downloading file &quot;+lcFile
            ENDIF
         ELSE
            *          WAIT WINDOW NOWAIT &quot;File is already download &quot;+lcFile
         ENDIF
      ENDSCAN
      = InternetCloseHandle(hFind)
ENDDEFINE

FUNCTION  buf2dword (lcBuffer)
   RETURN ASC(SUBSTR(lcBuffer, 1,1)) +;
      ASC(SUBSTR(lcBuffer, 2,1)) * 256 +;
      ASC(SUBSTR(lcBuffer, 3,1)) * 65536 +;
      ASC(SUBSTR(lcBuffer, 4,1)) * 16777216

PROCEDURE  DECL
   DECLARE INTEGER InternetCloseHandle IN wininet.DLL INTEGER hInet

   DECLARE INTEGER InternetOpen IN wininet;
      STRING sAgent, INTEGER lAccessType, STRING sProxyName,;
      STRING sProxyBypass, STRING lFlags

   DECLARE INTEGER InternetConnect IN wininet;
      INTEGER hInternetSession, STRING sServerName, INTEGER nServerPort,;
      STRING sUsername, STRING sPassword, INTEGER lService,;
      INTEGER lFlags, INTEGER lContext

   DECLARE INTEGER FtpFindFirstFile IN wininet;
      INTEGER hFtpSession, STRING lpszSearchFile,;
      STRING @lpFindFileData, INTEGER dwFlags, INTEGER dwContent

   DECLARE INTEGER InternetFindNextFile IN wininet;
      INTEGER hFind, STRING @lpvFindData

   DECLARE INTEGER FtpSetCurrentDirectory IN wininet;
      INTEGER hFtpSession, STRING @lpszDirectory
PROCEDURE downloads
   LPARAMETERS oFilename,oDestination
   * lAccessType - some values
   #DEFINE INTERNET_INVALID_PORT_NUMBER  0
   #DEFINE INTERNET_OPEN_TYPE_DIRECT     1
   #DEFINE INTERNET_OPEN_TYPE_PROXY      3
   #DEFINE INTERNET_DEFAULT_FTP_PORT     21

   * lFlags: only a few
   #DEFINE INTERNET_FLAG_ASYNC             268435456     && &H10000000
   #DEFINE INTERNET_FLAG_FROM_CACHE        16777216    && &H1000000
   #DEFINE INTERNET_FLAG_OFFLINE           16777216
   #DEFINE INTERNET_FLAG_CACHE_IF_NET_FAIL 65536        && &H10000

   * registry access settings
   #DEFINE INTERNET_OPEN_TYPE_PRECONFIG  0
   #DEFINE FTP_TRANSFER_TYPE_ASCII       1
   #DEFINE FTP_TRANSFER_TYPE_BINARY      2

   * type of service to access
   #DEFINE INTERNET_SERVICE_FTP     1
   #DEFINE INTERNET_SERVICE_GOPHER  2
   #DEFINE INTERNET_SERVICE_HTTP    3

   * file attributes
   #DEFINE FILE_ATTRIBUTE_NORMAL    128    && 0x00000080

   DO DECL2
   lpszRemoteFile = oFilename            && if it still exists
   lpszNewFile    = oDestination+oFilename    && check the destination folder
   fFailIfExists  = 0        && do not stop if the target already exists
   dwContext      = 0

   lnResult = FtpGetFile (oSession, lpszRemoteFile, lpszNewFile,;
      fFailIfExists, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_ASCII,;
      dwContext)
   IF lnResult > 0
      llSuccess = .T.
   ELSE
      llSuccess = .F.
   ENDIF
   lpszNewFile = JUSTSTEM(lpszRemoteFile)+&quot;.zi~&quot;
   *  lnresult2 = FtpRenameFile(oSession,lpszRemoteFile,lpszNewFile)
   RETURN        && main
ENDPROC
PROCEDURE  DECL2
   DECLARE INTEGER InternetOpen IN wininet;
      STRING sAgent, INTEGER lAccessType, STRING sProxyName,;
      STRING sProxyBypass, STRING  lFlags

   DECLARE INTEGER InternetCloseHandle IN wininet INTEGER hInet

   DECLARE INTEGER InternetConnect IN wininet;
      INTEGER hInternetSession, STRING  sServerName,;
      INTEGER nServerPort, STRING  sUsername,;
      STRING  sPassword, INTEGER lService,;
      INTEGER lFlags, INTEGER lContext

   DECLARE INTEGER FtpGetFile IN wininet;
      INTEGER hFtpSession, STRING  lpszRemoteFile,;
      STRING  lpszNewFile, INTEGER fFailIfExists,;
      INTEGER dwFlagsAndAttributes,;
      INTEGER dwFlags, INTEGER dwContext

   DECLARE INTEGER FtpRenameFile IN wininet.DLL;
      INTEGER hConnect,;
      STRING  lpszExisting,;
      STRING  lpszNew




Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike,

Nice bit of code. Star worthy.

Slighthaze = NULL

[ul][li]FAQ184-2483
An excellent guide to getting a fast and accurate response to your questions in this forum.[/li][/ul]
 
Thank you SlightHaze for the star.

Put all that in a prg, compile as an exe, run it as a service on Window2000 server, and create another service that unzips the files and a third service that parses the texfiles into a database and you have an unmanaged download-unzip-parse service.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
excellent - I should hire you guys! I will be testing next week - our web guy isn't in so don't have file names -#@!%%^
 
rickesilaw

our web guy isn't in so don't have file names

The above code will give you all files contained in the directory in the csResult cursor, no matter what the file name is.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
rickesilaw,

excellent - I should hire you guys!

Well we aren't cheap, but definately open to negotiations. [bigsmile]

Slighthaze = NULL

[ul][li]FAQ184-2483
An excellent guide to getting a fast and accurate response to your questions in this forum.[/li][/ul]
 
Mike - I was given following as test file storage area ( to test download - I am not sure of how to change your routine to look at this directory.

Also, I tried modifying Slighthaze routine to look at this but get message &quot;Internet Explorer cannot download file.txt?XXAX, from (The X is actually a special character - don't know value)
 
Rickesilaw

My suggestion was for an FTP site rather then a website. I would suggest, either you install an FTP site (takes a few minutes) and use the code suggested, or go to and use Rick's HTTP class


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Thx Mike - I will get a ftp site set up and also look at westwind.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top