4

I'm developing a cross-platform library that is meant to load configuration files from a user's home directory. The idea is to automatically provide configuration parameters without editing code.

This library can be used in desktop apps or in daemons/services. In (I assume) most Unix environments I can use getpwuid() to get the home directory of the user. In Windows SO told me I could use SHGetKnownFolderPath but its documentation says its for desktop apps only. Is there a way to get this path, on Windows, for the user running a service?

Community
  • 1
  • 1
ruipacheco
  • 11,526
  • 14
  • 63
  • 116
  • Why the Linux tag? – Ed Heal Mar 09 '17 at 13:17
  • Trying to get the attention of people who do cross-platform development. – ruipacheco Mar 09 '17 at 13:25
  • 2
    @ruipacheco People who do cross-platform development, most likely follows both of those tags anyway, however, people who only do linux development, can't answer your question. – Algirdas Preidžius Mar 09 '17 at 13:58
  • 1
    Services *are* desktop apps. The clause about "desktop apps only" means you can't use it in, for example, a Windows Phone apps. – Harry Johnston Mar 10 '17 at 00:23
  • ... of course, you'll get the folders associated with the user account that the service is running in. That *might* make sense, depending on how the service is configured. It seems unlikely to be sensible for a library, though; surely the programmer using your library should be setting the parameters, not the end user? – Harry Johnston Mar 10 '17 at 00:31

4 Answers4

3

For a console application the simplest method is to either retrieve the USERPROFILE environment variable or concatenate the values of the HOMEDRIVE and HOMEPATH environment variables.

Use the getenv() function in the standard library: https://msdn.microsoft.com/en-us/library/tehxacec.aspx

Example program:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv) {
    printf("USERPROFILE = %s\n", getenv("USERPROFILE"));
    printf("HOMEDRIVE   = %s\n", getenv("HOMEDRIVE"));
    printf("HOMEPATH    = %s\n", getenv("HOMEPATH"));
    return 0;
}

Output:

USERPROFILE = C:\Users\myuser
HOMEDRIVE   = C:
HOMEPATH    = \Users\myuser
Paul
  • 2,488
  • 20
  • 25
0

So do you want to get user home directory in service state? - If you want that in service state, you have to use GetUserToken() to get user token then duplicate them for CreateprocessAsUser() - Else I think it's better using SHGetSpecialPath(), SHGetTempPath().

Bryant
  • 304
  • 2
  • 15
0

You could resolve %HOMEPATH% using ExpandEnvironmentStrings(...)

u1982
  • 11
  • 1
0

What about this:

#include <shlobj.h> 

WCHAR profilePath[MAX_PATH];
HRESULT result = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, profilePath);
if (SUCCEEDED(result)) {
    // Do whatever you want with it
    // For example:
    // QString::fromWCharArray(profilePath)
}

I haven't tested it, though.

Note that what you receive is a wchar array (necessary to handle paths with special characters).

I think it's also possible to query special folders of other users than the current one by using the hToken parameter.

Also refer to the documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx

I used this code in another case where I wanted to obtain the start menu location. See this answer: C++: How do I create a Shortcut in the Start Menu on Windows

Community
  • 1
  • 1
bweber
  • 2,976
  • 2
  • 20
  • 49
  • No, no, no! The profile directory is NOT the right place for configuration files. Try `CSIDL_APPDATA`. – Harry Johnston Mar 10 '17 at 00:25
  • 1
    From what I understood he wanted the user's home directory. – bweber Mar 10 '17 at 08:05
  • There's always been [some disagreement](https://weblogs.asp.net/alex_papadimoulis/408925) about how best to respond when someone asks the wrong question. I'm firmly in the camp that says you give them the information they need, rather than (or as well as) the information they asked for. – Harry Johnston Mar 10 '17 at 19:54
  • ... besides, the user's home directory isn't necessarily their profile directory anyway. That's just the default if the user account settings don't specify a home directory explicitly. (I'm just nitpicking here, the distinction doesn't really matter, particularly since no modern application should use either the profile directory or the home directory for anything.) – Harry Johnston Mar 10 '17 at 20:04
  • SHGetFolderPathW seems deprecated – Adrian Maire Sep 03 '19 at 12:20