Reputation:
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?
Upvotes: 27
Views: 59858
Reputation: 5501
As VictorV pointed out, GetTempPath
returns a collapsed path. You'll need to use both the GetTempPathW
and GetLongPathNameW
functions to get the fully expanded path.
[[noreturn]]
static void throw_error(const DWORD error)
{
const std::error_code ec{ static_cast<int>(error), std::system_category() };
throw std::system_error{ ec };
}
static std::wstring get_expanded_temp_path(const std::wstring_view collapsed)
{
std::size_t count = GetLongPathNameW(collapsed.data(), nullptr, 0);
if (count == 0)
{
throw_error(GetLastError());
}
std::wstring expanded(count, L'\0');
count = GetLongPathNameW(
collapsed.data(),
expanded.data(),
static_cast<DWORD>(expanded.size()));
if (count == 0)
{
throw_error(GetLastError());
}
expanded.resize(count);
return expanded;
}
static std::wstring get_temp_path()
{
std::size_t count = GetTempPathW(0, nullptr);
if (count == 0)
{
throw_error(GetLastError());
}
std::wstring collapsed(count, L'\0');
count = GetTempPathW(
static_cast<DWORD>(collapsed.size()),
collapsed.data());
if (count == 0)
{
throw_error(GetLastError());
}
collapsed.resize(count);
return get_expanded_temp_path(collapsed);
}
int main()
{
const std::wstring expanded{ get_temp_path() };
std::wcout << expanded << L'\n';
}
Upvotes: 2
Reputation: 692
use the Default constant MAX_PATH
, Example :
wchar_t defaultTempPath[MAX_PATH];
GetTempPathW(MAX_PATH, defaultTempPath);
// in case you return the result in a string function
return wstring(defaultTempPath);
In C++, MAX_PATH
is a constant that represents the maximum length of a file path on the Windows operating system. It is defined as 260 characters, including the terminating null character.
The MAX_PATH
constant is used in various Win32 API
functions and structures that deal with file paths. It is important to note that this limit applies specifically to the Windows API and may not be applicable to other platforms or file systems .
Upvotes: 0
Reputation: 6978
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
Upvotes: 6
Reputation: 261
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
Upvotes: 17
Reputation: 727
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.
Upvotes: 4
Reputation: 131
#include <iostream>
#include <string>
int main(int argc, char* argv[]){
std::cout << getenv("TEMP") << std::endl;
return 0;
}
Upvotes: 3
Reputation: 4519
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;
Upvotes: 3
Reputation: 550
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:
Upvotes: 6
Reputation: 85
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.
Upvotes: 2
Reputation: 755317
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.
Upvotes: 25