Как я могу создать INI-файл в {commonappdata}, который может быть записан любым использованием при использовании Innosetup

Если я хочу создавать файлы в папке {commonappdata}, мне нужно добавить параметр Permissions:users-modify в строку [Files] Source:....

Это прекрасно работает (я наконец-то понял, как убедиться, что при изменении одного из установленных файлов из установленной программы не использовалась перемещаемая папка).

Однако, как я могу сделать INI-записи из раздела [INI] Filename:... также доступными для записи любому пользователю ПК? В конце концов, существуют программные значения, а не пользовательские.

Как и сейчас, ini-файл пишется установкой Inno-setup, но если я позже запускаю установленную программу и грамматически изменяю ini-файл, то записывается перемещаемая версия ini-файла.

Чтобы быть полным:

  • Я знаю о том, как создать ini-файл в качестве шаблона при установке вашего приложения, а затем при первом запуске программы скопировать их в папку {commonappdata}, но мне просто интересно, можно ли это сделать изнутри скрипт Inno-Setup.

  • Я использую последнюю версию Inno-Setup 5.4.2 под Windows 7 Prof 64 (если это имеет значение).


person Edelcom    schedule 21.04.2011    source источник
comment
Для справки, это создаст дыру в безопасности, особенно если этот файл содержит пути, поскольку это означает, что любой случайный пользователь может заставить других пользователей открывать/запускать/заменять файлы от их имени.   -  person Deanna    schedule 12.08.2014


Ответы (2)


Вас обвинят в этом дизайне. У вас могут быть противоречивые пользовательские настройки, если вы храните их в папках данных приложения. Обратитесь к этот вопрос для получения дополнительной информации. ;)

В любом случае, только разделы [Files], [Dirs] и [Registry] позволяют использовать параметр «Permissions». Таким образом, раздел [Ini] не может создать ini-файл с измененными разрешениями. Одним из способов выполнения вашей задачи может быть использование раздела «ini» для сбора необходимой информации во время установки, а затем в качестве действия после установки перенос содержимого файла ini в файл с измененными разрешениями, созданный через раздел «файлы». Что-то вроде этого:

[Files]
Source: MyProg.ini; DestDir: {commonappdata}\MyCompany; Permissions: users-modify; 
;// ini file contents will be transferred to this file

[Ini]
filename: {commonappdata}\MyCompany\MyProg_Temp.ini; section: users; key: username; string: {username}; Flags: UninsDeleteEntry; 
;// this is used in the installation, and will be deleted in post-install
...

[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
  s: string;
begin
  if CurStep = ssPostInstall then begin
    if LoadStringFromFile(ExpandConstant('{commonappdata}\MyCompany\MyProg_Temp.ini'), s) and
        SaveStringToFile(ExpandConstant('{commonappdata}\MyCompany\MyProg.ini'), s, False) then
      DeleteFile(ExpandConstant('{commonappdata}\MyCompany\MyProg_Temp.ini'));
  end;
end;
person Sertac Akyuz    schedule 21.04.2011

Inno Setup позволяет устанавливать разрешения только в разделах [Files] [Dirs] и [Registry] и вам придется как-то их использовать. Вот 2 решения этой проблемы. Оба хороши, но каждый со своим небольшим недостатком.

Решение 1. Установите разрешение для всего каталога

[Dirs]
Name: {commonappdata}\MyCompany; Permissions:everyone-modify

[INI]
Filename: {commonappdata}\MyCompany\MyProg.ini; Section: "SomeSection"; Key: "SomeKey"; String: "SomeValue"

Это отличное решение, если вы не против изменить права доступа ко всему каталогу. Я возражал и придумал второе решение.

Решение №2. Создайте файл .ini в {tmp} и скопируйте его в раздел [Файлы]:

#define TargetIniDir "{commonappdata}\MyCompany"
#define TargetIniName "MyProg.ini"
....

[Files]
Source: {tmp}\{#TargetIniName}; DestDir: {#TargetIniDir}; Flags:external; Permissions: users-modify;

....

[Code]
procedure PrepareIniFileForCopy(section, key, value, iniFileTemp, iniFileTarget:String);
begin
    if FileExists(iniFileTarget) then 
      FileCopy(iniFileTarget, iniFileTemp, False);

    SetIniString(section, key, value,  iniFileTemp);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  iniFile, iniFileTemp:String;
begin
  if CurStep=ssInstall then begin
    PrepareIniFileForCopy('SomeSection', 'SomeKey', 'SomeValue', ExpandConstant('{tmp}\{#TargetIniName}'), ExpandConstant('{#TargetIniDir}\{#TargetIniName}'));

  end;
end;

Это создаст ваш файл .ini в каталоге {tmp} (который будет удален после завершения установки), а затем скопирует его в раздел [Files] в нужный каталог commondata с нужными разрешениями. Обратите внимание на флаг external в разделе [Files], который означает, что файл не упаковывается в программу установки во время компиляции, а берется динамически во время установки. Также обратите внимание, что создание временного файла должно быть выполнено перед установкой (CurStep=ssInstall означает непосредственно перед установкой).

Я думаю, что это решение хорошее, но не очень красивое. Вы разделяете свою операцию на два разных места, которые полагаются на то, что одно выполняется раньше другого.

Оба решения могут добавлять значения в существующие файлы .ini, а не только создавать новые.

person Michael_S_    schedule 08.08.2014