How I can get the user's temp folder path in C++? My program has to run on Windows Vista and XP and they have different temp paths. How I can get it without losing compatibility?
-
2If you're only interested in windows solutions you should place that in your question title. – Richard Corden Aug 25 '09 at 11:00
-
Please consider changing the accepted answer to f-roche's, https://stackoverflow.com/a/51702008/3543437 – kayleeFrye_onDeck Dec 20 '18 at 01:31
9 Answers
Is there a reason you can't use the Win32 GetTempPath API?
This API is available starting with W2K and hence will be available on all of your listed targets.

- 733,204
- 149
- 1,241
- 1,454
-
2`GetTempPath()` has been around a lot longer than W2K. It existed in Win95. – Remy Lebeau Jul 15 '21 at 16:44
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

- 241
- 2
- 7
-
2`std::filesystem::temp_directory_path().wstring()` works like a charm! – kayleeFrye_onDeck Dec 20 '18 at 01:31
-
1Well... kind of. I was hoping it would return whatever `TEMP` was set to, but it does more behind the scenes (but for your own good). For example, I've got a UWP Unit Test app, and it returns this instead: `L"C:\\Users\\user name\\AppData\\Local\\Packages\\$(GUID)\\AC\\Temp\\$(FileName)"` Which is the more useful of the two possibilities, seeing as a UWP app wouldn't let you write directly to whatever is set to `TEMP` in your env-vars with something like `fwrite`, which I manually verified is in fact the case. – kayleeFrye_onDeck Dec 20 '18 at 01:38
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:
- The path specified by the TMP environment variable.
- The path specified by the TEMP environment variable, if TMP is not defined.
- The current directory, if both TMP and TEMP are not defined.

- 115
- 1
- 10

- 540
- 2
- 5
-
5You should link to an MSDN documentation as opposed to copy and apsting the contents – JaredPar Aug 24 '09 at 13:41
-
9I'd actually appreciate both the info AND the link. The problem with links is that they rot over time. – Michael Kohne Aug 24 '09 at 13:47
-
-1 for giving no indication that it's a quotation, for not citing the source of the quotation, and for pasting out-of-date information. – Rob Kennedy Aug 24 '09 at 14:42
-
1This will usually return `C:\Windows\Temp` for Win32 apps and the temporary storage location for Windows Store Apps for AppContainers, and is also what std's filesystem `temp_directory_path()` api will return. Personally, I'd rather use the std instead of mucking around directly with WinAPIs, but a mature `
` wasn't around when this was answered initially. – kayleeFrye_onDeck Feb 16 '19 at 00:20
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

- 4,546
- 3
- 40
- 69

- 6,648
- 5
- 69
- 80
Function GetTempPath will return a path with a short name,eg: C:\Users\WDKREM~1\AppData\Local\Temp\
.
To get a full temp path name,use GetLongPathName subsequently.

- 637
- 7
- 16
Use GetTempPath() to retrieve the path of the directory designated for temporary files.
wstring TempPath;
wchar_t wcharPath[MAX_PATH];
if (GetTempPathW(MAX_PATH, wcharPath))
TempPath = wcharPath;

- 4,211
- 1
- 20
- 25
-
3You should be able to just use `GetTempPath` instead of `GetTempPathW` or `GetTempPathA`. You're encouraged to not use WinAPIs with the `A` and `W` contexts directly, as it's supposed to detect if your project is ANSI or not and use the correct one based off of that. At the very least it will make your code more robust. – kayleeFrye_onDeck Dec 20 '18 at 01:26
#include <iostream>
#include <string>
int main(int argc, char* argv[]){
std::cout << getenv("TEMP") << std::endl;
return 0;
}

- 121
- 1
- 2
-
Won't that only work on Windows if it's in English or some set of Latin-character languages? – kayleeFrye_onDeck Dec 20 '18 at 01:27
GetTempPath isn't going to work on Vista unless the users have administrative access. I'm running into that problem right now with one of my apps.

- 85
- 1
-
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – Donald Duck Oct 29 '17 at 15:06
As VictorV pointed out, GetTempPath
returns a collapsed path. You'll need to use both the GetTempPath
and GetLongPathName
macros to get the fully expanded path.
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 ) );

- 5,162
- 2
- 25
- 36