5

I'm having a little problem with my program...

I have to create a file with the application data, but I don't know how to access the %USER% or %APPDATA% directories...

I've tried to use the application folder, but if I install the application in D:\Program Files\(Organization)\(APPName) I cannot write new files in this directory, I can just read or modify if I don't have admin privileges...

So, the question is: How to access the %USER% folder or Get ADMIN privileges with the application... PS.: I'm using VCL in C++ Builder

Sankumarsingh
  • 9,889
  • 11
  • 50
  • 74
mauroaraujo
  • 332
  • 1
  • 10
  • 23

3 Answers3

4

Assuming this is a pure Windows question, you should use SHGetSpecialFolderPath.

  • Pass CSIDL_PROFILE to get the equivalent of %USERPROFILE%.
  • Pass CSIDL_APPDATA to get the equivalent of %APPDATA%.

Note that the documentations for the CSIDL based functions are a little scary in that they talk about function not being supported or deprecated. Instead they urge you to use SHGetKnownFolderPath. That's fine if your program never needs to run on XP. If that's the case, go ahead and use SHGetKnownFolderPath. Otherwise, use the CSIDL based options.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

One classic way is to read the environment variables using getenv:

char *user = getenv("USER");
char *appdata = getenv("APPDATA");

Regarding user rights and performing file read/write/create in these locations, you certainly can in the user folder the application is running as. In other folders, you'll need to run it as either the target user or administrator. Also, after installing an application in Program Files or Program Files (x86), the system will not allow you to write there. Installations are performed under the 'trustedinstaller' user credentials and the final user rights are set during installation for 'current user' or 'all users'.

Hope this helps.

DNT
  • 2,356
  • 14
  • 16
  • But, it's just a var... Will it works with VCL? And I must to include another library to it works? – mauroaraujo Jan 29 '14 at 12:21
  • Installations are not, in general, performed by TrustedInstaller. Using `getenv` is not the right way to get this information. – David Heffernan Jan 29 '14 at 12:47
  • @David Heffernan: I mention 'One classic way' and not 'the only way'. This is portable to other platforms too for reading environment variables, where windows-specific API has changed quite a few times, despite Microsoft's efforts to maintain backward-compatibility. By 'installation', I refer to the default windows installation (msi) that actually uses the TrustedInstaller account in late windows incarnations. – DNT Jan 29 '14 at 12:54
  • @mauroaraujo: This is standard C call actually that works in C++ too. It is included in the standard run-time. – DNT Jan 29 '14 at 13:00
  • @DNT You are relying on the thing that creates your process setting up the appropriate environment variables. – David Heffernan Jan 29 '14 at 13:02
  • @DavidHeffernan: I agree in this case, since the author asked about environment variables. And yes, there is a hidden assumption here, that nobody has started a shell under the process with altered environment strings. However, I think that obtaining the real and effective user, is beyond the scope of the question. – DNT Jan 29 '14 at 13:09
0

Here an example to get the user folder, using SHGetKnownFolderPath function. Here you can see all the constants that you can use with this function to get the folder paths.

#include <iostream>
#include <atlstr.h>
#include <shlobj.h>

int main()
{
    PWSTR userFolderPath;
    HRESULT result = SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &userFolderPath);

    if (result == S_OK)
    {
        CString str1(userFolderPath);
        const wchar_t* str2 = str1;
        std::wstring str3(str2);
        wprintf(str3.c_str());
    }
    else
    {
        wprintf(L"Error\n");
    }

    CoTaskMemFree(static_cast<LPVOID>(userFolderPath));
}
Juan Carlos
  • 131
  • 1
  • 6