在 Windows 中获取用户临时文件夹路径

发布于 2024-08-03 14:01:07 字数 93 浏览 1 评论 0原文

如何在 C++ 中获取用户的临时文件夹路径?我的程序必须在 Windows Vista 和 XP 上运行,并且它们有不同的临时路径。我怎样才能在不失去兼容性的情况下获得它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

相权↑美人 2024-08-10 14:01:07

是否存在无法使用 Win32 GetTempPath API 的原因?

此 API 从 W2K 开始可用,因此将在您列出的所有目标上可用。

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.

伪心 2024-08-10 14:01:07

从 C++ 17 开始,您可以使用跨平台函数:
std::filesystem::temp_directory_path()

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

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

守不住的情 2024-08-10 14:01:07

GetTempPath 函数检索为临时文件指定的目录的路径。此函数取代 GetTempDrive 函数。

DWORD GetTempPath(

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

参数

nBufferLength

指定 lpBuffer 标识的字符串缓冲区的大小(以字符为单位)。

lpBuffer

指向一个字符串缓冲区,该缓冲区接收指定临时文件路径的以 null 结尾的字符串。

返回值

如果函数成功,返回值是复制到 lpBuffer 的字符串的长度(以字符为单位),不包括终止空字符。如果返回值大于nBufferLength,则返回值是保存路径所需的缓冲区的大小。
如果函数失败,返回值为零。要获取扩展错误信息,请调用 GetLastError。

备注

GetTempPath函数获取临时文件路径如下:

  1. TMP环境变量指定的路径。
  2. 如果未定义 TMP,则由 TEMP 环境变量指定的路径。
  3. 当前目录(如果 TMP 和 TEMP 均未定义)。

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.
甜扑 2024-08-10 14:01:07

在 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 可能会返回全名而不是短名称。
另外,如果正在运行的任何程序都以系统身份而不是登录用户身份执行,则它不会返回%USERPROFILE%\ AppData \ Local \ Temp ,而是会返回更像是的内容,< code >C:\Windows\System32\config\systemprofile\AppData\Local\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);
    }
}

[强健] 应用程序可访问的临时值 (C++17)

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

temp_directory_path 可能会返回短名称而不是全名。


根据您的需要,您可能会充分利用第一个和最后一个函数。如果您正在处理 AppContainer 应用程序,请选择 提供的最后一个。它应该返回类似

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

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

小女人ら 2024-08-10 14:01:07

函数GetTempPath将返回带有短名称的路径,例如:C:\Users\WDKREM~1\AppData\Local\Temp\

要获取完整的临时路径名称,请随后使用GetLongPathName

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.

夜清冷一曲。 2024-08-10 14:01:07

使用 GetTempPath() 检索指定用于临时文件的目录的路径。

wstring TempPath;
wchar_t wcharPath[MAX_PATH];
if (GetTempPathW(MAX_PATH, wcharPath))
   TempPath = wcharPath;

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;
她说她爱他 2024-08-10 14:01:07
#include <iostream>
#include <string>

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

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

    return 0;
}
#include <iostream>
#include <string>

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

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

    return 0;
}
坠似风落 2024-08-10 14:01:07

除非用户具有管理访问权限,否则 GetTempPath 将无法在 Vista 上运行。我现在在使用我的一个应用程序时遇到了这个问题。

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.

一场春暖 2024-08-10 14:01:07

正如 VictorV 指出的,GetTempPath 返回折叠路径。您需要使用 GetTempPathWGetLongPathNameW 函数来获取完全展开的路径。

[[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';
}

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';
}
折戟 2024-08-10 14:01:07

使用默认常量MAX_PATH示例

wchar_t defaultTempPath[MAX_PATH];
GetTempPathW(MAX_PATH, defaultTempPath);

// in case you return the result in a string function
return wstring(defaultTempPath);

在C++中,MAX_PATH是一个常量,表示Windows操作系统上文件路径的最大长度。它被定义为 260 个字符,包括终止空字符。

MAX_PATH 常量用于处理文件路径的各种Win32 API 函数和结构。请务必注意,此限制专门适用于 Windows API,可能不适用于其他平台或文件系统。

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 .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文