Search code examples
c++qtqsettings

Unable to change path of QSettings


I use the c:\windows\winf32.ini to store software parameters, I can read it by doing this:

QSettings settings("c:/windows/winf32.ini", QSettings::IniFormat, Q_NULLPTR);

I can read the file with the absolute path but when I use setValue() and sync(), the file is not updated.
However, with relative path "winf32.ini" he write correctly the change but it is not in the c:\windows\ path.
By default, with the QSettings::IniFormat, the folowing files are used:

  1. FOLDERID_RoamingAppData\MySoft\Star Runner.ini
  2. FOLDERID_RoamingAppData\MySoft.ini
  3. FOLDERID_ProgramData\MySoft\Star Runner.ini
  4. FOLDERID_ProgramData\MySoft.ini

So to change it, I have tried this:

QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, "c:/windows");
QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, "c:/windows");
QSettings settings("winf32.ini", QSettings::IniFormat, Q_NULLPTR);  

But settings is empty. I use setPath before declare my settings variable because in the QSettings doc, it says:

Warning: This function doesn't affect existing QSettings objects.

I don't see what is the problem.


Solution

  • This is definitely a permissions issue. Your user may have administrative privileges but due to UAC (User Account Control) you must explicitly grant those privileges to any new process, otherwise that process will be execute with a lower authorization level. For example, this is the reason why Windows asks you every time if you want to run certain software (such as installers) as administrator, even when your user is the administrator.

    To check it, just open the File Explorer, go to the directory where your executable was compiled, right-click on the executable and choose "Run as administrator". Windows (actually, the UAC) will ask you to confirm the action. After it, check your INI file has been modified.

    You can force your executable to ask for administrative privileges every time it runs by setting a linker flag:

    • Visual Studio: go to project's properties, then Linker > Manifest File > UAC Execution Level and set it to requireAdministrator. (Do not forget to set it for all the configurations of your project).

      enter image description here

    • Qt Creator (qmake): add QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\" to your .pro file.


    For completeness of the answer, my tests were performed with the code below:

    #include <QSettings>
    
    int main(int argc, char* argv[])
    {
      QSettings settings("c:/windows/winf32.ini", QSettings::IniFormat);
    
      settings.setValue("hello", "world");
    
      return 0;
    }