やはり自力で書いてみた。一応、動くようだ。ネットワークのパスが渡されても動くかもしれない。
Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Private Const MAX_PATH = 260 Private Type WIN32_FIND_DATA dwFileAttributes As Long ftCreationTime As FILETIME ftLastAccessTime As FILETIME ftLastWriteTime As FILETIME nFileSizeHigh As Long nFileSizeLow As Long dwReserved0 As Long dwReserved1 As Long cFileName As String * MAX_PATH cAlternate As String * 14 End Type Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long Private Const INVALID_HANDLE_VALUE = -1
'----------------------------------------------------------------------- ' 関数名 : CnvShortToLong ' 機能 : 短いファイル名から長いファイル名に変換する ' 引数 : (in) ファイルの短いファイル名 ' 戻り値 : 変換された長いファイル名 ' 備 考 : ファイル、ディレクトリドンと来い!! ネットワークパスも多分大丈夫 ' 引数に ? や * で終わる値が渡された場合、エラーにするとよいかも '----------------------------------------------------------------------- Public Function CnvShortToLong(ByVal ShortFileName As String) As String Dim udtW32FD As WIN32_FIND_DATA Dim hFindFile As Long 'ファイル・ディレクトリのハンドル Dim FoundPos As Long Dim NameParts() As String Dim ArrayIndex As Long Dim i As Long Dim TargetFileName As String Dim IsDirectory As Boolean '存在チェック hFindFile = FindFirstFile(ShortFileName, udtW32FD) If hFindFile = INVALID_HANDLE_VALUE Then Exit Function Else IsDirectory = CBool(udtW32FD.dwFileAttributes And vbDirectory) End If Call FindClose(hFindFile) hFindFile = 0 '後ろで使用するので初期化しておこう 'ディレクトリである場合 If IsDirectory Then '最後尾が \ でない場合は付加する '\ を付加しないと下記の Instr で一番後ろのディレクトリを取得できなくなるので If Right$(ShortFileName, 1) <> "\" Then ShortFileName = ShortFileName & "\" End If '0番目のメモリー確保 ReDim Preserve NameParts(ArrayIndex) As String 'ネットワーク FoundPos = InStr(ShortFileName, "\\") If FoundPos > 0 Then NameParts(ArrayIndex) = "\\" '通常のドライブ Else FoundPos = InStr(ShortFileName, "\") NameParts(ArrayIndex) = Left$(ShortFileName, FoundPos) End If '\が見つからないなら終了。ここで終了することは理論的にありえない If FoundPos = 0 Then Exit Function '\単位に分ける FoundPos = FoundPos + IIf(Len(NameParts(ArrayIndex)) = 2, Len("\\"), Len("\")) Do '被交換文字列検索 FoundPos = InStr(FoundPos, ShortFileName, "\") '検索文字列が見つからなかったらループ終了 If FoundPos = 0 Then Exit Do 'インデックスを増やしてメモリー確保 ArrayIndex = ArrayIndex + 1 ReDim Preserve NameParts(ArrayIndex) As String NameParts(ArrayIndex) = Left$(ShortFileName, FoundPos - 1) '最後尾が \ である場合は削除する '\ で終わっていると FindFirstFile 関数が INVALID_HANDLE_VALUE 'を返すため(んなアホな!!) If Right$(NameParts(ArrayIndex), 1) = "\" Then NameParts(ArrayIndex) = Left$(NameParts(ArrayIndex), Len(NameParts(ArrayIndex)) - 1) End If '次回検索位置算出 FoundPos = FoundPos + Len("\") Loop 'ファイルである場合 If IsDirectory = False Then 'インデックスを増やしてメモリー確保 ArrayIndex = ArrayIndex + 1 ReDim Preserve NameParts(ArrayIndex) As String NameParts(ArrayIndex) = ShortFileName End If '後ろからディレクトリ名・ファイル名を復元する For i = UBound(NameParts) To 1 Step -1 hFindFile = FindFirstFile(NameParts(i), udtW32FD) 'ネットワーク対応 'ルートパス(何て呼べば良いか分からない)以上を指定すると INVALID_HANDLE_VALUE が返る If hFindFile = INVALID_HANDLE_VALUE Then CnvShortToLong = NameParts(i) & TargetFileName Exit Function End If 'パス連結 TargetFileName = Left$(udtW32FD.cFileName, InStr(udtW32FD.cFileName, Chr$(0)) - 1) _ & IIf(i = UBound(NameParts), "", "\") & TargetFileName Call FindClose(hFindFile) Next i 'C:\などのドライブ名を付加 CnvShortToLong = NameParts(0) & TargetFileName End Function 以下で動作確認 Private Sub Form_Load() Debug.Print CnvShortToLong("C:\PROGRA~1\INTERN~1\PLUGINS\QUICKT~1.CLA") Debug.Print CnvShortToLong("C:\PROGRA~1\INTERN~1\PLUGINS\") Debug.Print CnvShortToLong("C:\PROGRA~1\INTERN~1\PLUGINS") Debug.Print CnvShortToLong("C:\WINDOWS\青いレ~1.BMP") End Sub [実行結果] C:\Program Files\Internet Explorer\PLUGINS\QuickTimePlugin.class C:\Program Files\Internet Explorer\PLUGINS C:\Program Files\Internet Explorer\PLUGINS C:\WINDOWS\青いレース編み 16.bmp |