SHGetFolderPath Не рекомендуется: Какая альтернатива для извлечения пути для папок Windows?

SHGetFolderPath() функция устарела, начиная с Windows Vista: http://msdn.microsoft.com/en-us/library/bb762181%28v=VS.85%29.aspx

Каков альтернативный способ получения пути к папке приложения в Windows?

SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath)

Кроме того, почему я получаю эти ошибки при использовании этой функции:

Error   1   error C2065: 'CSIDL_COMMON_APPDATA' : undeclared identifier

Error   2   error C3861: 'SHGetFolderPath': identifier not found

7

Решение

Альтернатива описана в документации, на которую вы ссылаетесь. А именно это SHGetKnownFolderPath.

Тем не мение, SHGetKnownFolderPath доступно только на Vista или позже. Так что, если вы используете привязку времени загрузки и запускаете программу, которая вызывает SHGetKnownFolderPath на XP эта программа не запустится. Это явно проблема, если вы хотите поддерживать XP.

Теперь вы можете перейти на связывание во время выполнения SHGetKnownFolderPath, Перед вызовом выполните проверку версии, и если функция недоступна, вернитесь к SHGetFolderPath,

Лично я бы не допустил, чтобы это унижение беспокоило тебя слишком сильно. Microsoft славится поддержкой обратной совместимости. Не ожидайте SHGetFolderPath исчезнуть в ближайшее время. Вы найдете это SHGetFolderPath существует в Windows 8, и я ожидаю, что она все еще будет присутствовать в любой версии Windows 10 лет спустя. Мой совет — придерживаться ссылки на время загрузки и переключаться только на SHGetKnownFolderPath когда вы отказываетесь от поддержки XP.

Ваш другой вопрос, который вы задаете в редакции, это как позвонить SHGetFolderPath, Вы должны соблюдать требования, изложенные в нижней части раздела документации MSDN, который вы указали в своем вопросе. В частности, включить Shlobj.h и передать Shlobj.lib компоновщику.

11

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

Это связано прямо наверху, SHGetKnownFolderPath.

CSIDL_COMMON_APPDATA заменяется на FOLDERID_ProgramData в новом API.

2

Я столкнулся с тем же набором ошибок, когда добавил несколько новых заголовочных файлов в свое уже работающее решение.

Я уже звонила SHGetFolderPath и также включил #include <ShlObj.h> но это было в другом заголовочном файле. Решение компилировалось без каких-либо ошибок, прежде чем я добавил в него новые файлы заголовков библиотеки.

Я пытался заменить SHGetFolderPath() с SHGetKnownFolderPath() но это просто перенаправило идентификатор не найден ошибка в SHGetKnownFolderPath,

При добавлении #include <ShlObj.h> в заголовочный файл вызывающего класса SHGetFolderPath,
ошибки прекратились, и решение снова было успешно скомпилировано.

Как уже упоминалось в этот страница, звонящая SHGetFolderPath в Windows Vista или более поздней версии SHGetKnownFolderPath,

1

Я проверил, используя SHGetFolderPath() с Visual Studio 2015 Enterprise на ПК с Windows 10, и он скомпилирован и прекрасно работает, чтобы найти домашнюю папку текущего пользователя. На странице Центра разработки Windows на SHGetFolderPath() Функция SHGetFolderPath есть следующее примечание:

Заметка Начиная с Windows Vista, эта функция является просто оболочкой для
SHGetKnownFolderPath, CSIDL значение переводится в его связанный
KNOWNFOLDERID а потом SHGetKnownFolderPath называется. новый
приложения должны использовать известную систему папок, а не старые
CSIDL система, которая поддерживается только для обратной совместимости.

Как отметил в своем ответе Дэвид Хеффман, у Microsoft есть история обратной совместимости в течение многих лет, особенно когда они могут взять старую функцию и просто перенаправить ее на новую функцию с соответствующими аргументами. CSIDL значения, кажется, имеют соответствующий KNOWNFOLDERID значение. Видеть это таблица из CSIDL константы с краткими аннотациями и соответствующими KNOWNFOLDERID значение.

Пример использования этой функции приведен ниже. Это использование извлекает папку пользователя текущего пользователя (например, «C: \ Users \ myuser \ Documents» в Windows 7), а затем добавляет имя папки в конец пути, используя PathAppend() функция.

TCHAR   achDevice[MAX_PATH];
HRESULT  hr;
// include file ShlObj.h contains list of CSIDL defines however only a subset
// are supported with Windows 7 and later.
// for the 3rd argument, hToken, can be a specified Access Token or SSID for
// a user other than the current user. Using NULL gives us the current user.
if (SUCCEEDED(hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, achDevice))) {
// append a folder name to the user's Documents directory.
// the Path Handling functions are pretty handy.
PathAppend(achDevice, L"xxx");
}

Одна возможная ошибка — один или несколько недопустимых аргументов (hr == E_INVALIDARG). Возвращаемое значение S_OK указывает на то, что вызов выполнен успешно.

Есть несколько CSIDL константы, которые могут быть использованы для изменения результатов функции, таких как CSIDL_FLAG_CREATE используя побитовый оператор ИЛИ. Я не уверен, насколько хорошо эти операторы будут работать с Windows 7 и более поздними версиями.

Есть ограничения на поддерживаемые CSIDL константы с Windows 7 и выше. Похоже также, что в сложных, удаленно смонтированных, перенаправленных и / или общих папках в Active Directory или аналогичной среде могут быть возможные проблемы, которые необходимо решить.

Смотрите также KNOWNFOLDERID которая включает в себя таблицу, которая указывает на некоторые ограничения CSIDL а также SHGetFolderPath(), Некоторые примеры из таблицы CSIDL константы, которые могут быть полезны.

CSIDL_LOCAL_APPDATA - %USERPROFILE%\AppData\Local
CSIDL_MYDOCUMENTS - %USERPROFILE%\Document
CSIDL_PERSONAL -    %USERPROFILE%\Documents
CSIDL_FONTS -       %windir%\Fonts
CSIDL_MYMUSIC -     %USERPROFILE%\Music
CSIDL_MYPICTURES -  %USERPROFILE%\Pictures
CSIDL_COMMON_APPDATA - %ALLUSERSPROFILE% (%ProgramData%, %SystemDrive%\ProgramData)
CSIDL_COMMON_DOCUMENTS -    %PUBLIC%\Documents

Кстати, Функции обработки пути оболочки хорошая библиотека методов для манипулирования путями к файлам

Смотрите также Где разместить общие файлы приложений, доступные для записи?

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