Convert between long and short file names #6

Here's a way to convert between short 8.3 DOS file names and long file names.

First function will convert long file names to the 8.3 format:

uses
  Windows, SysUtils;

function GetShortName(sLongName: string): string;
var
  sShortName    : string;
  nShortNameLen : integer;
begin
  SetLength(sShortName, MAX_PATH);
  nShortNameLen := GetShortPathName(
    PChar(sLongName), PChar(sShortName), MAX_PATH - 1
  );
  if (0 = nShortNameLen) then
  begin
    // handle errors...
  end;
  SetLength(sShortName, nShortNameLen);
  Result := sShortName;
end;

Now a function to convert a short file name into a long file name:

uses
  Windows, SysUtils;

function __GetLongName(sShortName: string; var bError : boolean): string;
var
  bAddSlash : boolean;
  SearchRec : TSearchRec;
  nStrLen   : integer;
begin
  bError    := False;
  Result    := sShortName;
  nStrLen   := Length(sShortName);
  bAddSlash := False;

  if('\' = sShortName[nStrLen]) then
  begin
    bAddSlash := True;
    SetLength(sShortName, nStrLen - 1);
    dec(nStrLen);
  end;

  if (nStrLen - Length(ExtractFileDrive(sShortName))) > 0 then
  begin
    if 0 = FindFirst(sShortName, faAnyFile, SearchRec) then
    begin
      Result := ExtractFilePath(sShortName) + SearchRec.Name;
      if bAddSlash then
      begin
        Result := Result + '\';
      end;
    end
    else
    begin
      // handle errors...
      bError := True;
    end;
    FindClose(SearchRec);
  end;
end;

function GetLongName(sShortName: string): string;
var
  s      : string;
  p      : integer;
  bError : boolean;
begin
  Result := sShortName;

  s := '';
  p := Pos('\', sShortName);
  while p > 0 do
  begin
    s := __GetLongName(s + Copy(sShortName, 1, p), bError);
    Delete(sShortName, 1, p);
    p := Pos('\', sShortName);

    if bError then
      Exit;
  end;
  if '' <> sShortName then
  begin
    s := __GetLongName(s + sShortName, bError);
    if bError then
      Exit;
  end;
  Result := s;
end;

Let's give our functions a try:

procedure Test;
const
  csTest = 'C:\Program Files';
var
  sShort,
  sLong: string;
begin
  sShort := GetShortName(csTest);
  MessageDlg(
    'Short name for "' + csTest + '" is "' + sShort + '"',
    mtInformation, [mbOk], 0
  );
  sLong := GetLongName(sShort);
  MessageDlg(
    'Long name for "' + sShort + '" is "' + sLong + '"',
     mtInformation, [mbOk], 0
  );
end;
See also the LongToShortFilePath & ShortToLongFilePath routines in the DelphiDabbler Code Snippets Database.
Author: Unknown
Added: 2007/06/02
Last updated: 2013/10/12