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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1322442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:33:05  来源:igfitidea点击:

Getting user temporary folder path in Windows

c++windowspathdirectory

提问by JaredPar

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?

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

回答by JaredPar

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

是否有不能使用 Win32 GetTempPath API 的原因?

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

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

回答by f-roche

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

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

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

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

回答by Henrico Dolfing

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

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

DWORD GetTempPath(

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

Parameters

参数

nBufferLength

nBufferLength

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

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

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.

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

Remarks

评论

The GetTempPath function gets the temporary file path as follows:

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

  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.
  1. TMP 环境变量指定的路径。
  2. 如果未定义 TMP,则由 TEMP 环境变量指定的路径。
  3. 当前目录,如果未定义 TMP 和 TEMP。

回答by kayleeFrye_onDeck

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.

在 Windows 10 中,这可能很棘手,因为临时路径的值不仅取决于它的默认设置,还取决于您使用的应用程序类型。所以这取决于你具体需要什么。

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

【公共区域】用户本地应用数据中的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);
    }
}

GetUserLocalTempPathwill 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

GetUserLocalTempPath可能会返回全名而不是短名称。
此外,如果正在运行的任何东西都以 SYSTEM 身份而不是登录用户身份运行,则%USERPROFILE%\AppData\Local\Temp它不会返回,而是会返回更类似的内容,C:\Windows\System32\config\systemprofile\AppData\Local\Temp

Temp for whatever the TEMP environment variable is

无论 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);
    }
}

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

[强大] 应用程序可访问的任何温度 (C++17)

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

temp_directory_pathwill likely return the short name instead of the full name.

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



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,

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

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

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

回答by Deadlock

Use GetTempPath() to retrieve the path of the directory designated for temporary files.

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

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

回答by C0LD

#include <iostream>
#include <string>

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

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

    return 0;
}

回答by John Reynolds

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.

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

回答by VictorV

Function GetTempPathwill return a path with a short name,eg: C:\Users\WDKREM~1\AppData\Local\Temp\.

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

To get a full temp path name,use GetLongPathNamesubsequently.

要获得完整的临时路径名随后使用GetLongPathName

回答by WBuck

As VictorV pointed out, GetTempPathreturns a collapsed path. You'll need to use both the GetTempPathand GetLongPathNamemacros to get the fully expanded path.

正如 VictorV 所指出的,GetTempPath返回一个折叠的路径。您需要同时使用GetTempPathGetLongPathName宏来获得完全展开的路径。

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