我的印象是,如果我有这样一个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