【问题标题】:Getting user temporary folder path in Windows在 Windows 中获取用户临时文件夹路径
【发布时间】:2010-11-22 06:54:22
【问题描述】:

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

【问题讨论】:

标签: c++ windows path directory


【解决方案1】:

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

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

【讨论】:

  • GetTempPath() 的存在时间比 W2K 长得多。它存在于Win95中。
【解决方案2】:

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

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

【讨论】:

  • std::filesystem::temp_directory_path().wstring() 就像一个魅力!
  • 嗯...有点。我希望它会返回 TEMP 设置的任何内容,但它在幕后做的更多(但为了你自己好)。例如,我有一个 UWP 单元测试应用程序,它会返回:L"C:\\Users\\user name\\AppData\\Local\\Packages\\$(GUID)\\AC\\Temp\\$(FileName)" 这两种可能性中更有用的是,因为 UWP 应用程序不允许您直接写入设置为 @ 的任何内容987654326@ 在您的环境变量中使用fwrite 之类的东西,我手动验证确实是这种情况。
【解决方案3】:

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

DWORD GetTempPath(

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

参数

nBufferLength

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

lpBuffer

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

返回值

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

备注

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

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

【讨论】:

  • 您应该链接到 MSDN 文档,而不是复制和获取内容
  • 我真的很感激信息和链接。链接的问题在于它们会随着时间的推移而腐烂。
  • -1 表示没有表明它是引用,没有引用引用的来源,以及粘贴过时的信息。
  • 这通常会为 Win32 应用程序返回 C:\Windows\Temp 和为 AppContainers 的 Windows 应用商店应用程序的临时存储位置,这也是 std 的文件系统 temp_directory_path() api 将返回的内容。就个人而言,我宁愿使用 std 而不是直接使用 WinAPI,但最初回答这个问题时,还没有成熟的 <filesystem>
【解决方案4】:

在 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 可能会返回全名而不是短名。
此外,如果无论运行什么,它都以 SYSTEM 而不是登录用户的身份运行,而不是返回 %USERPROFILE%\AppData\Local\Temp,它将返回更像 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);
    }
}

[Robust] Temp 适用于您的应用程序可访问的任何内容 (C++17)

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

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


根据您的需要,您可能会充分利用 first 和 last 函数。如果您正在处理 AppContainer 应用程序,请使用&lt;filesystem&gt; 提供的最后一个。它应该返回类似的东西,

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

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 您应该可以只使用GetTempPath 而不是GetTempPathWGetTempPathA。鼓励您不要直接将 WinAPI 与 AW 上下文一起使用,因为它应该检测您的项目是否为 ANSI 并基于此使用正确的。至少它会让你的代码更加健壮。
    【解决方案6】:
    #include <iostream>
    #include <string>
    
    int main(int argc, char* argv[]){
    
        std::cout << getenv("TEMP") << std::endl;
    
        return 0;
    }
    

    【讨论】:

    • 如果它是英语或某些拉丁字符语言,那不是只能在 Windows 上运行吗?
    【解决方案7】:

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

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

    【讨论】:

      【解决方案8】:

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

      【讨论】:

      • 这并没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
      【解决方案9】:

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

      【讨论】:

        猜你喜欢
        • 2013-08-27
        • 2013-10-08
        • 2013-07-26
        • 2012-08-19
        • 1970-01-01
        • 1970-01-01
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多