Announcement

Collapse
No announcement yet.

8.3-Dateinamen -> Lange Dateinamen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • 8.3-Dateinamen -> Lange Dateinamen

    Wie bekomme ich aus einer Dateiangabe der Art C:\Progra~1\... einen langen Dateinamen der Art C:\Programme\...?

    Hab zwar schon einige Zeit in der Delphi und Win32-Hilfe gesucht, aber nichts passendes gefunden!

  • #2
    Hallo Bernhard,

    die API-Funktion <b>SHGetFileInfo</b> liefert auf Wunsch den langen Dateinamen für einen kurzen Dateinamen zurück:

    <pre>
    uses ShellAPI;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    aInfo: TSHFileInfo;
    begin
    SHGetFileInfo('C:\temp\5019_0~1.doc', 0, aInfo, Sizeof(aInfo), SHGFI_DISPLAYNAME);
    ShowMessage(aInfo.szDisplayName);
    end;
    </pre&gt

    Comment


    • #3
      Das dumme an dieser Funktion ist, daß nicht der gesammte Dateiname mit Pfadangabe übersetzt wird sondern nur ein Teil:

      Bei einer Datei der Art: <b>C:\Progra~1\Unterv~1\Langer~1.Exe</b> kommt nur <b>Langer Dateiname.exe</b> zurück.<br>
      Bei der Übergabe des Pfades der Art: <b>C:\Progra~1\Unterv~1\</b> kommt nur der letzte Pfadteil zurück (<b>Unterverzeichnis</b>). Ich muß also die einzelnene Pfadangaben einzeln "übersetzen" und wieder zusammenbauen!

      Mach ich irgendwas falsch, oder muß ich den Weg zu Fuß implementieren

      Comment


      • #4
        Hallo,

        nein - das Aufstückeln und Zusammenbauen von Hand ist nicht notwendig. Ich würde die offiziellen COM-Funktionen des Betriebssystems heranziehen und über die <b>IShellLink</b>-Abfrage die Arbeit an Win32 weiterdelegieren. Das folgende Beispiel für Delphi 5 liefert den vollständigen Pfad in langenen Dateinamen zurück:
        <pre>
        uses ComObj, ActiveX, ShlObj;

        function GetLongPathName(ShortPathName: String): String;
        var
        aSL : IShellLink;
        szPath : array[0..MAX_PATH] of Char;
        aWFD : TWin32FindData;
        begin
        Result := '';
        StrPcopy(szPath, ShortPathName);
        OleCheck(CoCreateInstance(CLSID_ShellLink, nil,
        CLSCTX_INPROC_SERVER,IID_IShellLinkA , aSL));
        OleCheck(aSL.SetPath(szPath));
        OleCheck(aSL.GetPath(szPath, MAX_PATH, aWFD, SLGP_UNCPRIORITY));
        Result := szPath;
        end;

        procedure TForm1.Button1Click(Sender: TObject);
        begin
        ShowMessage(GetLongPathName('C:\Temp\TESTPF~1\LANG ER~1.TXT'));
        end;
        </pre&gt

        Comment


        • #5
          Danke für Deine Hilfe!

          Hast mir einiges an weiterer Sucharbeit erspart

          Comment


          • #6
            Hallo,

            dies Lösung von Andreas Kosch ist zumindest beim ersten Aufruf sehr langsam. Im Netz habe ich vor einiger Zeit folgende "schnellere" Lösung gefunden (mit einer kleinen Modifikation von mir):

            <PRE>
            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) &lt;= I then
            Exit; // only drive

            if copy (Path, i + 1, 1) = '\' then begin // CM: copy statt if Path[I + 1] = '\' then begin

            Result := Result + '\';
            inc (i);
            end;
            Delete(Path, 1, i);

            repeat
            i := Pos ('\', Path);
            IsBackSlash := i &gt; 0;
            if not IsBackSlash then
            i := Length (Path) + 1;

            SearchHandle := FindFirstFile (PChar (Result + copy (Path, 1, i - 1)), FindData);
            if SearchHandle &lt;&gt; 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;
            </PRE&gt

            Comment


            • #7
              Hallo,

              dies Lösung von Andreas Kosch ist zumindest beim ersten Aufruf sehr langsam. Im Netz habe ich vor einiger Zeit folgende "schnellere" Lösung gefunden (mit einer kleinen Modifikation von mir):

              <PRE>
              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) &lt;= I then
              Exit; // only drive

              if copy (Path, i + 1, 1) = '\' then begin // CM: copy statt if Path[I + 1] = '\'
              Result := Result + '\';
              inc (i);
              end;
              Delete(Path, 1, i);

              repeat
              i := Pos ('\', Path);
              IsBackSlash := i &gt; 0;
              if not IsBackSlash then
              i := Length (Path) + 1;

              SearchHandle := FindFirstFile (PChar (Result + copy (Path, 1, i - 1)), FindData);
              if SearchHandle &lt;&gt; 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;
              </PRE&gt

              Comment

              Working...
              X