Topic "Long file paths support problem and inconsistency"

Author Message
jovanpn
[View user's profile]

Joined: 2016-09-12
Posts: 3
Hi,

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:
Quote:
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).

I've been searching about this problem on forum and found couple of threads and a bug tracked here https://winscp.net/tracker/show_bug.cgi?id=821.

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
Quote:
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.

LOCAL FILE PATH is 325 characters long. Also, there is only 1 file in this folder structure.
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
Quote:
Error creating folder '...'
System Error. Code: 206.
The filename or extension is too long

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.

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
Quote:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989.aspx

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.

If you need some more info, I'm willing to provide and help.
Advertisements
martin
[View user's profile]
Site Admin
Joined: 2002-12-10
Posts: 25025
Location: Prague, Czechia
As the tracker shows, long paths are indeed supported for SFTP protocol only.

Regarding your .NET assembly problem:
I do not think the assembly ever throws the PathTooLongException. The assembly does not work with the files. It's WinSCP process that does. And it's not a .NET process.
Please show us a complete callstack of the exception.
jovanpn
[View user's profile]

Joined: 2016-09-12
Posts: 3
Here is the StackTrace from the exception:
Quote:
Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll
at System.IO.PathHelper.GetFullPathName()
at System.IO.Path.LegacyNormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
at System.IO.Path.GetFullPathInternal(String path)
at System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)
at net2air.SFTP.Download(String remoteUrl, String localUrl) in E:\Projects\net2air\net2air\SFTP.vb:line 333


I agree that .NET assembly might not throw PathTooLongException but as I'm aware, .NET assembly start WinSCP.exe process to handle SFTP connection and download process. This is why .NET assembly requires WinSCP.exe file to be next to the dll file or that path to the WinSCP.exe file is provided to .NET assembly through the code. So probably that WinSCP.exe process doesn't handle long paths very well.
martin
[View user's profile]
Site Admin
Joined: 2002-12-10
Posts: 25025
Location: Prague, Czechia
There's no frame from WinSCP .NET assembly in the stack trace.

And the winscp.exe is not .NET application, so it cannot throw .NET exceptions. And even if it could, the exception cannot cross process boundaries anyway, so you would not be able to catch it in your application.

Sorry, but so far, I do not see any evidence that you problem has anything to do with WinSCP.
jovanpn
[View user's profile]

Joined: 2016-09-12
Posts: 3
I'm very sorry Martin, you are right! It isn't WinSCP bug. I was looking wrong at StackTrace. It's the problem with CreateDirectory function I'm using to create folder structure when downloading a file.
Sorry once more for bothering you because of my mistake!
Advertisements

You can post new topics in this forum






Search Site

What is WinSCP?

It is award-winning SFTP client, SCP client, FTPS client and FTP client integrated into one software program for file transfer to FTP server or secure SFTP server. [More]

And it's free!

Donate

About donations

$9   $19   $49   $99

About donations

Recommend

WinSCP Privacy Policy

WinSCP License