login about faq

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

asked Aug 08 '13 at 18:42

margaretduddy's gravatar image

margaretduddy
1112

edited Aug 08 '13 at 18:54


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.

link

answered Aug 09 '13 at 10:24

chilkat's gravatar image

chilkat ♦♦
11.8k316358421

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

  • Chilkat - Important: It is helpful to send the contents of the sftp.LastErrorText property
  • 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.

  • The standard SSH port = 22, but not always used.
  • The hostname may be a hostname or IP address. lcHostname = ALLTRIM(sftp_load.connectip)
  • Use the default port in this case lnport = sftp_load.port

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

  • Login info pulled from metadata
  • Authenticate with the SSH server. Chilkat SFTP supports both password-based
  • authenication as well as public-key authentication. Use password authenication. SELECT sftpwork lnSuccess = loSftp.AuthenticatePw(ALLTRIM(sftp_load.loginid), ; ALLTRIM(sftp_load.loginpw))

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

  • After authenticating, the SFTP subsystem must be initialized: lnSuccess = loSftp.InitializeSftp() IF (lnSuccess <> 1) CD ALLTRIM((syspref.basedir)) lcSubject = 'ERROR - Unable to authenticate SFTP 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 ENDIF

*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Get DIRECTORY handle here

  • Open a directory on the server...
  • Paths starting with a slash are "absolute", and are relative to the root of the file
  • system.
  • Names starting with any other character are relative to the user's default directory
  • (home directory). A path component of ".." refers to the parent directory, and "."
  • refers to the current directory.

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

  • Each file will have a unique name - we need to capture the names of all files
  • available for download here
  • Iterate over the files. n = loDirListing.NumFilesAndDirs IF (n > 0) FOR i = 0 TO n - 1 loFileObj = loDirListing.GetFileObject(i) * Pickup the file names available for download INSERT INTO sftpwork (directory,filename,download,filetype) VALUES (lfilefrompath,lofileobj.filename,.t.,loFileObj.filetype) RELEASE loFileObj NEXT ENDIF

RELEASE loDirListing

  • Download the files (use lcFHandle for handle value to distinguish from directory
  • handle set above) SELECT sftpwork GO top SCAN
    • Only download specific files here - no subdirectories DO CASE
    • Don't download directories CASE sftpwork.filetype ='directory' OR sftpwork.filename='.' OR ; sftpwork.filename='..' LOOP
    • Only download files with certain prefix and that are not xml files CASE INLIST(lfilefrompath,'SHP','RCP') AND ; !RIGHT(ALLTRIM(sftpwork.filename),4) ='.XML' LOOP
    • Don't download files we already have (just in case) CASE FILE(ADDBS(ALLTRIM(syspref.inbounddir))+ALLTRIM(sftpwork.filename)) ; OR FILE(ADDBS(ALLTRIM(syspref.archiveindir))+ALLTRIM(sftpwork.filename)) LOOP ENDCASE

*<<<<<<<<<<<< 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 to base directory CD (syspref.basedir)

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

link
This answer is marked "community wiki".

answered Aug 09 '13 at 11:46

margaretduddy's gravatar image

margaretduddy
1112

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 ) 
..
ENDIF

lnSuccess = 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.

link

answered Aug 14 '13 at 17:31

chilkat's gravatar image

chilkat ♦♦
11.8k316358421

Thanks for the advice! We will make that change and report back.

(Aug 14 '13 at 19:00) margaretduddy
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or __italic__
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×2

Asked: Aug 08 '13 at 18:42

Seen: 1,551 times

Last updated: Aug 14 '13 at 19:00

powered by OSQA