如何为UNC路径制作一个长Unicode版本



我的印象是,如果我有这样一个UNC路径:

\SRVR-AHomeUserADocumentsTestFolder

和我想扩展它通过MAX_PATH限制,我可以这样做:

\?UNCSRVR-AHomeUserADocumentsTestFolder

但是当我在Windows XP上运行以下命令时,它失败了,错误代码为ERROR_INVALID_NAME:

TCHAR buffDummy;
DWORD dwNeededLn = ::GetLongPathName(
    L"\\?\UNC\SRVR-A\HomeUserA\Documents\TestFolder",
    &buffDummy, 0);
if(dwNeededLn == 0)
{
    //Error
    int nErrorCode = ::GetLastError();
}

我错过了什么吗?

p。这个文件夹存在,如果我使用\SRVR-AHomeUserADocumentsTestFolder, API也可以正常工作。

提示实际上来自MSDN页面:"在许多文件系统中,短文件名包含一个波浪(~)字符。然而,并不是所有的文件系统都遵循这个约定。

对于远程文件系统,您不知道底层文件系统。你猜不到它生成短文件名的方法是什么,或者即使有这样的概念(毕竟这是windows特有的概念)

因此,GetLongPathName应该是可以工作的。现在,它在某些情况下似乎可以工作,但这可能是一个不幸的意外—如果系统足够相似,则将本地规则应用于远程名称可能会工作。

函数::GetLongPathName()实际上是两个函数:::GetLongPathNameA() (ANSI)和::GetLongPathNameW() (Wide)。

在包含文件fileapi.h中有一些代码:

#ifdef UNICODE
#define GetLongPathName  GetLongPathNameW
#else
#define GetLongPathName  GetLongPathNameA
#endif // !UNICODE

只有GetLongPathNameW()处理较长的路径名。

您需要确保定义了"UNICODE",否则专门调用GetLongPathNameW(),而不是GetLongPathName()

我在家里的局域网上做了一些测试。

CALCITE为外置硬盘。它运行某种类型的Unix/Linux变体,但我没有对它进行修补。IP地址为192.168.1.2。我正在使用VC Express 2013在Win7 Professional桌面上运行测试。

#include <iostream>
#include <string>
#include <Windows.h>
void Test(const std::wstring &sName)
{
    std::wcout << sName << L" ==> ";
    const size_t nBuffsize = 1024;
    wchar_t szBuff[nBuffsize] = { 0 };
    if (::GetLongPathNameW(sName.c_str(), szBuff, nBuffsize))
        std::wcout << szBuff << std::endl;
    else
        std::wcout << L"Error: " << ::GetLastError() << std::endl;
}
int main() 
{
    Test(L"\\CALCITE\public\x.txt");
    Test(L"\\?\UNC\CALCITE\public\x.txt");
    Test(L"\\?\UNC\192.168.1.2\public\x.txt");
    Test(L"\\CALCITE\public\bad name.txt");
    Test(L"\\CALCITE\Bad path\x.txt");
    return 0;
}
结果:

 \CALCITEpublicx.txt ==> \CALCITEpublicx.txt
 \?UNCCALCITEpublicx.txt ==> \?UNCCALCITEpublicx.txt
 \?UNC192.168.1.2publicx.txt ==> \?UNC192.168.1.2publicx.txt
 \CALCITEpublicbad name.txt ==> Error: 2 
 \CALCITEBad pathx.txt ==> Error: 67

Error 2 is ERROR_FILE_NOT_FOUND

Error 67 is ERROR_BAD_NET_NAME

最新更新