使用Unicode文件名获取完整路径

5

我有一个短路径或DOS格式的路径(例如"C:/DOCUME~1"),想要获取其完整路径/长路径(例如"C:/Documents And Settings")。

我尝试了GetLongPathName api。它可以工作。但是当处理Unicode文件名时,它会出现失败。

Private Declare Function GetLongPathName Lib "kernel32" Alias _
    "GetLongPathNameA" (ByVal lpszShortPath As String, _
    ByVal lpszLongPath As String, ByVal cchBuffer As Long) As Long

我尝试别名GetLongPathNameW,但似乎没有效果,对于Unicode和非Unicode文件名都返回0。在MSDN中,只有关于C/C++的GetLongPathNameW文章,而没有任何关于VB/VBA的文章。我可能做错了什么吗?

这种情况有解决方案吗?我在Google和StackOverflow上花了几个小时,但找不到答案。

谢谢!


1
我从文档中注意到Unicode必须以\\?\ 为前缀,因此您的示例将变为\\?\C:\DOCUME~1 - SeanC
@SeanCheshire 谢谢您的建议。但我尝试了几次测试,都没有成功。 以下是结果: strPath = "\?" & strPath ?GetLongPathName(strPath, strTemp, 255) 0 - Shinigamae
2个回答

4

这对你有用吗?我已经将文件路径转换为短路径名,然后再转换回来,这样即使是Unicode字符(例如C:/Tö+)也可以得到正确的字符串。

Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" _
    (ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal lBuffer As Long) As Long
Private Declare Function GetLongPathName Lib "kernel32" Alias "GetLongPathNameA" _
    (ByVal lpszShortPath As String, ByVal lpszLongPath As String, ByVal cchBuffer As Long) As Long

Public Function GetShortPath(ByVal strFileName As String) As String
    'KPD-Team 1999
    'URL: [url]http://www.allapi.net/[/url]
    'E-Mail: [email]KPDTeam@Allapi.net[/email]
    Dim lngRes As Long, strPath As String
    'Create a buffer
    strPath = String$(165, 0)
    'retrieve the short pathname
    lngRes = GetShortPathName(strFileName, strPath, 164)
    'remove all unnecessary chr$(0)'s
    GetShortPath = Left$(strPath, lngRes)
End Function

Public Function GetLongPath(ByVal strFileName As String) As String
    Dim lngRes As Long, strPath As String
    'Create a buffer
    strPath = String$(165, 0)
    'retrieve the long pathname
    lngRes = GetLongPathName(strFileName, strPath, 164)
    'remove all unnecessary chr$(0)'s
    GetLongPath = Left$(strPath, lngRes)
End Function

Private Sub Test()
    shortpath = GetShortPath("C:/Documents And Settings")

    Longpath = GetLongPath(shortpath)
End Sub

1

要在vb6/vba中使用W函数,您需要将所有字符串参数声明为long类型:

Private Declare Function GetLongPathName Lib "kernel32" Alias "GetLongPathNameW" _
  (ByVal lpszShortPath As Long, _
   ByVal lpszLongPath As Long, _
   ByVal cchBuffer As Long) As Long

而不是只传递a_string,请传递StrPtr(a_string)

所以如果你有:

dim s_path as string
dim l_path as string

s_path = "C:\DOCUME~1"
l_path = string$(1024, vbnullchar)

GetLongPathNameA s_path, l_path, len(l_path)

它将变成

dim s_path as string
dim l_path as string

s_path = "C:\DOCUME~1"
l_path = string$(1024, vbnullchar)

GetLongPathNameW strptr(s_path), strptr(l_path), len(l_path)

我想在困难时尝试过这种方法,但我会再考虑一下。 - Shinigamae

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接