Question:
We have a circumstance with a new SFTP server where the "closehandle" method fails after downloading a file and we want to close the directory. Files are downloaded with out issue. We use this process with a number of other SFTP servers without any problem - the only difference might be that the new SFTP server is in Europe. The trace info from the Chilkat log is shown below:
ChilkatLog: CloseHandle: DllDate: Dec 12 2012 UnlockPrefix: Unlockprefixvalue Username: Server:administrator Architecture: Little Endian; 32-bit Language: ActiveX VerboseLogging: 0 SshVersion: SSH-2.0-mod_sftp/0.9.9 SftpVersion: 3 handle: 66333534653438646233323233356531 closeHandle: handle: 66333534653438646233323233356531 Sent FXP_CLOSE StatusResponseFromServer: Request: FXP_CLOSE InformationReceivedFromServer: StatusCode: 9 StatusMessage: Invalid handle --InformationReceivedFromServer --StatusResponseFromServer Received a failed status response. --closeHandle Failed. --CloseHandle --ChilkatLog
1) Verify that the problem exists with the latest version of Chilkat.
2) Please post LastErrorText's enclosed in <pre> tags so that they're readable.
3) By coincidence, I just finished helping another customer via email with the same problem, and the issue was found to be in the application code, not Chilkat. Make sure the handle is actually valid, hasn't already been closed, AND make sure you're calling CloseHandle on the same SFTP object instance that was used to open the handle.
Thanks for the feedback. I have installed the latest version and we are still getting the error with the CloseHandle method. I do believe the application code is correct since it works fine for three other SFTP sites, but have posted it below just in case:
Thanks for the feedback. I have installed the latest version and we are still getting the error with the CloseHandle method. I do believe the application code is correct since it works fine for three other SFTP sites, but have posted it below just in case:
Application code:
* lfilefompath = path on the FTP server where files to be downloaded are located LPARAMETERS lfilefrompath
Open the FSC table to find the directory files will be downloaded into SELECT FSC_phrase GO top LOCATE FOR active
This is a work table that is used to hold the contents of the directory on the SFTP site IF !USED('sftpsyspref') USE datasftpwork IN 0 EXCLUSIVE endif SELECT sftpwork ZAP
Move to the "incoming" directory so files will be placed there when downloaded CD ALLTRIM((syspref.inbounddir))
LOCAL loSftp LOCAL lnSuccess LOCAL lnPort LOCAL lcHostname LOCAL lcHandle LOCAL loDirListing LOCAL i LOCAL n LOCAL loFileObj
when requesting support. loSftp = CreateObject('Chilkat.SFtp')
Check for current subscription and open the Chilkat widget lnSuccess = loSftp.UnlockComponent(Chilkat_sftpkey) IF (lnSuccess <> 1) CD ALLTRIM((syspref.basedir)) lcSubject = 'Subscription to Chilkat.SFTP has expired' lcMessage = "The subscrption to Chilkat.SFTP tool has expired. The subscription "+ ; "needs to be renewed before it will run. The Chilkat message is "+; losftp.lasterrortext Do sendmessage With lcMessage, lcsubject return ENDIF
Get connection values from metadata SELECT sftp_load LOCATE FOR active loSftp.ConnectTimeoutMs = sftp_load.connecttimeout loSftp.IdleTimeoutMs = sftp_load.idletimeout
Connect to the SSH server.
lnSuccess = loSftp.Connect(lcHostname,lnport) IF (lnSuccess <> 1) CD ALLTRIM((syspref.basedir)) lcSubject = 'ERROR Unable to connect to SFTP site for file download for '+; lfilefrompath lcMessage = "The SFTP connection to download files failed for "+lfilefrompath+; ". Verify IP address for the connection. The Chilkat message is "+; losftp.lasterrortext Do sendmessage With lcMessage, lcsubject return ENDIF
IF (lnSuccess <> 1) CD ALLTRIM((syspref.basedir)) lcSubject = 'ERROR - Unable to login to SFTP site for file download for '+; lfilefrompath lcMessage = "The login to the SFTP connection to download files failed for "+; lfilefrompath+". Verify the login information. The Chilkat message is "+; losftp.lasterrortext Do sendmessage With lcMessage, lcsubject return ENDIF
*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Get DIRECTORY handle here
lcHandle = loSftp.OpenDir(lfilefrompath)
IF (lcHandle = NULL )
CD ALLTRIM((syspref.basedir))
lcSubject = 'Error - Unable to open directory SFTP site for file download for '+;
lfilefrompath
lcMessage = "The SFTP file download failed for "+lfilefrompath+". Verfy file "+;
" name, path and connection information. The Chilkat message is "+;
losftp.lasterrortext
Do sendmessage With lcMessage, lcsubject
return
ENDIF
Download the directory listing: loDirListing = loSftp.ReadDir(lcHandle) IF (loDirListing = NULL ) CD ALLTRIM((syspref.basedir)) lcSubject = 'Error - Unable to read directory on SFTP site for file download '+; lfilefrompath lcMessage = "The SFTP file download failed for "+lfilefrompath+". Verfy file "+; " name, path and connection information. The Chilkat message is "+; losftp.lasterrortext Do sendmessage With lcMessage, lcsubject return ENDIF
Get directory contents
RELEASE loDirListing
*<<<<<<<<<<<< Get FILE handle here for download (separate from directory handle)
lcfHandle = loSftp.OpenFile(ALLTRIM(sftpwork.directory)+'/'+;
ALLTRIM(sftpwork.filename),"readOnly","openExisting")
DO CASE
case (lcfHandle = NULL )
CD ALLTRIM((syspref.basedir))
lcSubject = 'ERROR - Unable to download files from SFTP site for '+;
lfilefrompath
lcMessage = "The SFTP file download failed from source path "+;
lfilefrompath+". Verfy"+;
" file name, path and connection information (open). The Chilkat "+;
message is "+losftp.lasterrortext
Do sendmessage With lcMessage, lcsubject
RETURN
CASE EMPTY(lcfHandle)
CD ALLTRIM((syspref.basedir))
lcSubject = 'ERROR - Unable to download files from SFTP site for '+;
lfilefrompath
lcMessage = "The SFTP file download from source path "+lfilefrompath+;
". Verfy file name, path and connection information (open). The "+;
Chilkat message is "+losftp.lasterrortext
Do sendmessage With lcMessage, lcsubject
return
ENDCASE
* Download the file:
lnSuccess = loSftp.DownloadFile(lcfHandle,ALLTRIM(sftpwork.filename))
IF (lnSuccess <> 1)
CD ALLTRIM((syspref.basedir))
lcSubject = 'Error - Unable to download files from SFTP site for '+;
lfilefrompath
lcMessage = "The SFTP file download failed from source path "+;
lfilefrompath+". Verfy file name, path and connection information "+;
"(download). The Chilkat message is "+losftp.lasterrortext
Do sendmessage With lcMessage, lcsubject
return
ENDIF
* Delete the file downloaded file from the server
lnSuccess = loSftp.RemoveFile(ALLTRIM(sftpwork.directory)+'/'+;
ALLTRIM(sftpwork.filename))
IF (lnSuccess <> 1)
CD ALLTRIM((syspref.basedir))
lcSubject = 'Error - Unable to delete downloaded from SFTP site for '+;
lfilefrompath
lcMessage = "The SFTP file download could not be deleted on the SFTP "+;
site from source path "+lfilefrompath+". Verfy file name, path and "+;
connection information. This file will need to be removed manually. "+;
"The Chilkat message is "+losftp.lasterrortext
Do sendmessage With lcMessage, lcsubject
* don't return if this fails - just send a message.
ENDIF
ENDSCAN
*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Close directory here
Close the directory lnSuccess = loSftp.CloseHandle(lcHandle) IF (lnSuccess <> 1) CD ALLTRIM((syspref.basedir)) lcSubject = 'ERROR - Unable to close download directory on SFTP site for '+; lfilefrompath lcMessage = "The SFTP directory could not be closed through VFP from source "+; " path"+lfilefrompath+". Verfy file name, path and connection information."+; "The Chilkat message is "+losftp.lasterrortext Do sendmessage With lcMessage, lcsubject return ENDIF
Release the sftp object RELEASE losftp
RETURN
The error is coming up when we close the directory at the end of this process:
The SFTP directory could not be closed through VFP - Verfy file name, path and connection information. The Chilkat message is ChilkatLog: CloseHandle: DllDate: Jul 10 2013 ChilkatVersion: 9.4.1.26 UnlockPrefix: unlockkey Username: Server:User Architecture: Little Endian; 32-bit Language: ActiveX VerboseLogging: 0 SshVersion: SSH-2.0-mod_sftp/0.9.9 SftpVersion: 3 handle: 34633936313138333335363539316562 closeHandle: handle: 34633936313138333335363539316562 Sent FXP_CLOSE StatusResponseFromServer: Request: FXP_CLOSE InformationReceivedFromServer: StatusCode: 9 StatusMessage: Invalid handle --InformationReceivedFromServer --StatusResponseFromServer Received a failed status response. --closeHandle Failed. --CloseHandle --ChilkatLog
Margaret,
After calling
loDirListing = loSftp.ReadDir(lcHandle)
the lcHandle is no longer needed because at that point the directory listing has been downloaded and is locally available within the loDirListing object. You may close the lcHandle at this point. In other words:
Download the directory listing: loDirListing = loSftp.ReadDir(lcHandle) IF (loDirListing = NULL ) .. ENDIFlnSuccess = loSftp.CloseHandle(lcHandle) IF (lnSuccess <> 1) ... ENDIF
The remainder of your code, which iterates over the files in the directory, will start here...
Check to see if this resolves the problem.