如何在C++中查找桌面路径

发布于 2025-01-06 07:07:23 字数 886 浏览 3 评论 0原文

更新:在科迪·格雷回复后,

我想找到一种将文件保存到桌面的方法。由于每个用户都有不同的用户名,我发现以下代码将帮助我找到其他人桌面的路径。但是如何将以下内容保存到桌面呢?

#include <iostream>
#include <windows.h>
#include <fstream>
#include <direct.h>
#include <shlobj.h>
using namespace std;
int main ()
{
    ofstream file;  

    TCHAR appData[MAX_PATH];
    if (SUCCEEDED(SHGetFolderPath(NULL,
                                  CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
                                  NULL,
                                  SHGFP_TYPE_CURRENT,
                                  appData)))

    wcout << appData << endl; //This will printout the desktop path correctly, but
    file.open(appData +"/.txt"); //how can I open the desktop path here??
    file<<"hello\n";
    file.close();
    return 0;
}

Microsoft Visual Studio 2010、Windows 7、C++ 控制台

UPDATED: after Cody Gray's reply

I want to find a way to save a file to a desktop. Since every user has different user name, I found following code will help me find the path to someone else’s desktop. But how can I save the following to desktop?

#include <iostream>
#include <windows.h>
#include <fstream>
#include <direct.h>
#include <shlobj.h>
using namespace std;
int main ()
{
    ofstream file;  

    TCHAR appData[MAX_PATH];
    if (SUCCEEDED(SHGetFolderPath(NULL,
                                  CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
                                  NULL,
                                  SHGFP_TYPE_CURRENT,
                                  appData)))

    wcout << appData << endl; //This will printout the desktop path correctly, but
    file.open(appData +"/.txt"); //how can I open the desktop path here??
    file<<"hello\n";
    file.close();
    return 0;
}

Microsoft Visual Studio 2010, Windows 7, C++ console

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

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

发布评论

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

评论(2

骷髅 2025-01-13 07:07:23

问题是您正在使用定义的 UNICODE 来编译应用程序(您应该这样做),这意味着 C 样式字符串不会存储在 char 数组中(因为它们适用于 ANSI 字符串),而是 wchar_t 数组。

这就是为什么您无法从 char* 转换为 LPWSTR(在 Windows 标头中 typedefwchar_t*)。

解决方案是更改字符串缓冲区的类型。您可以显式使用 wchar_t

wchar_t appData[MAX_PATH];

或者利用 TCHAR 宏,它会自动#define 到适当的类型,具体取决于您是否编译定义了 UNICODE:

TCHAR appData[MAX_PATH];

但这并不是唯一的问题。其他需要注意的事项:

  1. 您应该强烈考虑使用 TRUEFALSE 符号,而不是文字 01 编写 Win32 代码时。当函数的文档表明它接受 BOOL 类型的值时,请利用已为该类型定义的符号。它使您的代码更加清晰易读,即使您可以合理地假设这些符号永远不会更改标头中的定义。

  2. 如果您想要桌面文件夹,

    CSIDL_LOCAL_APPDATA 不是正确的常量。这将返回一个与当前用户关联的文件夹,该文件夹旨在由应用程序用于存储不应该与用户一起漫游的数据(它应该存储在本地计算机上并可用)。考虑到所有因素,这可能是比桌面更好的选择,因为应用程序在将垃圾溢出到用户桌面上之前确实应该有一个非常好的理由。

    如果您需要数据随应用程序漫游,则应使用 CSIDL_APPDATA。我在我的回答<这里简要介绍了所有这些不同的文件夹是什么、它们的含义以及何时应该使用它们< /a>.

    但是请注意,SHGetSpecialFolderPath 函数将您限制为特殊文件夹的特定子集。这让我想到...

  3. 从 Windows 2000 开始(老实说,我认为没有人还在编写针对 2000 年之前的 Windows 版本的应用程序) ),SHGetSpecialFolderPath 函数 已过时。

    针对 Windows 2000 和 XP 的首选替代品是 SHGetFolderPath,您将以类似的方式使用它:

    TCHAR appData[MAX_PATH];
    
    如果(成功(SHGetFolderPath(NULL, 
                                  CSIDL_LOCAL_APPDATA | CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 
                                  无效的, 
                                  SHGFP_TYPE_CURRENT, 
                                  应用程序数据))) 
    {
        wcout <<应用程序数据<<结束;
    }
    

    该家族的最新成员是SHGetKnownFolderPath 适用于仅针对 Windows Vista 及更高版本的新应用程序。

The problem is that you're compiling the application with UNICODE defined (as you well should be), meaning that C-style strings are not stored in char arrays (as they would be for ANSI strings), but rather wchar_t arrays.

That's why you can't convert from char* to LPWSTR (which is typedefed in the Windows headers as wchar_t*).

The solution is to change the type of your string buffer. You can either use wchar_t explicitly:

wchar_t appData[MAX_PATH];

or take advantage of the TCHAR macro that will automatically #define to the appropriate type, depending on whether you compile with UNICODE defined:

TCHAR appData[MAX_PATH];

That's not the only problem though. A couple of other things to note:

  1. You should strongly consider using the TRUE and FALSE symbols instead of the literals 0 and 1 when writing Win32 code. When the function's documentation indicates that it accepts values of type BOOL, take advantage of the symbols that are already defined for that type. It makes your code much clearer and easier to read, even if you can reasonably assume that these symbols will never change their definitions in the headers.

  2. CSIDL_LOCAL_APPDATA is not the correct constant to use if you want the desktop folder. That will return a folder that is associated with the current user and intended to be used by applications for storing data that should not roam with the user (it should be stored and available on the local machine only). All things considered, this is probably a better choice than the desktop anyway, as apps should really have a darn good reason before spilling junk out on a user's desktop.

    If you need the data to roam with the application, you should use CSIDL_APPDATA instead. I provide a brief run-down of what all these different folders are, what they mean, and when you should use them in my answer here.

    Do note, however, that the SHGetSpecialFolderPath function limits you to a particular subset of the special folders. Which brings me to...

  3. As of Windows 2000 (and I honestly don't think there's anyone out there still writing apps targeting versions of Windows prior to 2000), the SHGetSpecialFolderPath function is obsolete.

    The preferred replacement for those targeting Windows 2000 and XP is SHGetFolderPath, which you would use in a similar fashion:

    TCHAR appData[MAX_PATH];
    
    if (SUCCEEDED(SHGetFolderPath(NULL, 
                                  CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 
                                  NULL, 
                                  SHGFP_TYPE_CURRENT, 
                                  appData))) 
    {
        wcout << appData << endl;
    }
    

    And the newest member of the family is SHGetKnownFolderPath for new applications targeting only Windows Vista and later.

陌若浮生 2025-01-13 07:07:23
    Böyle Olması Gerekiyor

    TCHAR path[_MAX_PATH] = _T("");
    if (SUCCEEDED(SHGetFolderPath(NULL, 
                                  CSIDL_DESKTOP 
                                  0, 
                                  NULL, 
                                  path))) 
    strcat(path,"\\Test.txt");
    ofstream out;
    out.open(path);
    Böyle Olması Gerekiyor

    TCHAR path[_MAX_PATH] = _T("");
    if (SUCCEEDED(SHGetFolderPath(NULL, 
                                  CSIDL_DESKTOP 
                                  0, 
                                  NULL, 
                                  path))) 
    strcat(path,"\\Test.txt");
    ofstream out;
    out.open(path);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文