如何配置 Inno Setup 来卸载所有内容?

发布于 2024-07-14 14:00:01 字数 413 浏览 7 评论 0原文

我是 Inno Setup 的新手。 卡在一个问题上~如何配置卸载部分以删除应用程序创建的所有文件、文件夹、子文件夹,甚至新文件/文件夹等(换句话说,100% 删除应用程序和关联文件)。

我在这里和他们的论坛上四处寻找,但一无所获。 任何人都可以向我指出有关如何执行此操作的文档、常见问题解答等吗?

更新

感谢迄今为止的所有反馈(非常棒)。 所以看起来我可以使用卸载部分中的 {app}*.* 指令删除所有内容。 看起来每个人都反对它。 所以现在的问题变成了(我想知道这是否应该是一个全新的问题)在卸载过程中,我们是否可以询问用户“您想删除与此相关的所有项目文件吗?”应用?' 如果他们回答“是”,则运行卸载 {app}*.* 部分?

谢谢 -

I am new to Inno Setup. Stuck on one issue ~ how to configure the uninstall piece to remove all files, folders, subfolders, and even new files/folders etc. created by application (in other words, a 100% removal of the application and associated files).

I hunted around here and also on their forum, and came up empty. Can anyone point me to a document, FAQ etc. regarding how to do this?

UPDATE

Thanks for all the feedback so far (very awesome). So it looks like I can delete everything using the {app}*.* directive in the uninstall section. Also looks like everyone is advising against it. So the question now becomes (I am wondering if this should be a totally new question) is there a way during the uninstall that we can ask the user 'Do you want to remove all project files associated with this application?' and if they answer YES, to run the uninstall {app}*.* piece?

Thanks -

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

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

发布评论

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

