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
Альтернатива описана в документации, на которую вы ссылаетесь. А именно это SHGetKnownFolderPath
.
Тем не мение, SHGetKnownFolderPath
доступно только на Vista или позже. Так что, если вы используете привязку времени загрузки и запускаете программу, которая вызывает SHGetKnownFolderPath
на XP эта программа не запустится. Это явно проблема, если вы хотите поддерживать XP.
Теперь вы можете перейти на связывание во время выполнения SHGetKnownFolderPath
, Перед вызовом выполните проверку версии, и если функция недоступна, вернитесь к SHGetFolderPath
,
Лично я бы не допустил, чтобы это унижение беспокоило тебя слишком сильно. Microsoft славится поддержкой обратной совместимости. Не ожидайте SHGetFolderPath
исчезнуть в ближайшее время. Вы найдете это SHGetFolderPath
существует в Windows 8, и я ожидаю, что она все еще будет присутствовать в любой версии Windows 10 лет спустя. Мой совет — придерживаться ссылки на время загрузки и переключаться только на SHGetKnownFolderPath
когда вы отказываетесь от поддержки XP.
Ваш другой вопрос, который вы задаете в редакции, это как позвонить SHGetFolderPath
, Вы должны соблюдать требования, изложенные в нижней части раздела документации MSDN, который вы указали в своем вопросе. В частности, включить Shlobj.h
и передать Shlobj.lib
компоновщику.
Это связано прямо наверху, SHGetKnownFolderPath.
CSIDL_COMMON_APPDATA заменяется на FOLDERID_ProgramData в новом API.
Я столкнулся с тем же набором ошибок, когда добавил несколько новых заголовочных файлов в свое уже работающее решение.
Я уже звонила SHGetFolderPath
и также включил #include <ShlObj.h>
но это было в другом заголовочном файле. Решение компилировалось без каких-либо ошибок, прежде чем я добавил в него новые файлы заголовков библиотеки.
Я пытался заменить SHGetFolderPath()
с SHGetKnownFolderPath()
но это просто перенаправило идентификатор не найден ошибка в SHGetKnownFolderPath
,
При добавлении
#include <ShlObj.h>
в заголовочный файл вызывающего классаSHGetFolderPath
,
ошибки прекратились, и решение снова было успешно скомпилировано.
Как уже упоминалось в этот страница, звонящая SHGetFolderPath
в Windows Vista или более поздней версии SHGetKnownFolderPath
,
Я проверил, используя 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
Кстати, Функции обработки пути оболочки хорошая библиотека методов для манипулирования путями к файлам
Смотрите также Где разместить общие файлы приложений, доступные для записи?