So, ich hab es jetzt auch in einem Programm versucht,
sowie dort auch explizit nochmal mit der
ANSI-
API,
aber im Windows 11 bekomme ich niemals einen Kurznamen. (außer wenn ich es im Samba auf einen Share des Synology-NAS versuche)
Auf einem Windows Server 2016 dagegen, klappt es, mit dem Kurznamen-Test.
siehe Anhang, die Test.cmd ausführen
So, jetzt bau ich noch ein Drag&Drop-Testprogramm fertig und dann mal beim Kunden nachsehn.
Vielleicht hat es was mit dieser Bermerkung zu GetLongPathName zu tun, wobei ich sie nicht ganz verstehe
Ist schon richtig, auch wenn es schon bissl "eigenartig" ist,
aber selbst wenn dabei ein Fehler drin wäre, dann dürfte nur ein und nicht zwei Zeichen fehlen.
- wenn Fehler (z.B. Buffer zu klein oder nicht angegeben), dann Result=Chars+#0
- wenn kein Fehler (Buffer und groß genug), dann nur Result=Chars (ohne #0)
- so oder so, reingeben muß man immer inkl. #0 (oder 0 wenn Buffer=nil)
und raus bekommt man die benötigte Länge (bei Fehler, bzw. Abfrage) oder nur die Anzahl der Zeichen, wenn es OK war.
Es gibt milliarden Varianten der Implementation.
Da "hier" der Pfad kürzer als MAX_PATH ist, dürfte alles der Nachfolgenden gehen.
Die ersten 3 machen es aber eigetlich richtig und fragen vorher die Länge ab.
Empfehlen würde ich die 2 (meine Implementation
) ... Viele machen es mehr wie bei 3 oder bissl wie 1, aber wozu den Speichermanager unnötig beanspruchen.
Delphi-Quellcode:
function GetShortName(Filename:
string):
string;
var
Len, Res: Cardinal;
Buffer: TBytes;
begin
// so mehr C++-ig
Len := GetShortPathName(PChar(Filename),
nil, 0);
SetLength(Buffer, Len * SizeOf(Char));
// oder halt eigentlich mit Pointer, GetMem und anschließend FreeMem (und natürlich mit einem Try-Finally)
Res := GetShortPathName(PChar(Filename), Pointer(Buffer), Len);
if Res > Len
then
raise Exception.Create('
das sollte zwar nie passieren, da wir die Größe ja vorher abgefragt hatten, aber wir prüfen es einfach nochmal');
SetLength(Result, Res);
MoveMemory(PChar(Result), Pointer(Buffer), Res * SizeOf(Char));
end;
function GetShortName(Filename:
string):
string;
begin
// ich schneide die #0 ab, da String implizit zwei #0#0 am Ende besitzt und Diese auch beschreibbar sind
SetLength(Result, GetShortPathName(PChar(Filename),
nil, 0) - 1);
GetShortPathName(PChar(Filename), PChar(Result), Length(Result) + 1);
end;
function GetShortName(Filename:
string):
string;
begin
// Puffer erstmal inkl. der #0 und dann wieder abschneiden
SetLength(Result, GetShortPathName(PChar(Filename),
nil, 0));
SetLength(Result, GetShortPathName(PChar(Filename), PChar(Result), Length(Result));
// hier müsste man noch -1, wenn die #0 bei OK inkl. wäre
end;
function GetShortName(Filename:
string):
string;
begin
// MAX_PATH = maximal 260 Chars
// 3 = Laufwerk (C:\)
// 256 = Pfad
// 1 = #0
SetLength(Result, MAX_PATH);
SetLength(Result, GetShortPathName(PChar(Filename), PChar(Result), MAX_PATH);
// hier müsste man noch -1, wenn die #0 bei OK inkl. wäre
end;
function GetShortName(Filename:
string):
string;
var
Temp:
array[0..MAX_PATH-1]
of Char;
Len: Cardinal;
begin
Len := GetShortPathName(PChar(Filename), @Temp, MAX_PATH);
SetString(Result, @Temp, Len);
// bei einem Fehler, z.B. wenn Pfad länger MAX_PATH, dann wäre eine #0 im String
//Result := PChar(Result); // den Fehlerfall könnte man so beheben (#0 weg), aber der Pfad bleibt dennoch abgeschnitten (maximal 259 Zeichen)
end;
function GetShortName(Filename:
string):
string;
var
Temp:
array[0..MAX_PATH-1]
of Char;
begin
// einfach blind hindurch
GetShortPathName(PChar(Filename), @Temp, MAX_PATH);
Result := Temp;
end;
function GetShortName(Filename:
string):
string;
var
Temp:
array[0..MAX_PATH-1]
of Char;
begin
// auf Gott vertrauen und hoffen es knallt nicht,
// aber wenn keine #0 im Temp vorkommt, dann ab in die Hölle
GetShortPathName(PChar(Filename), @Temp, MAX_PATH);
Result := PChar(@Temp);
end;
function GetShortName(Filename:
string):
string;
var
Temp:
array[0..MAX_PATH-1]
of Char;
begin
// einfach blind hindurch
if GetShortPathName(PChar(Filename), @Temp, MAX_PATH) <> 0
then
Result := PChar(@Temp)
else
Result := '
';
end;
...