Home > MFC, Windows API > How to retrieve special folder paths, for e.g. my documents?

How to retrieve special folder paths, for e.g. my documents?

SHGetFolderPath is the API that we use to retrieve special folder paths.  Some examples of special folders are as follows…

  • My Documents
  • My Pictures
  • Windows directory
  • System directory
  • Program files
  • Internet history directory
  • Cookies directory
  • etc…

So here is a small useful function which retrieves path of any special directory documented for SHGetFolderPath API in MSDN.

CString GetSpecialFolderPath( const DWORD csidl )
{
   HANDLE ProcToken = NULL;
   VERIFY( OpenProcessToken( GetCurrentProcess(), TOKEN_READ, &ProcToken ));

   TCHAR szBuffer[MAX_PATH*2] = { 0 };
   SHGetFolderPath( NULL, csidl, ProcToken, SHGFP_TYPE_CURRENT, szBuffer );
   CString SpecialFolderPath = szBuffer;

   CloseHandle( ProcToken );

   return SpecialFolderPath;
}

// Usage
int main()
{
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } // Get my documents folder path const CString MyDocuments = GetSpecialFolderPath( CSIDL_PERSONAL ); ::MessageBox( NULL, MyDocuments, "MyDocuments Path", MB_OK | MB_ICONINFORMATION ); // Get Program files path const CString ProgramFiles = GetSpecialFolderPath( CSIDL_PROGRAM_FILES ); ::MessageBox( NULL, ProgramFiles, "Program files", MB_OK | MB_ICONINFORMATION ); // Get internet history path const CString HistoryFolder = GetSpecialFolderPath( CSIDL_HISTORY ); ::MessageBox( NULL, HistoryFolder, "History folder", MB_OK | MB_ICONINFORMATION ); return 0; }[/sourcecode] There may be times when a special folder might not be present, so for that case you can combine CSIDL_FLAG_CREATE with other CSIDL flags. For example if you want to create my documents folder if there is no such one present then we'll call "GetSpecialFolderPath" likewise... [sourcecode language='cpp']// You can be sure that my documents will be present this way CString MyDocuments = GetSpecialFolderPath( CSIDL_PERSONAL | CSIDL_FLAG_CREATE ); // Now create a file in this directory MyDocuments += "/Learning.txt"; // CreateFile [/sourcecode] Above function is extremely easy to use but internally it opens and closes a token handle, so if you want to retrieve multiple entries then you can provide a token handle which may increase performance. Return values from ShGetFolderPath is interpreted as follows... S_FALSE -> SHGetFolderPathA only. The CSIDL in nFolder is valid, but the folder does not exist. Note that the failure code is different for the ANSI and Unicode versions of this function. E_FAIL -> SHGetFolderPathW only. The CSIDL in nFolder is valid, but the folder does not exist. Note that the failure code is different for the ANSI and Unicode versions of this function. E_INVALIDARG -> The CSIDL in nFolder is not valid.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: