Regarding your question,
” So, what is the correct procedure of doing this ?
Windows doesn't have a single HOME
standard variable. Instead, in the old days there were HOMEDRIVE
and HOMEPATH
, and apparently because they didn't know about it, with Windows Explorer in Windows 95, a new variable called USERPROFILE
.
[C:\Users\alfps_000]
> set home
HOMEDRIVE=C:
HOMEPATH=\Users\alfps_000
[C:\Users\alfps_000]
> set user
USERDOMAIN=FRIKADELL
USERDOMAIN_ROAMINGPROFILE=FRIKADELL
USERNAME=alfps_000
USERPROFILE=C:\Users\alfps_000
[C:\Users\alfps_000]
> _
The silly triple-oh suffix (as if I were better than double-oh seven) is just what Windows 8.1 saw fit to give me. It's just too much work to cajole Windows into reasonable choices. And so not just with usernames but also with environment variables.
Here's your program rewritten to use the Windows variable that vaguely corresponds to Unix-land HOME
, namely USERPROFILE
:
#include <iostream>
#include <stdlib.h> // getenv
using namespace std;
auto main() -> int
{
cout
<< "User's profile directory: "
<< "[" << getenv( "USERPROFILE" ) << "]"
<< endl;
}
The Windows environment variables are awkward and not guaranteed, but still usable in scripts and very simple programs like the one above. In more serious C++ code you can instead use the SHGetKnownFolderPath
API function. With Visual C++ it can look like this:
#undef UNICODE
#define UNICODE
#include <windows.h>
#include <shlobj.h> // SHGetKnownFolderPath
#include <objbase.h> // CoTaskMemFree
#include <iostream> // std::wcout
#include <memory> // std::unique_ptr
#include <stdexcept> // std::runtime_error, std::exception
#include <stdlib.h> // EXIT_FALURE, EXIT_SUCCESS
using namespace std;
void cotaskmem_free( wchar_t* p ) { CoTaskMemFree( p ); }
auto main() -> int
{
using X = runtime_error;
using String_deallocation = unique_ptr<wchar_t[], void(*)(wchar_t*)>;
try
{
wchar_t* path;
HRESULT const hr = SHGetKnownFolderPath(
FOLDERID_Profile, // REFKNOWNFOLDERID rfid -> %USERPROFILE%
0, // DWORD dwFlags,
0, // HANDLE hToken,
&path // PWSTR *ppszPath
);
if( FAILED( hr ) ) { throw X( "SHGetKnownFolderPath failed" ); }
String_deallocation const path_cleanup( path, cotaskmem_free );
wcout << "User profile directory: [" << path << "]" << endl;
return EXIT_SUCCESS;
}
catch( exception const& x )
{
wcerr << "!" << x.what() << endl;
}
return EXIT_FAILURE;
}
g++ (per version 4.8.2) doesn't yet support API functions from Windows Vista and onward, at least not in general, so if you need to support g++ use some older function.
Note:
It's not unlikely that whatever you intended to access or place in %HOME%
, would better be accessed or placed in one of the other special users's directories, also available via SHGetKnownFolderPath
.