评论(9

任谁 2024-07-21 14:00:01

我认为推荐的方法是在卸载部分指定要删除的内容。 原因是,如果用户出于某种原因决定将他们自己不想删除的文件放在您的安装目录中,或者他们可能想要保留的已保存数据(也许他们卸载是为了安装更新版本? )

话虽这么说,我不知道脚本是什么,但如果您使用 ISTool(强烈推荐),只需进入“卸载删除”部分并添加您想要删除的内容。 它应该在一个漂亮的 GUI 中呈现所有可能的选项,并为您生成脚本。

编辑:Inno Setup 文档中的一个示例:

[UninstallDelete]
Type: files; Name: "{win}\MYPROG.INI"

但是他们强烈要求你不要做类似的事情

[UninstallDelete]
Type: files; Name: "{app}\*.*"

注意:不要试图在此处使用通配符来删除其中的所有文件
{app} 目录。 我强烈
建议不要为两个人这样做
原因。 首先,用户通常不会
感谢拥有他们的数据文件
他们放入应用程序目录中
在没有警告的情况下删除(他们可能
只是卸载它,因为它们
想要将其移动到不同的驱动器,
例如)。 最好还是离开它
由最终用户手动删除
如果他们愿意的话。 另外,如果用户
碰巧将该程序安装在
错误的目录(对于
例如,C:\WINDOWS),然后转到
卸载它可能会造成灾难性的后果
结果。 再次强调,不要这样做!

I think the recommended approach is to specify what to remove in the uninstall section. The reasoning is that what if for whatever reason the user decided to put their own files in your installation directory that they didn't want removed, or saved data that they might want to keep around (maybe they uninstall is to install a newer version?)

That being said, I don't know offhand what the script is, but if you use ISTool (highly recommend) just got to the Uninstall Delete section and add things you want removed. It should present all the possible options in a nice GUI and generate the script for you.

Edit: An example from the Inno Setup documentation:

[UninstallDelete]
Type: files; Name: "{win}\MYPROG.INI"

But they strongly you don't do something like

[UninstallDelete]
Type: files; Name: "{app}\*.*"

NOTE: Don't be tempted to use a wildcard here to delete all files in
the {app} directory. I strongly
recommend against doing this for two
reasons. First, users usually don't
appreciate having their data files
they put in the application directory
deleted without warning (they might
only be uninstalling it because they
want to move it to a different drive,
for example). It's better to leave it
up to the end users to manually remove
them if they want. Also, if the user
happened to install the program in the
wrong directory by mistake (for
example, C:\WINDOWS) and then went to
uninstall it there could be disastrous
consequences. So again, DON'T DO THIS!

一片旧的回忆 2024-07-21 14:00:01

您可能应该将此作为一个全新的问题,但我也会在这里回答您更新的问题。 查看 Inno 安装文档中的“Pascal Scripting:卸载代码”部分。

举一个例子,如何在卸载过程中有条件地删除数据文件:

[Code]

procedure DeleteBitmaps(ADirName: string);
var
  FindRec: TFindRec;
begin
  if FindFirst(ADirName + '\*.*', FindRec) then begin
    try
      repeat
        if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then begin
          if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin
            DeleteBitmaps(ADirName + '\' + FindRec.Name);
            RemoveDir(ADirName + '\' + FindRec.Name);
          end;
        end else if Pos('.bmp', AnsiLowerCase(FindRec.Name)) > 0 then
          DeleteFile(ADirName + '\' + FindRec.Name);
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usUninstall then begin
    if MsgBox('Do you want to delete all data files?', mbConfirmation,
        MB_YESNO) = IDYES 
    then begin
      DeleteBitmaps(ExpandConstant('{app}'));
    end;
  end;
end;

但是,根据您需要清理的内容的数量,您最好创建一个特殊的帮助程序,该程序是安装的一部分,并且可以在卸载应用程序期间执行(使用[UninstallRun]部分中的条目)。

You should probably have made this a totally new question, but I'll answer your updated question here as well. Have a look at the section "Pascal Scripting: Uninstall Code" in the Inno Setup Documentation.

To give an example how to conditionally delete data files as part of the uninstallation process:

[Code]

procedure DeleteBitmaps(ADirName: string);
var
  FindRec: TFindRec;
begin
  if FindFirst(ADirName + '\*.*', FindRec) then begin
    try
      repeat
        if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then begin
          if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin
            DeleteBitmaps(ADirName + '\' + FindRec.Name);
            RemoveDir(ADirName + '\' + FindRec.Name);
          end;
        end else if Pos('.bmp', AnsiLowerCase(FindRec.Name)) > 0 then
          DeleteFile(ADirName + '\' + FindRec.Name);
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usUninstall then begin
    if MsgBox('Do you want to delete all data files?', mbConfirmation,
        MB_YESNO) = IDYES 
    then begin
      DeleteBitmaps(ExpandConstant('{app}'));
    end;
  end;
end;

But depending on the amount of stuff you need to clean up you might be better off to create a special helper program that is part of the installation, and which can be executed during the uninstallation of the app (using an entry in the [UninstallRun] section).

她说她爱他 2024-07-21 14:00:01

有时需要删除安装时最初未写入用户磁盘的文件。 其中一种情况是您的应用程序在启动时会自行更新。 可以通过这种方式将新文件添加到磁盘,这些文件不属于卸载程序的一部分。

对于这种情况,我建议您创建一个“补丁清单”文件,该文件保留 {app} 目录中应包含哪些文件的运行记录。 下面是从 {app} 目录中名为“patch_manifest.txt”的文件读取的代码示例

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  i: Integer;
  arrayLen: Longint;
  item: String;
  itemsToDelete: Array of String;
begin
  case CurUninstallStep of
    usUninstall:
      begin
        LoadStringsFromFile(ExpandConstant('{app}') + '\patch_manifest.txt', itemsToDelete);
        arrayLen := GetArrayLength(itemsToDelete);
        for i := 0 to arrayLen-1 do
          begin
          item := ExpandConstant('{app}') + '\' + itemsToDelete[i];
          if FileExists(item) then
            DeleteFile(item);
          if DirExists(item) then
            RemoveDir(item);
          end;
      end;
  end;
end;

以及 patch_manifest.txt 的示例

data/something_here.dat
data/moredatahere.dat
data/
Launcher.exe
patch_manifest.txt

注意:patch_manifest 中的行顺序很重要。 应首先列出目录中的所有文件,然后列出目录 - 不为空的目录无法删除。

您的应用程序应附带 patch_manifest,并且 patch_manifest 应随每个补丁进行更新。 将此作为构建过程的一部分,这样您就不会忘记更新它!

即使您提示用户,也不要使用通配符 (.) 进行删除,这一点非常重要。 卸载程序具有提升的权限,可能会破坏用户的计算机。 以用户意外地将您的应用程序安装到 C:\Windows\ 或 C:\Program Files 为例。

另一个好主意是在删除文件之前执行 MD5 检查来验证该文件确实是“您的文件”。 在这种情况下,您的 patch_manifest.txt 不仅包含文件的相对路径,还包含 MD5 校验和。

There are cases to want to delete files which were not initially written to the user's disk at time of installation. One of these cases is when you have an application that updates itself when it is started. New files can be added to the disk in this manner which are not a part of the uninstaller.

For this case I suggest that you create a "patch manifest" file which keeps a running record of what files should be in the {app} directory. Find below a sample of code that reads from a file in the {app} dir called 'patch_manifest.txt'

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  i: Integer;
  arrayLen: Longint;
  item: String;
  itemsToDelete: Array of String;
begin
  case CurUninstallStep of
    usUninstall:
      begin
        LoadStringsFromFile(ExpandConstant('{app}') + '\patch_manifest.txt', itemsToDelete);
        arrayLen := GetArrayLength(itemsToDelete);
        for i := 0 to arrayLen-1 do
          begin
          item := ExpandConstant('{app}') + '\' + itemsToDelete[i];
          if FileExists(item) then
            DeleteFile(item);
          if DirExists(item) then
            RemoveDir(item);
          end;
      end;
  end;
end;

and a sample of the patch_manifest.txt

data/something_here.dat
data/moredatahere.dat
data/
Launcher.exe
patch_manifest.txt

Note: The order of the lines in the patch_manifest is important. All files within a directory should first be listed followed by the directory - directories which are not empty cannot be delete.

Your application should be shipped with a patch_manifest and the patch_manifest should be updated with every patch. Make this part of your build process so you don't forget to update it!

It is very important that you do not delete by wildcard (.) even if you prompt the user. Uninstaller's have elevated privileges which could potentially destroy a user's computer. Take the case of a user who accidentally installed your application to C:\Windows\ or C:\Program Files.

Another good idea is to verify that the file is in fact "your file" by performing an MD5 check prior to deleting it. In this case your patch_manifest.txt would not only include the relative path to the file but also the MD5 checksum.

森林散布 2024-07-21 14:00:01

您不能使用 InnoSetup 卸载它未安装的任何内容,而且您也不应该这样做。 如果我安装了一个应用程序,输入了大量数据,然后决定使用其他东西来从您的应用程序中读取这些数据,我会非常不高兴。 如果你的卸载杀死了我已经完成的所有工作,我可能会想来找你。 可能也不会请你喝杯咖啡。

或者考虑我在评估几个应用程序的过程中安装您的应用程序的情况。 我尝试了这些应用程序,并继续使用您的应用程序,因为我更喜欢它,并且每次我输入更多数据。 然后我决定暂时不做任何事情,所以我删除了所有测试应用程序。 一周后,我决定现在需要使用您的应用程序,然后我重新安装了它。 哎呀! 我现在想要使用的所有测试工作都消失了。

以上就是为什么当您卸载应用程序时,它会留下您在文件夹中创建的所有内容,例如配置文件、数据文件等。它不知道您希望它对它们做什么,所以它不会处理它们。

You can't use InnoSetup to uninstall anything it didn't install, and you shouldn't want to do so. I for one would be very unhappy if I installed an application, entered a lot of data, and then decided to use something else instead that would read that data from your app. If your uninstall killed all of the work I'd already done, I might be tempted to come looking for you. And probably not to buy you a cup of coffee.

Or consider the case where I install your application in the process of evaluating several. I try the apps, and keep going back to yours because I like it a little better, and each time I enter more data. Then I decide not to do anything for a while, so I remove all the test apps. In a week, I decide I need to use your app now after all, and I reinstall it. Oops! All of the work I did testing it that I now wanted to use is gone.

The above is why, when you uninstall an application, it leaves behind anything you created in the folders, like configuration files, data files, etc. It doesn't know what you want it to do with them, so it leaves them alone.

树深时见影 2024-07-21 14:00:01

这应该可以解决问题:

[Dirs]
Name: "{app}"; Flags: uninsalwaysuninstall

This should do the trick:

[Dirs]
Name: "{app}"; Flags: uninsalwaysuninstall
私藏温柔 2024-07-21 14:00:01

在 Inno Setup studio 中添加删除文件/文件夹项。 或者直接使用如下脚本。

[生成的代码示例]

[UninstallDelete]
Type: filesandordirs; Name: "{app}\unnecessary_files"

Add delete file/folder item in Inno Setup studio. Or directly use the script as follows.

[Generated code sample]

[UninstallDelete]
Type: filesandordirs; Name: "{app}\unnecessary_files"
骄兵必败 2024-07-21 14:00:01

我想删除在运行时在安装的文件夹中创建的 gData.dat

,并且对我来说工作正常

[UninstallDelete]
Type: files; Name: "{app}\gData.dat"

I wanted to delete gData.dat which created on run time in installed folder

and was working fine for me

[UninstallDelete]
Type: files; Name: "{app}\gData.dat"
说不完的你爱 2024-07-21 14:00:01

如果您没有为条目指定“uninsneveruninstall”,这不是默认值吗?

编辑 - 抱歉,我没有意识到你在谈论新创建的数据文件。

Isn't that the default if your don't specify "uninsneveruninstall" for an entry?

edit - Sorry I hadn't realised you were talking about newly created data files.

芯好空 2024-07-21 14:00:01

要删除所有内容,我使用以下命令:

[UninstallDelete]
Type:files; Name: "{app}"

To delete everything I use this :

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