У меня сложилось впечатление, что если бы у меня был UNC-путь, подобный этому:
\\SRVR-A\Home\UserA\Documents\TestFolder
а также Я хотел продлить прошел MAX_PATH предел, я мог бы сделать это:
\\?\UNC\SRVR-A\Home\UserA\Documents\TestFolder
Но когда я запускаю следующее в Windows XP, происходит сбой с кодом ошибки ERROR_INVALID_NAME
:
TCHAR buffDummy;
DWORD dwNeededLn = ::GetLongPathName(
L"\\\\?\\UNC\\SRVR-A\\Home\UserA\\Documents\\TestFolder",
&buffDummy, 0);
if(dwNeededLn == 0)
{
//Error
int nErrorCode = ::GetLastError();
}
Я что-то пропустил?
PS. Эта папка существует, и API работает нормально, если я делаю \\SRVR-A\Home\UserA\Documents\TestFolder
вместо.
Подсказка содержится в цитате со страницы MSDN: «Во многих файловых системах короткое имя файла содержит символ тильды (~). Однако не все файловые системы следуют этому соглашению».
С удаленной файловой системой вы не знаете основную файловую систему. Вы не можете догадаться, каков его метод для генерации коротких имен файлов, или даже если такое понятие существует (в конце концов, это действительно специфичная для Windows концепция)
Таким образом, GetLongPathName
следует ожидать, чтобы работать на всех. Теперь это может показаться работоспособным в некоторых случаях, но, возможно, это несчастный случай — применение локальных правил к удаленному имени может работать, если системы достаточно похожи.
Функция ::GetLongPathName()
действительно две функции: ::GetLongPathNameA()
(ANSI) и ::GetLongPathNameW()
(Широкий).
Во включаемом файле 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
, Я запускаю тест на рабочем столе Win7 Professional, используя VC Express 2013.
#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;
}
Результаты, достижения:
\\CALCITE\public\x.txt ==> \\CALCITE\public\x.txt
\\?\UNC\CALCITE\public\x.txt ==> \\?\UNC\CALCITE\public\x.txt
\\?\UNC\192.168.1.2\public\x.txt ==> \\?\UNC\192.168.1.2\public\x.txt
\\CALCITE\public\bad name.txt ==> Error: 2
\\CALCITE\Bad path\x.txt ==> Error: 67
Ошибка 2: ERROR_FILE_NOT_FOUND
Ошибка 67: ERROR_BAD_NET_NAME