Getting user temporary folder path in Windows

The GetTempPath function retrieves the path of the directory designated for temporary files. This function supersedes the GetTempDrive function.

DWORD GetTempPath(

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

Parameters

nBufferLength

Specifies the size, in characters, of the string buffer identified by lpBuffer.

lpBuffer

Points to a string buffer that receives the null-terminated string specifying the temporary file path.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to lpBuffer, not including the terminating null character. If the return value is greater than nBufferLength, the return value is the size of the buffer required to hold the path. If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetTempPath function gets the temporary file path as follows:

  1. The path specified by the TMP environment variable.
  2. The path specified by the TEMP environment variable, if TMP is not defined.
  3. The current directory, if both TMP and TEMP are not defined.

Is there a reason you can't use the Win32 GetTempPath API?

  • http://msdn.microsoft.com/en-us/library/aa364992(VS.85).aspx

This API is available starting with W2K and hence will be available on all of your listed targets.


Since C++ 17 you can use a cross-platform function: std::filesystem::temp_directory_path()

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


In Windows 10, this can be tricky because the value of the Temporary Path depends not only what it's set to by default, but also what kind of app you're using. So it depends what specifically you need.

[Common Area] TEMP in User's Local App Data

#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 will likely return the full name instead of the short name.
Also, if whatever is running it is doing it as as SYSTEM instead of a logged in user, instead of it returning %USERPROFILE%\AppData\Local\Temp, it will return something more like, C:\Windows\System32\config\systemprofile\AppData\Local\Temp

Temp for whatever the TEMP environment variable is

#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);
    }
}

[Robust] Temp for whatever is accessible by your app (C++17)

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

temp_directory_path will likely return the short name instead of the full name.


You're probably going to get the most use out of the first and last functions depending on your needs. If you're dealing with AppContainer apps, go for the last one provided by <filesystem>. It should return something like,

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