Justin k
Justin k

Reputation: 1104

How to find Path of Desktop in 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

Upvotes: 2

Views: 8903

Answers (2)

Leth4Lweap0N
Leth4Lweap0N

Reputation: 1

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

Upvotes: 0

Cody Gray
Cody Gray

Reputation: 244722

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.

Upvotes: 6

Related Questions