Kurze und lange Dateinamen konvertieren

Veröffentlicht: 04. Apr 2005
Von Mathias Schiffer

In diesem MSDN Quickie zeigt Mathias Schiffer, wie Sie Pfadangaben der alten 8.3-Namenskonvention in deren längere Pendants umwandeln können – Rückwärtsgang inklusive.

Als Anwender freuen wir uns seit gut zehn Jahren darüber, nicht mehr an die enge 8.3-Dateinamenskonvention gebunden zu sein, die bis zu Windows 95 zum Alltag jedes Windows-Anwenders gehörte. Als Entwickler haben wir es leider nicht ganz so einfach: Immer wieder tauchen die durch Tilden geprägten Abkürzungen langer Pfade auf. Sei es bei Verwendung eines alten Kommandozeilenwerkzeugs, bei der Kommunikation mit 16-Bit Windows-Anwendungen oder bei anderen unliebsamen Weggefährten aus der Vergangenheit – die Tilde scheint einfach nicht totzukriegen zu sein.

Glücklicherweise können Sie in Ihren 32-Bit Anwendungen rein technisch betrachtet auch die kurzen Versionen der Pfade direkt verwenden, statt diese zunächst in ihre langen Pendants umwandeln zu müssen. Für die Ausgabe an den Endanwender eignen sie sich hingegen nur wenig. Benötigen Sie in umgekehrter Richtung die 8.3-Version eines gegebenen längeren Pfades (etwa zur Übergabe an eine Fremdanwendung), so kommen Sie um die Umwandlung in keinem Fall herum.

Obwohl Microsoft selber sich in den meisten Belangen noch immer an die 8.3-Namenskonvention hält und damit Problembewusstsein an den Tag legt, findet sich im .NET Framework selbst in plattformspezifischen Namespaces keine Unterstützung für die Umwandlung zwischen den traditionellen und den bequemen Pfadvarianten. Die Windows-Plattform stellt diese Möglichkeiten jedoch zur Verfügung: Unter Verzicht auf die theoretisch erreichbare Plattformunabhängigkeit von .NET-Kompilaten können Sie diese Möglichkeiten durch die Definition von Win32 API-Funktionen nutzen.

Der folgende Beispielcode zeigt, wie man die Funktionen GetShortPathName und GetLongPathName aus dem Win32 API unter Visual Basic .NET deklariert und nutzt, um diese gegenseitigen Umwandlungen vorzunehmen. Im Beispielcode erhalten die API-Funktionen jeweils das Präfix „PInvoke“, um auch bei der Benutzung im Sourcecode darauf hinzuweisen, dass es sich um Funktionen handelt, die nicht vom .NET Framework, sondern von der Plattform (Windows) selber zur Verfügung gestellt werden.

  Private Declare Function PInvokeGetShortPathName _
    Lib "kernel32" Alias "GetShortPathNameA" ( _
    ByVal strLongPath As String, _
    ByVal strShortPath As String, _
    ByVal intBufferLen As Integer _
    ) As Integer
  
  Private Declare Function PInvokeGetLongPathName _
    Lib "kernel32" Alias "GetLongPathNameA" ( _
    ByVal strShortPath As String, _
    ByVal strLongPath As String, _
    ByVal intBufferLen As Integer _
    ) As Integer
  
  
  Public Function GetShortPathname(ByVal LongPathName As String) As String
    ' Ermittelt aus einem langen Dateipfad dessen Repräsentation in 8.3-Konvention.
    ' Der im Parameter LongPathName übergebene Pfad muss existieren.
    Dim strShortName As String
    Dim iLen As Integer
  
    Try
  
      ' Benötigte Stringlänge ermitteln
      iLen = PInvokeGetShortPathName(LongPathName, strShortName, 0)
  
      ' Stringspeicher reservieren
      strShortName = Space(iLen - 1)
  
      ' Den kurzen Pfadnamen abholen
      Call PInvokeGetShortPathName(LongPathName, strShortName, iLen)
  
      ' Ergebnis als Rückgabewert verwenden
      Return strShortName
  
    Catch ex As Exception
    End Try
  
  End Function
  
  
  Public Function GetLongPathname(ByVal ShortPathName As String) As String
    ' Ermittelt aus einem Dateipfad nach 8.3-Konvention dessen "lange" Repräsentation.
    ' Der im Parameter ShortPathName übergebene Pfad muss existieren.
    '
    ' Hinweis: Die grundlegende API-Funktion GetLongPathname steht unter Windows NT4
    ' nicht zur Verfügung, das .NET Framework 1.0/1.1 ist jedoch auch für NT4 geeignet.
    ' Hier sind erforderlichenfalls alternative Herangehensweisen notwendig.
    Dim strLongName As String
    Dim iLen As Integer
  
    Try
  
      ' Benötigte Stringlänge ermitteln
      iLen = PInvokeGetLongPathName(ShortPathName, strLongName, 0)
  
      ' Stringspeicher reservieren
      strLongName = Space(iLen - 1)
  
      ' Den langen Pfadnamen abholen
      Call PInvokeGetLongPathName(ShortPathName, strLongName, iLen)
  
      ' Ergebnis als Rückgabewert verwenden
      Return strLongName
  
    Catch ex As Exception
    End Try
  
  End Function

Mathias Schiffer widmet sich als freier Softwareentwickler und Technologievermittler größeren Projekten ebenso wie arbeitserleichternden Alltagslösungen. Seit Jahren gibt er sein Wissen in unzähligen Publikationen auch an andere Entwickler und Entscheider weiter. Sie erreichen ihn per E-Mail an die Adresse Schiffer@mvps.org.


Anzeigen: