I'm using WinSCP .NET assembly in my desktop application to transfer files over SFTP protocol and I ran into a problem while transferring some folders from SFTP server into a local machine when files inside remote folder would create deep folder structure on local machine. This is causing error with long file paths:
I've been searching about this problem on forum and found couple of threads and a bug tracked here https://winscp.net/tracker/821.Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll
The thread 0x3ebc has exited with code 0 (0x0).
The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
The thread 0x28f4 has exited with code 0 (0x0).
However, as I saw that it is marked as fixed, I've tried to transfer an remote folder which would create deep file structure on local machine over portable version of WinSCP. And there I found that application is inconsistent.
First, as I've read on forum that some guys had problem to download deep file structure folders over FTP. I've tried this over FTP protocol and I was unable to download folder on my local machine getting error
LOCAL FILE PATH is 325 characters long. Also, there is only 1 file in this folder structure.Error transferring file 'REMOTE FILE PATH'.
Can't open file 'LOCAL FILE PATH'.
System Error. Code: 3.
The system cannot find the path specified
Copying files from remote side failed.
What WinSCP actually did is that it created complete folder structure and then failed to create file inside the latest subfolder (parent folder of the file). Latest subfolder has file path 275 characters long.
Then I've deleted complete folder structure and tried the same process over SFTP protocol. This and every other time I've tried, WinSCP succeeded to write remote file to the desired location on local machine (to the path 375 characters long).
So my conclusion is that WinSCP isn't quite consistent.
I've also noticed some other thing (maybe bug also) in Download dialog box (the one after F5). If you want to download an folder and in Download dialog box in Local directory field you put folder location without "\" at the end, then only selected remote folders content will be downloaded without local folder with remote folders name being created on local machine.
For example, if you have folder "Remote folder" on a remote server and you want to download it in "C:\Download" local folder, if you put "C:\Download" in local directory field, then you'll actually get only contents of "Remote folder" directly in "Download" local folder. However, if you put "C:\Download\" instead in local directory field, you will get a folder with name "Remote folder" created first inside "Download" folder and then get all "Remote folder" contents from the server inside local "Remote folder".
Using this approach (excluding "\" at the end of the path) portable WinSCP isn't then able to download my remote folder over SFTP protocol too. In this case I'm getting error
and it actually creates folder structure until the latest subfolder in file structure. This also happens on FTP protocol when "\" is excluded at the end of given local folder path.Error creating folder '...'
System Error. Code: 206.
The filename or extension is too long
WinSCP version: 5.9.1
OS: Windows 10 Pro Anniversary Update
Protocol: SFTP over .NET assembly
The most important part for me is .NET assembly because I want to achieve to get files from a remote servers which will cause too long paths on local machines through my application. I see that portable WinSCP can transfer files with very long file paths over SFTP protocol but it has problem with FTP protocol and also SFTP protocol through .NET assembly.
Suggestion for possible solution:
In some other section of my application I'm dealing with long file paths over Windows API using GetShortPathName function from kernel32.dll. Documentation for this function can be found here
Important note with this function is that in order to get short file path file needs to exist on given location. Because I have to move some files around in my application storage location, I've come up with a solution to test file existence first and then going through selected long file path from its very first parent folder (selected partition) and then looping to the end of file path doing folder existence check, its creation if it doesn't exist and then collecting its shorter path. At the end, I just append selected file name and then I'm able to successfully move file to desired location.https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getshortpathnamew
If you need some more info, I'm willing to provide and help.