長いパス名(ファイル名)から8.3の短いパス名を取得する方法は、.NET Frameworkでは用意されていません。Win32 APIのGetShortPathName関数を使う必要があります。
以下にGetShortPathName関数を使って短いパス名を取得する例を示します。
<System.Runtime.InteropServices.DllImport("kernel32.dll", _ CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _ Private Shared Function GetShortPathName( _ <System.Runtime.InteropServices.MarshalAs( _ System.Runtime.InteropServices.UnmanagedType.LPTStr)> _ ByVal lpszLongPath As String, _ <System.Runtime.InteropServices.MarshalAs( _ System.Runtime.InteropServices.UnmanagedType.LPTStr)> _ ByVal lpszShortPath As System.Text.StringBuilder, _ ByVal cchBuffer As Integer) As Integer End Function ''' <summary> ''' 短いファイルパス名を取得する ''' </summary> ''' <param name="path">ファイルのパス</param> ''' <returns>短いパス名</returns> Public Shared Function GetShortPath(ByVal path As String) As String Dim sb As New System.Text.StringBuilder(1023) Dim ret As Integer = GetShortPathName(path, sb, sb.Capacity) If ret = 0 Then Throw New Exception("短いファイル名の取得に失敗しました。") End If Return sb.ToString() End Function 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click Console.WriteLine(GetShortPath("C:\Documents and Settings")) End Sub
[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern uint GetShortPathName( [System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.LPTStr)] string lpszLongPath, [System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.LPTStr)] System.Text.StringBuilder lpszShortPath, uint cchBuffer); /// <summary> /// 短いファイルパス名を取得する /// </summary> /// <param name="path">ファイルのパス</param> /// <returns>短いパス名</returns> public static string GetShortPath(string path) { System.Text.StringBuilder sb = new System.Text.StringBuilder(1024); uint ret = GetShortPathName(path, sb, (uint)sb.Capacity); if (ret == 0) throw new Exception("短いファイル名の取得に失敗しました。"); return sb.ToString(); } //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { Console.WriteLine(GetShortPath("C:\\Documents and Settings")); }
.NET Framework 3.0からは、Path.GetFullPathメソッドを使って、短いパス名から長いパス名を取得することができます。
MSDNのPath.GetFullPathメソッドの説明によると、.NET Framework 2.0までは「ショートファイル名で渡すと、長いファイル名に拡張されません」と書かれていますので、.NET Framework 2.0以下ではこの方法は使えないかもしれません。(私が試した限りでは、.NET Framework 2.0でも長いパス名に変換できました。)
上記の方法が使用できない場合は、面倒ですが、ルートフォルダから順番にDirectoryInfoクラスのGetFileSystemInfosプロパティを使って一つずつ正しいフォルダ名(最後はファイル名)を取得していくという方法が考えられます。このような方法は、ニュースグループのこちらの投稿などで紹介されています。
上に紹介した記事にあるコードで十分ですが、私なりに書いたものを以下に紹介します。
''' <summary> ''' 短いファイル名から長いファイル名を取得する ''' </summary> ''' <param name="path">短いファイル名(フルパス)</param> ''' <returns>長いファイル名</returns> Public Shared Function GetLongPath(ByVal path As String) As String 'ルートディレクトリを取得 Dim root As String = System.IO.Path.GetPathRoot(path) 'ルートディレクトリ以降を'\'で分割 Dim folders As String() = path.Substring(root.Length). _ Split(System.IO.Path.DirectorySeparatorChar) Dim res As String = root Dim name As String For Each name In folders Dim di = New DirectoryInfo(res) 'ディレクトリ(またはファイル)を探す Dim fsi As System.IO.FileSystemInfo() = _ di.GetFileSystemInfos(name) If fsi.Length = 1 Then res = fsi(0).FullName Else Throw New Exception("ERROR") End If Next name Return res End Function
/// <summary> /// 短いファイル名から長いファイル名を取得する /// </summary> /// <param name="path">短いファイル名(フルパス)</param> /// <returns>長いファイル名</returns> public static string GetLongPath(string path) { //ルートディレクトリを取得 string root = System.IO.Path.GetPathRoot(path); //ルートディレクトリ以降を'\'で分割 string[] folders = path.Substring(root.Length) .Split(System.IO.Path.DirectorySeparatorChar); string res = root; foreach (string name in folders) { System.IO.DirectoryInfo di = new DirectoryInfo(res); //ディレクトリ(またはファイル)を探す System.IO.FileSystemInfo[] fsi = di.GetFileSystemInfos(name); if (fsi.Length == 1) res = fsi[0].FullName; else throw new Exception("ERROR"); } return res; }