Получение пути к временной папке пользователя в Windows - PullRequest
18 голосов
/ 24 августа 2009

Как я могу получить путь к временной папке пользователя в C ++? Моя программа должна работать в Windows Vista и XP, и у них разные временные пути. Как я могу получить его без потери совместимости?

Ответы [ 9 ]

21 голосов
/ 24 августа 2009

Есть ли причина, по которой вы не можете использовать Win32 GetTempPath API?

Этот API доступен начиная с W2K и, следовательно, будет доступен для всех ваших целей в списке.

6 голосов
/ 24 августа 2009

Функция GetTempPath извлекает путь к каталогу, предназначенному для временных файлов. Эта функция заменяет функцию GetTempDrive.

DWORD GetTempPath(

DWORD nBufferLength, // size, in characters, of the buffer 
LPTSTR lpBuffer // address of buffer for temp. path 
); 

Параметры

nBufferLength

Определяет размер в символах строкового буфера, идентифицируемого lpBuffer.

lpBuffer

Указывает на строковый буфер, который получает строку с нулевым символом в конце, указывающую путь к временному файлу.

Возвращаемые значения

Если функция завершается успешно, возвращаемое значение представляет собой длину в символах строки, скопированной в lpBuffer, не включая завершающий нулевой символ. Если возвращаемое значение больше, чем nBufferLength, возвращаемое значение является размером буфера, необходимого для хранения пути. Если функция завершается ошибкой, возвращаемое значение равно нулю. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.

Примечания

Функция GetTempPath получает временный путь к файлу следующим образом:

  1. Путь, указанный в переменной среды TMP.
  2. Путь, указанный в переменной среды TEMP, если TMP не определен.
  3. Текущий каталог, если не определены ни TMP, ни TEMP.
4 голосов
/ 06 августа 2018

Начиная с C ++ 17 вы можете использовать кроссплатформенную функцию: std::filesystem::temp_directory_path()

https://en.cppreference.com/w/cpp/filesystem/temp_directory_path

3 голосов
/ 10 сентября 2017
#include <iostream>
#include <string>

int main(int argc, char* argv[]){

    std::cout << getenv("TEMP") << std::endl;

    return 0;
}
2 голосов
/ 24 августа 2015

Используйте GetTempPath (), чтобы получить путь к каталогу, предназначенному для временных файлов.

wstring TempPath;
wchar_t wcharPath[MAX_PATH];
if (GetTempPathW(MAX_PATH, wcharPath))
   TempPath = wcharPath;
1 голос
/ 05 февраля 2010

GetTempPath не будет работать в Vista, если у пользователей нет прав администратора Я столкнулся с этой проблемой прямо сейчас с одним из моих приложений.

0 голосов
/ 16 февраля 2019

В Windows 10 это может быть непросто, потому что значение Временного пути зависит не только от того, какой он установлен по умолчанию, но и от того, какое приложение вы используете. Так что это зависит от того, что конкретно вам нужно.

[Общая область] TEMP в пользовательских данных локального приложения

#include <Windows.h>
#include <Shlobj.h>
#include <Shlobj_core.h>
#include <string_view>
// ...
static void GetUserLocalTempPath(std::wstring& input_parameter) {
    static constexpr std::wstring_view temp_label = L"\\Temp\\";
    HWND folder_handle = { 0 };
    WCHAR temp_path[MAX_PATH];
    auto get_folder = SHGetFolderPath( 
        folder_handle, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_DEFAULT, temp_path
    );
    if (get_folder == S_OK) {
        input_parameter = static_cast<const wchar_t*>(temp_path);
        input_parameter.append(temp_label);
        CloseHandle(folder_handle);
    }
}

GetUserLocalTempPath скорее всего вернет полное имя вместо короткого.
Кроме того, если что-либо работает, оно делает это как SYSTEM, а не как вошедший в систему пользователь, вместо того, чтобы возвращать %USERPROFILE%\AppData\Local\Temp, оно вернет что-то более похожее, C:\Windows\System32\config\systemprofile\AppData\Local\Temp

Temp для любой переменной среды TEMP

#include <Windows.h>
// ...
static void GetEnvTempPath(std::wstring& input_parameter) {
    wchar_t * env_var_buffer = nullptr;
    std::size_t size = 0;
    if ( _wdupenv_s(&env_var_buffer, &size, L"TEMP") == 0 &&
         env_var_buffer != nullptr) {
        input_parameter = static_cast<const wchar_t*>(env_var_buffer);
    }
}

[Надежный] Temp для всего, что доступно вашему приложению (C ++ 17)

#include <filesystem>
// ...
auto temp_path = std::filesystem::temporary_directory_path().wstring();

temporary_directory_path, скорее всего, вернет короткое имя вместо полного имени.


Вероятно, вы получите наибольшую пользу от первой и последней функций в зависимости от ваших потребностей. Если вы имеете дело с приложениями AppContainer, выберите последнее, предоставленное <filesystem>. Должен вернуть что-то вроде

C:\Users\user name\AppData\Local\Packages\{APP's GUID}\AC\Temp

0 голосов
/ 30 августа 2018

Как отметил VictorV, GetTempPath возвращает свернутый путь. Вам нужно использовать оба макроса GetTempPath и GetLongPathName, чтобы получить полностью развернутый путь.

std::vector<TCHAR> collapsed_path;
TCHAR copied = MAX_PATH;
while ( true )
{
    collapsed_path.resize( copied );
    copied = GetTempPath( collapsed_path.size( ), collapsed_path.data( ) );
    if ( copied == 0 ) 
        throw std::exception( "An error occurred while creating temporary path" );
    else if ( copied < collapsed_path.size( ) ) break;
}

std::vector<TCHAR> full_path;
copied = MAX_PATH;
while ( true )
{
    full_path.resize( copied );
    copied = GetLongPathName( collapsed_path.data( ), full_path.data( ), full_path.size( ) );
    if ( copied == 0 ) 
        throw std::exception( "An error occurred while creating temporary path" );
    else if ( copied < full_path.size( ) ) break;
}
std::string path( std::begin( full_path ), std::end( full_path ) );
0 голосов
/ 19 июля 2018

Функция GetTempPath вернет путь с коротким именем , например: C:\Users\WDKREM~1\AppData\Local\Temp\.

Чтобы получить полное имя временного пути , используйте GetLongPathName впоследствии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...