views:

139

answers:

2

There are some folder with more than 100 files on it. But all files and folders names broken with wrong encoding names (UTF->ANSI).

"C:\...\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\Госдача-Лечебни корпус\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\Госдача-Лечебни корпус\вертолетка\Госдача-Лечебни корпус\..."

Regular function Utf8ToAnsi finxing it, but FindFirst can't search folders with names longer than 255 symbols.

It gaves me only 70/100 files.

Need your help, master! ;)

A: 

Change the current directory (ChDir) to the deepest one you know about, and then pass a relative path to FindFirst or FindFirstFile.

No path component in that file name is longer than MAX_PATH characters, so you should be able to work your way into the directories one step at a time.

Beware that multithreaded programs may be sensitive to changes in the current directory since a process has only one current directory shared by all the threads.

Rob Kennedy
+9  A: 

FindFirst wraps the Win32 API function FindFirstFile, and the Unicode version of that function can search paths up to 32,767 characters long if you prepend \\?\ to the path you're passing in, like \\?\C:\Folder\Folder\*.

Since Delphi 2009 and newer call the Unicode funtions for you, you can just use FindFirst and co there. For Delphi 2007 and earlier (ANSI versions), you'll need to call FindFirstFile/FindNextFile/FindClose from Windows.pas directly. For more information check the Naming a file section of the platform SDK.

Do note that using \\?\ disables various bits of path processing though, so make sure it's a fully qualified path without any '.' or '..' entries. You can use the same trick to open file streams, rename, or copy files with longer paths.

The shell (Explorer) doesn't support this though, so you still need to limit those to at most MAX_PATH characters for things like SHFileOperation (to delete to the recycle bin) or ShellExecute. In many cases you can work around the problem by passing in the DOS 8.3 names instead of the long ones. FindFirst's TSearchRec doesn't expose the short names, but FindFirstFile's TWin32FindData structure does as cAlternateFileName.

Craig Peterson