Code: Select all | Expand
// FTPTESTE.PRG - Exemplo: envio de lista de arquivos por FTP (WinINet)
// Usa somente: InternetOpen, InternetConnect, FtpPutFile, InternetCloseHandle
// Opcionais (so se estiverem linkadas): FtpCreateDirectory, GetLastError
#include "FiveWin.ch"
#define INTERNET_OPEN_TYPE_DIRECT 1
#define INTERNET_SERVICE_FTP 1
#define INTERNET_FLAG_PASSIVE 134217728 // 0x08000000
#define FTP_TRANSFER_TYPE_BINARY 2
FUNCTION Main()
LOCAL hInternet, hConnect
LOCAL aArquivos := { "arq1.txt", "arq2.dat", "arq3.xml" }
LOCAL cHost := "ftp.seu-servidor.com" // somente o host, sem "ftp://"
LOCAL nPorta := 21
LOCAL cUsr := "usuario"
LOCAL cPsw := "senha"
LOCAL cDest := "/pasta_remota/"
LOCAL lPassivo := .T.
LOCAL cArq, cRemoto, nX
LOCAL nOk := 0, nErro := 0, nFalta := 0
LOCAL cLog := "FTPTESTE.LOG"
LOCAL cResumo := ""
// Ajusta o destino remoto: sempre com "/" no inicio e no fim
cDest := StrTran( AllTrim( cDest ), "\", "/" )
IF Left( cDest, 1 ) != "/"
cDest := "/" + cDest
ENDIF
IF Right( cDest, 1 ) != "/"
cDest += "/"
ENDIF
Ftp_Log( cLog, "---- Inicio do envio para " + cHost )
// Abre a sessao de internet
hInternet := InternetOpen( "FiveWin_FTP", INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0 )
IF Empty( hInternet )
Ftp_Erro( cLog, "InternetOpen falhou" )
RETURN NIL
ENDIF
// Conecta ao servidor FTP (modo passivo costuma ser necessario atras de firewall/NAT)
hConnect := InternetConnect( hInternet, cHost, nPorta, cUsr, cPsw, ;
INTERNET_SERVICE_FTP, ;
If( lPassivo, INTERNET_FLAG_PASSIVE, 0 ), 0 )
IF Empty( hConnect )
Ftp_Erro( cLog, "Nao foi possivel conectar em " + cHost + ":" + LTrim( Str( nPorta ) ) )
InternetCloseHandle( hInternet )
RETURN NIL
ENDIF
Ftp_Log( cLog, "Conectado em " + cHost )
// Cria a pasta remota, se a funcao existir. Se a pasta ja existe, o erro e ignorado.
IF Type( "FtpCreateDirectory()" ) == "UI"
FtpCreateDirectory( hConnect, Left( cDest, Len( cDest ) - 1 ) )
ENDIF
FOR nX := 1 TO Len( aArquivos )
cArq := aArquivos[ nX ]
cRemoto := cDest + cFileNoPath( cArq )
IF ! File( cArq )
nFalta++
Ftp_Log( cLog, "NAO ENCONTRADO: " + cArq )
LOOP
ENDIF
// Transferencia binaria: evita alterar quebras de linha / corromper .dat
IF FtpPutFile( hConnect, cArq, cRemoto, FTP_TRANSFER_TYPE_BINARY, 0 )
nOk++
Ftp_Log( cLog, "OK: " + cArq + " -> " + cRemoto )
ELSE
nErro++
Ftp_Erro( cLog, "ERRO ao enviar " + cArq )
ENDIF
NEXT
InternetCloseHandle( hConnect )
InternetCloseHandle( hInternet )
cResumo := "Enviados: " + LTrim( Str( nOk ) ) + CRLF + ;
"Com erro: " + LTrim( Str( nErro ) ) + CRLF + ;
"Nao encontrados: " + LTrim( Str( nFalta ) ) + CRLF + ;
"Log: " + cLog
Ftp_Log( cLog, StrTran( cResumo, CRLF, " | " ) )
IF nErro > 0 .OR. nFalta > 0
MsgStop( cResumo, "FTP concluido com problemas" )
ELSE
MsgInfo( cResumo, "FTP concluido" )
ENDIF
RETURN NIL
// Grava uma linha com data/hora no arquivo de log (acrescenta no final)
STATIC FUNCTION Ftp_Log( cArqLog, cTexto )
LOCAL nH
LOCAL cLinha := DToC( Date() ) + " " + Time() + " " + cTexto + CRLF
IF File( cArqLog )
nH := FOpen( cArqLog, 2 )
ELSE
nH := FCreate( cArqLog )
ENDIF
IF nH >= 0
FSeek( nH, 0, 2 )
FWrite( nH, cLinha )
FClose( nH )
ENDIF
RETURN NIL
// Registra erro no log; inclui o codigo do Windows se GetLastError() estiver linkada
STATIC FUNCTION Ftp_Erro( cArqLog, cTexto )
LOCAL cMsg := cTexto
IF Type( "GetLastError()" ) == "UI"
cMsg += " (erro Windows " + LTrim( Str( GetLastError() ) ) + ")"
ENDIF
Ftp_Log( cArqLog, cMsg )
IF "Nao foi possivel" $ cTexto .OR. "InternetOpen" $ cTexto
MsgStop( cMsg, "FTP" )
ENDIF
RETURN NIL
Regards, saludos.