如何在使用 Innosetup 时在 {commonappdata} 中创建一个可由任何用户写入的 INI 文件

发布于 2024-11-02 14:11:43 字数 676 浏览 0 评论 0原文

如果我想在 {commonappdata} 文件夹中创建文件,我需要在 [Files] 上添加 Permissions:users-modify 参数来源:... 行。

这非常有效(我终于弄清楚了如何确保在从已安装的程序中更改已安装的文件之一时不使用漫游文件夹)。

但是,如何使 [INI] Filename:... 部分中的 INI 条目可供任何用户写入电脑?毕竟,存在的是程序价值,而不是用户价值。

现在,ini 文件是由 Inno-setup 安装写入的,但如果我稍后启动安装的程序并在语法上更改 ini 文件,则会写入 ini 文件的漫游版本。

完整:

  • 我知道如何在安装应用程序时创建 ini 文件作为模板,然后在第一次运行该程序时,将它们复制到 < code>{commonappdata} 文件夹,但我只是想知道这是否可以从 Inno-Setup 脚本中实现。

  • 我正在 Windows 7 Prof 64 下运行最新版本的 Inno-Setup 5.4.2(如果这会产生影响)。

If I want to create files in the {commonappdata} folder, I need to add the Permissions:users-modify parameter on a [Files] Source:... line.

This works great ( I finally figured out how to make sure no roaming folder was used when changing one of the installed files from within the installed program ).

However , how can I make INI-entries from the [INI] Filename:... section also writeable by any user on the PC ? There are program values, not user values, after all.

As it is now, the ini-file is written by the Inno-setup installation, but if I later start the installed program and change the ini file grammatically, a roaming version of the ini file is written.

To be complete:

  • I know about the way to create the ini-file as a template when installing your application, and than , upon first run of the program , copy them over to the the {commonappdata} folder, but I am just wondering whether this can be achieved from within the Inno-Setup script.

  • I am running the latest version of Inno-Setup 5.4.2 under Windows 7 Prof 64 ( if this should make a difference ).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天邊彩虹 2024-11-09 14:11:43

你会因为这个设计而受到指责。如果将用户设置保存在应用程序数据文件夹中,则可能会出现矛盾的用户设置。请参阅此问题了解更多问题。 ;)

无论如何,只有 [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;

You'll be blamed for this design. You might have contradicting user settings if you keep them in application data folders. Refer to this question for more blame. ;)

Anyway, only [Files], [Dirs] and [Registry] sections allow 'Permissions' parameter. So it is not possible for an [Ini] section to create an ini file with modified permissions. One way to achieve your task can be to use the 'ini' section to collect necessary information during setup, then as a post-install action, transfer the contents of the ini file to one with modified permissions created through the 'files' section. Something like this:

[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;
箜明 2024-11-09 14:11:43

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:在 {tmp} 中创建 .ini 文件并将其复制到 [Files] 部分:

#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;

这将在 {tmp} 目录中创建 .ini 文件(安装后该文件将被删除)完成),然后将 [Files] 部分复制到具有所需权限的所需 commondata 目录。
请注意 [Files] 部分中的 external 标志,这意味着文件不会在编译时打包到安装程序中,而是在安装时动态获取。另请注意,临时文件的创建必须在安装之前完成(CurStep=ssInstall 表示在安装之前)。

我认为这个解决方案很好,但不是很漂亮。您将操作拆分到两个不同的位置,其中一个位置先于另一个位置完成。

这两种解决方案都可以向现有 .ini 文件添加值,而不仅仅是创建新文件。

Inno Setup allows to set permissions only in sections [Files] [Dirs] and [Registry] and you'll have to use those somehow. Here are 2 solution to this problem. Both are good but each with a slight disadvantage.

Solution #1: Set permission to the entire directory

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

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

This is a great solution if you don't mind to have the entire directory's permissions modified. I did mind and came up with a second solution.

Solution #2: Create your .ini file in {tmp} and copy it in the [Files] section:

#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;

This will create your .ini file in the {tmp} directory (which will be deleted after install finishes), then copied in the [Files] section to the desired commondata directory with desired permissions.
Note the external flag in the [Files] section which means the file isn't packed to the setup at compile time, rather taken dynamically at installation time. Also note that the creation of the temporary file must be done before the install (CurStep=ssInstall means right before installation).

I think this solution is good, but not very pretty. You split your operation to two different places, that rely one one being done before the other.

Both solution can add values to existing .ini files, not just create new ones.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文