長いパス名(ファイル名)から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; }