In my (Windows) program a user can input text and that text can be a file or a directory.
Now I want to fix the text case so that the input text match the file system case. For example if a user input:
C:\PROGRAM FILES\FOO\BAR
and the directory exists with this text case:
C:\Program Files\Foo\Bar
I want to return it with the later (correct) text case.
How would I do that in Delphi? I tried using FindFirst
/FindNext
but I don't have the full path in the TSearchRec
(of course I could split the string and do multiple FindFirst
for each level but there must be a better way).
I use Delphi 10.4 if it changes something.
CodePudding user response:
Open a handle to the file/directory using CreateFile()
, and then you can use either
GetFileInformationByHandleEx()
withFileInformationClass
set toFileNameInfo
NtQueryInformationFile()
withFileInformationClass
set toFileNameInformation
CodePudding user response:
I ended up doing this:
uses
System.IOUtils;
function GetCaseSensitivePath(const APath: String): String;
var
Root, CurrPart: String;
PathParts, FileSysEntries: TArray<String>;
NotFound: Boolean;
begin
try
Root := UpperCase(TPath.GetPathRoot(APath));
except
on EArgumentException do
Root := '';
end;
if Root = '' then
begin
Result := APath;
exit;
end;
Result := Root;
NotFound := False;
PathParts := APath.Substring(Root.Length).Split(TPath.DirectorySeparatorChar);
for CurrPart in PathParts do
begin
if not NotFound then
begin
try
FileSysEntries := TDirectory.GetFileSystemEntries(Result, CurrPart);
if Length(FileSysEntries) > 0 then
Result := FileSysEntries[0]
else
NotFound := True;
except
on EDirectoryNotFoundException do
NotFound := True;
end;
end;
if NotFound then
Result := IncludeTrailingPathDelimiter(Result) CurrPart;
end;
end;
The function will try to fix the APath
sent even if it partially exists. If APath
is invalid the result will be APath
as-is.