2010. február 7., vasárnap
Convert short file names to long ones
Problem/Question/Abstract:
How do I convert a short (alias) filename or directory name into its long equivalent?
Answer:
Solve 1:
{Parameters:
shortname:
File name or path to convert. This can be a fully qualified file name or a path relative to the current directory. It can contain long and / or short forms for the names.
Returns:
Fully qualified filename using the long names for all elements of the path.
Description:
Recursively uses FindFirst to find the long names for the path elements.
Error Conditions:
Will raise an exception if any part of the path was not found.
Created:
15.01.98 14:09:26 by Peter Below}
function GetLongFilename(shortname: string): string;
function GetL(shortname: string): string;
var
srec: TSearchRec;
begin
{ Lob off the last element of the passed name. If we received only a root name,
e.g. c:\, ExtractFileDir returns the path unchanged. }
Result := ExtractFileDir(shortname);
if (Result <> shortname) then
begin
{ We still have an unconverted path element. So convert the last one in
the current shortname and combine the resulting long name with what we get
by calling ourselves recursively with the rest of the path. }
if FindFirst(shortname, faAnyfile, srec) = 0 then
try
Result := GetL(Result) + '\' + srec.Name;
finally
FindClose(srec);
end
else
raise Exception.CreateFmt('Path %s does not exist!', [shortname]);
end
else
{ Only the root remains. Remove the backslash since the caller will add it
back anyway. }
Delete(Result, length(result), 1);
end;
begin
{ Create fully qualified path and pass it to the converter. }
Result := GetL(ExpandFilename(shortname));
end;
Solve 2:
{Get LFN from 8.3}
function GetLongPathName(const PathName: string): string;
var
Drive: string;
Path: string;
SearchRec: TSearchRec;
begin
if PathName = '' then
Exit;
Drive := ExtractFileDrive(PathName);
Path := Copy(PathName, Length(Drive) + 1, Length(PathName));
if (Path = '') or (Path = '\') then
begin
Result := PathName;
if Result[Length(Result)] = '\' then
Delete(Result, Length(Result), 1);
end
else
begin
Path := GetLongPathName(ExtractFileDir(PathName));
if FindFirst(PathName, faAnyFile, SearchRec) = 0 then
begin
Result := Path + '\' + SearchRec.FindData.cFileName;
FindClose(SearchRec);
end
else
Result := Path + '\' + ExtractFileName(PathName);
end;
end;
Solve 3:
You could try the following. It should work on Win95 and above.
unit WhateverYouWantToCallIt;
interface
function LongPathFromShort(const ShortPath: string): string;
implementation
uses
Windows, SysUtils, ActiveX, ShlObj;
function LongPathFromShort(const ShortPath: string): string;
var
iAttributes: Cardinal;
iEaten: Cardinal;
IntfDesktop: IShellFolder;
IntfMalloc: IMalloc;
pItemList: PItemIDList;
sFile: WideString;
szFile: array[0..MAX_PATH] of Char;
begin
Result := ShortPath;
if not FileExists(ShortPath) then
Exit;
if Succeeded(SHGetDesktopFolder(IntfDesktop)) then
begin
sFile := ShortPath;
iAttributes := 0;
if Succeeded(IntfDesktop.ParseDisplayName(0, nil, POleStr(sFile),
iEaten, pItemList, iAttributes)) then
begin
SHGetPathFromIDList(pItemList, szFile);
Result := szFile;
SHGetMalloc(IntfMalloc);
IntfMalloc.Free(pItemList)
end
end
end;
end.
Solve 4:
GetFullPathName converts a relative path to an absolute path. You can use GetLongPathName, but this requires Win98 and later or Win2k and later.
function GetLongName(const APath: string): string;
var
Buffer: array[0..MAX_PATH] of Char;
Required: Integer;
begin
Required := GetLongPathName(PChar(APath), Buffer, Length(Buffer));
if Required > MAX_PATH then {Buffer too small}
begin
SetLength(Result, Required - 1);
GetLongPathName(PChar(APath), Pointer(Result), Required);
end
else if Required = 0 then {Error}
Result := APath
else
SetString(Result, Buffer, Required);
end;
For an ANSI only function you can reduce the above to:
function GetLongName(const APath: AnsiString): AnsiString;
var
Buffer: array[0..MAX_PATH] of AnsiChar;
Required: Integer;
begin
Required := GetLongPathNameA(PChar(APath), Buffer, Length(Buffer));
SetString(Result, Buffer, Required);
end;
If you need to support for Win95 or WinNT, you can use this function:
function GetLongPathName(Path: string): string;
var
I: Integer;
SearchHandle: THandle;
FindData: TWin32FindData;
IsBackSlash: Boolean;
begin
Path := ExpandFileName(Path);
Result := ExtractFileDrive(Path);
I := Length(Result);
if Length(Path) <= I then {only drive}
Exit;
if Path[I + 1] = '\' then
begin
Result := Result + '\';
Inc(I);
end;
Delete(Path, 1, I);
repeat
I := Pos('\', Path);
IsBackSlash := I > 0;
if not IsBackSlash then
I := Length(Path) + 1;
SearchHandle := FindFirstFile(PChar(Result + Copy(Path, 1, I - 1)), FindData);
if SearchHandle <> INVALID_HANDLE_VALUE then
begin
try
Result := Result + FindData.cFileName;
if IsBackSlash then
Result := Result + '\';
finally
Windows.FindClose(SearchHandle);
end;
end
else
begin
Result := Result + Path;
Break;
end;
Delete(Path, 1, I);
until Length(Path) = 0;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése