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