Short answer is you need to platform invoke (pinvoke) SHGetSpecialFolderPath
with the current profile value and then chop off the directory on the end.
[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(
IntPtr hwndOwner,[Out] StringBuilder lpszPath, int nFolder, bool fCreate);
const int CSIDL_PROFILE = 0x0028;
public void foo() {
StringBuilder path = new StringBuilder(260);
SHGetSpecialFolderPath(IntPtr.Zero, path, CSIDL_PROFILE, false);
// Add code here to chop off the dir at the end of the path.
}
There is no direct API call that will return this folder. Calls made to
Environment.GetFolderPath(Environment.SpecialFolder myFolder)
will not obtain this folder because the enumeration for "SpecialFolder" doesn't
include a profile-related value. Additionally there is no native Win32 API
call that will return the value. While the method "SHGetSpecialFolderPath()"
exists, and the enumeration that is passed to this method contains a value
called "CSIDL_PROFILES", making the following call yields an empty path:
SHGetSpecialFolderPath(IntPtr.Zero, path, (int)CSIDL_PROFILES, false);
Fortunately there is a value in the enumation "CSIDL_PROFILE" (notice it's
not plural like above) which does return the path for the currently running
profile. So making this call and then removing the last directory in the
path will give the directory / folder where profiles are kept.