Author: Jonas Bilinkevicius
How do I convert a short (alias) filename or directory name into its long
equivalent?
Answer:
Solve 1:
1 {Parameters:
2
3 shortname:
4 File name or path to convert. This can be a fully qualified file name or a path
5 relative to the current directory. It can contain long and / or short forms for the
6 names.
7
8 Returns:
9 Fully qualified filename using the long names for all elements of the path.
10
11 Description:
12 Recursively uses FindFirst to find the long names for the path elements.
13
14 Error Conditions:
15 Will raise an exception if any part of the path was not found.
16
17 Created:
18 15.01.98 14:09:26 by Peter Below}
19
20 function GetLongFilename(shortname: string): string;
21
22 function GetL(shortname: string): string;
23 var
24 srec: TSearchRec;
25 begin
26 { Lob off the last element of the passed name. If we received only a root name,
27 e.g. c:\, ExtractFileDir returns the path unchanged. }
28 Result := ExtractFileDir(shortname);
29 if (Result <> shortname) then
30 begin
31 { We still have an unconverted path element. So convert the last one in
32 the current shortname and combine the resulting long name with what we get
33 by calling ourselves recursively with the rest of the path. }
34 if FindFirst(shortname, faAnyfile, srec) = 0 then
35 try
36 Result := GetL(Result) + '\' + srec.Name;
37 finally
38 FindClose(srec);
39 end
40 else
41 raise Exception.CreateFmt('Path %s does not exist!', [shortname]);
42 end
43 else
44 { Only the root remains. Remove the backslash since the caller will add it
45 back anyway. }
46 Delete(Result, length(result), 1);
47 end;
48
49 begin
50 { Create fully qualified path and pass it to the converter. }
51 Result := GetL(ExpandFilename(shortname));
52 end;
Solve 2:
53 {Get LFN from 8.3}
54
55 function GetLongPathName(const PathName: string): string;
56 var
57 Drive: string;
58 Path: string;
59 SearchRec: TSearchRec;
60 begin
61 if PathName = '' then
62 Exit;
63 Drive := ExtractFileDrive(PathName);
64 Path := Copy(PathName, Length(Drive) + 1, Length(PathName));
65 if (Path = '') or (Path = '\') then
66 begin
67 Result := PathName;
68 if Result[Length(Result)] = '\' then
69 Delete(Result, Length(Result), 1);
70 end
71 else
72 begin
73 Path := GetLongPathName(ExtractFileDir(PathName));
74 if FindFirst(PathName, faAnyFile, SearchRec) = 0 then
75 begin
76 Result := Path + '\' + SearchRec.FindData.cFileName;
77 FindClose(SearchRec);
78 end
79 else
80 Result := Path + '\' + ExtractFileName(PathName);
81 end;
82 end;
Solve 3:
You could try the following. It should work on Win95 and above.
83 unit WhateverYouWantToCallIt;
84
85 interface
86
87 function LongPathFromShort(const ShortPath: string): string;
88
89 implementation
90
91 uses
92 Windows, SysUtils, ActiveX, ShlObj;
93
94 function LongPathFromShort(const ShortPath: string): string;
95 var
96 iAttributes: Cardinal;
97 iEaten: Cardinal;
98 IntfDesktop: IShellFolder;
99 IntfMalloc: IMalloc;
100 pItemList: PItemIDList;
101 sFile: WideString;
102 szFile: array[0..MAX_PATH] of Char;
103 begin
104 Result := ShortPath;
105 if not FileExists(ShortPath) then
106 Exit;
107 if Succeeded(SHGetDesktopFolder(IntfDesktop)) then
108 begin
109 sFile := ShortPath;
110 iAttributes := 0;
111 if Succeeded(IntfDesktop.ParseDisplayName(0, nil, POleStr(sFile),
112 iEaten, pItemList, iAttributes)) then
113 begin
114 SHGetPathFromIDList(pItemList, szFile);
115 Result := szFile;
116 SHGetMalloc(IntfMalloc);
117 IntfMalloc.Free(pItemList)
118 end
119 end
120 end;
121
122 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.
123
124 function GetLongName(const APath: string): string;
125 var
126 Buffer: array[0..MAX_PATH] of Char;
127 Required: Integer;
128 begin
129 Required := GetLongPathName(PChar(APath), Buffer, Length(Buffer));
130 if Required > MAX_PATH then {Buffer too small}
131 begin
132 SetLength(Result, Required - 1);
133 GetLongPathName(PChar(APath), Pointer(Result), Required);
134 end
135 else if Required = 0 then {Error}
136 Result := APath
137 else
138 SetString(Result, Buffer, Required);
139 end;
140
141 for an ANSI only function you can reduce the above to:
142
143 function GetLongName(const APath: AnsiString): AnsiString;
144 var
145 Buffer: array[0..MAX_PATH] of AnsiChar;
146 Required: Integer;
147 begin
148 Required := GetLongPathNameA(PChar(APath), Buffer, Length(Buffer));
149 SetString(Result, Buffer, Required);
150 end;
151
152 //If you need to support for Win95 or WinNT, you can use this function:
153
154 function GetLongPathName(Path: string): string;
155 var
156 I: Integer;
157 SearchHandle: THandle;
158 FindData: TWin32FindData;
159 IsBackSlash: Boolean;
160 begin
161 Path := ExpandFileName(Path);
162 Result := ExtractFileDrive(Path);
163 I := Length(Result);
164 if Length(Path) <= I then {only drive}
165 Exit;
166 if Path[I + 1] = '\' then
167 begin
168 Result := Result + '\';
169 Inc(I);
170 end;
171 Delete(Path, 1, I);
172 repeat
173 I := Pos('\', Path);
174 IsBackSlash := I > 0;
175 if not IsBackSlash then
176 I := Length(Path) + 1;
177 SearchHandle := FindFirstFile(PChar(Result + Copy(Path, 1, I - 1)), FindData);
178 if SearchHandle <> INVALID_HANDLE_VALUE then
179 begin
180 try
181 Result := Result + FindData.cFileName;
182 if IsBackSlash then
183 Result := Result + '\';
184 finally
185 Windows.FindClose(SearchHandle);
186 end;
187 end
188 else
189 begin
190 Result := Result + Path;
191 Break;
192 end;
193 Delete(Path, 1, I);
194 until Length(Path) = 0;
195 end;
|