Как сделать длинную версию Unicode для UNC-пути?

У меня сложилось впечатление, что если бы у меня был 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 вместо.

1

Решение

Подсказка содержится в цитате со страницы MSDN: «Во многих файловых системах короткое имя файла содержит символ тильды (~). Однако не все файловые системы следуют этому соглашению».

С удаленной файловой системой вы не знаете основную файловую систему. Вы не можете догадаться, каков его метод для генерации коротких имен файлов, или даже если такое понятие существует (в конце концов, это действительно специфичная для Windows концепция)

Таким образом, GetLongPathName следует ожидать, чтобы работать на всех. Теперь это может показаться работоспособным в некоторых случаях, но, возможно, это несчастный случай — применение локальных правил к удаленному имени может работать, если системы достаточно похожи.

1

Другие решения

Функция ::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

0

По вопросам рекламы [email protected]