2

IOUtils.TDirectory.GetDirectoryRoot(Folder) gives me an error when 'Folder' is 259 chars long (yes, it includes the \ separator at the end):

Project Tester.exe raised exception class EPathTooLongException with message 'The specified path is too long'.

I though that I can use up to 260 chars in paths.
enter image description here

Why GetDirectoryRoot does not accept paths that are of Max_Path chars?

Gabriel
  • 20,797
  • 27
  • 159
  • 293
  • My path is 259 chars. So, there is one extra char available for the #0 terminator. But anyway, I work in Delphi. Delphi doesn't use #0 terminators in strings. – Gabriel May 23 '17 at 18:11
  • I assume this is calling a windows api function under the covers, in which case the null terminator will eventually need to be there. Still doesn't explain why 259 is too long. It might have something to do with the specific path. – Millie Smith May 23 '17 at 18:28
  • I got fed with IOUtils library. It has more bugs than lines of code. How the producer of a PROGRAMMING LANGUAGE can release on market libraries that is totally non-functional? And how do they manage to milk so much money from us on this product? Sorry... actually I know... they force us buy those damn "Update Subscriptions" – Gabriel May 23 '17 at 19:00
  • 1
    Well known design defect, copied from the .net libraries IIRC. Best to roll your own. IOUtils is no good. Windows 10 now allows you to bypass that limit completely, and you could always use the `\\?\` prefix to allow longer paths. – David Heffernan May 23 '17 at 20:16
  • @DavidHeffernan - I don't have the new Berlin edition. Do you know if they fixed this library in Berlin? – Gabriel May 24 '17 at 08:02
  • 1
    I don't think this is something that they plan to fix because they regard it as being as designed – David Heffernan May 24 '17 at 08:22

1 Answers1

2

And this is why:

class procedure TDirectory.InternalCheckDirPathParam(const Path: string; const ExistsCheck: Boolean);
begin
  TPath.CheckPathLength(Path, MAX_PATH {$IFDEF MSWINDOWS}- TFile.FCMinFileNameLen{$ENDIF});
 ...
end;

And this is the user manual for this 'wonderful' function:

Returns the root directory for a given path.

Use GetDirectoryRoot to obtain the root directory for a given path. Relative paths are considered relative to the application working directory. The following table lists the parameters expected by this method.

Note: GetDirectoryRoot raises an exception if the given path is invalid or the directory does not exist.

Thank you Embarcadeor/Idera for this high quality job!


So, IOutils cannot be used in conjunction with Max_Path. It uses InternalCheckDirPathParam all over the place!

The solution would be to define your own MaxPath constant:

  {$IFDEF MSWINDOWS}
    MAXPATH= MAX_PATH- 12;               { TFile.FCMinFileNameLen = 12. There is a problem in IOUtils and we cannot user Max_Path. }
  {$ELSE}
    MAXPATH= MAX_PATH;
  {$ENDIF}

So, go now do a Ctrl+Shift+F and check all your code :)

Anyway, a conflict remains: a valid path (260 chars) returned by some API call cannot be passed to IOUtils which only accepts 248 chars. If you find a better solution, let me/us know and I will accept your answer :)

Victoria
  • 7,822
  • 2
  • 21
  • 44
Gabriel
  • 20,797
  • 27
  • 159
  • 293