inno setup 初次使用

inno setup从小白到大白

这是我初次使用inno setup制作安装包,花了几日时间搜罗全网中别人的inno经验,制作了一个自己的安装包。这里分享一下我的成果( ̄▽ ̄)"

从新建的向导开始

点击File -> New,开始新建iss文件
新建
取消点击create a new empty script file的勾,否则无法进入向导帮助。点击next
取消点击create a new empty script file
填写软件的名称,版本,公司名,公司网址的信息。点击next
在这里插入图片描述
填写软件的安装目录,这里我选择自定义的安装目录并填了C:\Program Files,my_program是安装解压时的目录,并允许用户修改安装目录的位置。这样在安装时显示的安装目录的路径就为C:\Program Files\my_program。点击next
在这里插入图片描述
编译一个release的版本,这里选择release下的exe的文件位置,允许用户在安装完成后运行这个exe文件,然后点击add folder…选择文件夹,这个文件夹放置了软件运行需要的文件,即安装包压缩的文件。点击next
在这里插入图片描述
在开始菜单创建快捷方式。如果想在开始菜单创建文件的话要取消第一个勾(create a shortcut的那个),然后下面的application start menu folder name会亮起,“我的程序”就是开始菜单的文件名。倒数第二个是在桌面创建快捷方式。点击next
创建快捷方式
这里输入凭证信息,我的软件没有这些(别期待,只是个输出hello world的exe),所以全部为空。点击next
凭证
默认的是仅为当前用户安装,勾选了可以让用户选择安装模式。
安装模式
之后双击安装包就会弹出选择模式
selete install mode
点击next。

选择安装包显示的语言,因为我事先有中文的配置文件,所以这里有Chinese,这里我先选择English,稍后在iss脚本文件中配置回中文模式(如果有中文的话,大家可以直接选择中文,免折腾)。点击next
语言
这里选择编译后得到的安装包的保存路径和名称。点击next
保存路径
这里选择使用#define,这样可以简化脚本文件的编写,一旦需要修改可以只改动define中的内容(生成的isl会有软件名,版本号,公司名之类的)。点击next
define
完成了脚本文件的向导操作,下面就可以生成iss文件了
finish
点击finish后会弹出下面的对话框问你是否立刻编译,选择是会先叫你保存脚本文件,再开始编译生成一个安装包,这里我还需要配置一些信息,所以我先选择否(可以先编译一个版本和后面作比较)
compile

编辑脚本文件

[setup]

根据上面向导中的内容生成出来的iss中的setup部分如下图

setup

选择安装目录

这里添加一行

UsePreviousAppDir=no

不加时,安装包第一次双击打开时可以让用户选择安装目录,但之后再选择安装目录时,就会跳过选择安装目录的这步。加了后每次打开安装包时都可以选择安装目录。

配置图片

WizardImageFile=F:\inno\image\finish.bmp
WizardSmallImageFile=F:\inno\image\small_icon.bmp

WizardSmallImageFile是向导右上角的小图标。所有图片的格式需要为bmp
wizardinmagefile
WizardImageFile是安装向导最后一页左侧的图片,
wizardimagefile

[message]

上面生成的脚本文件没有message这项,可以自己加上。下面设置了安装时对话框的标题和选择安装模式(当前用户 or 所有用户)的对话框标题,setupapptitle是消息的对话框mesbox标题

#define MyOutputBaseFilename “mysetup”
#define MyDialogTitle “安装”
[Messages]
SetupAppTitle= 消息标题
SetupWindowTitle={#MyDialogTitle}{#MyOutputBaseFilename}
PrivilegesRequiredOverrideTitle = {#MyDialogTitle}{#MyOutputBaseFilename}

[languages]

上面选择语言是选择的是english,所以这里是默认的isl文件。
languages
改成中文需要有中文的isl文件,然后选择中文isl的相对文件位置

[Languages]
Name: “chinesesimp”; MessagesFile: “compiler:Languages\Chinese.isl”

中文isl文件可以在一些中文增强版的inno setup中找到。也可以在这里下载chinese.isl
移进inno安装目录的 Languages文件夹中

[tasks]

上面向导生成的tasks如下
tasks
只有创建快捷方式的任务可选,而且默认是不勾选的。这里我改为默认勾选,并且添加创建开始菜单的任务

[Tasks]
Name: “desktopicon”; Description: “{cm:CreateDesktopIcon}”; GroupDescription: “{cm:AdditionalIcons}”; Flags: checkedonce
Name: “startmenuicon”;Description:“创建开始菜单”;GroupDescription:"{cm:AdditionalIcons}"; Flags: checkedonce

删除Flag也可以达到勾选的效果

[files]

这里我没有什么需要改,所以省略了吧

[icons]

这里配置桌面快捷方式的文件和开始菜单的文件,如果软件还需要在菜单在新建一项“软件说明书“,可以在这里配置这项

[Icons]
Name: “{group}{#MyAppName}”; Filename: “{app}{#MyAppExeName}”; Tasks: startmenuicon
Name: “{autodesktop}{#MyAppName}”; Filename: “{app}{#MyAppExeName}”; Tasks: desktopicon
Name: “{group}\使用说明”; Filename: “F:\inno\软件说明书.txt”;Tasks: startmenuicon

第一和第二行是向导默许生成的,第三行是软件说明书一项。{group}是开始菜单的文件名,如向导时快捷方式配置那一页的”我的程序“就是group。这里只是说明一下,后面编译时我只用默认的前二行。

[Run]

安装完成时默认运行exe,这里也没有要改的,省略

[Registry]

添加registry可以在注册表写东西,如下面一行

[Registry]
Root: HKLM; Subkey: “Software\myprogram”; ValueType: string; ValueName: “myprogramVersion”; ValueData: “1.0”; Flags: uninsdeletevalue

表示在注册表中的根为HKEY_LOCAL_MACHINE中的Software项添加myprogram一行,记录我软件的版本号,uninsdeletevalue表示卸载时就删除该项。后面编译时没有这项
在这里插入图片描述

后面发现inno setup默认安装时会根据appid在注册表中写入软件的卸载信息,如下
在这里插入图片描述

[code]

这里可以添加一些代码段,我在这里加了安装时检测软件是否安装(通过检查注册表中的软件信息实现),如果安装了调用卸载程序,和安装时检查安装程序是否已经打开的代码。下面直接上代码

[Code]
{获取安装信息}
function GetUninstallString():String;
var
ResultStr: String;
begin
	ResultStr:='';
	{PrivilegesRequired=lowest}
	//注册表位置,需要知道AppId在注册表中的位置,可以安装后在注册表中查找AppId
	if RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{1138B0E0-ABC0-424F-A80D-A834D140ED75}_is1', 'UninstallString', ResultStr) then
    begin
		ResultStr := RemoveQuotes(ResultStr);
	{PrivilegesRequired=admin}
	//同上
    end else if RegQueryStringValue(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{1138B0E0-ABC0-424F-A80D-A834D140ED75}_is1', 'UninstallString', ResultStr) then
	begin
		ResultStr := RemoveQuotes(ResultStr);
	end;
    Result := ResultStr;
end;

//卸载程序
function UninstallApp(uninstallString: String): Boolean;
var
    ResultCode: Integer;
    bRes: Boolean;
begin
    result := true;
    if length(uninstallString) > 0 then 
    begin
        //如果发现程序已经安装过了
        if MsgBox('{#MyAppName} 已经安装,是否卸载本程序?', mbConfirmation, MB_YESNO) = IDYES then
        begin
            uninstallString := RemoveQuotes(uninstallString);  
            bRes := Exec(uninstallString, '/silent', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
            if bRes and (ResultCode = 0) then   
            begin
                result := true;
                Exit;
            end 
            else
            begin
              MsgBox('卸载失败!请手动卸载', mbInformation, MB_OK);
              result:= false;
            end;
        end
        else
            result := false;
    end;    
end;

//安装程序是否已启动
function InitializeSetUpOpened(): Boolean;
var
    bRes: Boolean;
    MainRun: HWND;
    ResultCode: Integer;
begin
    result := false;
    //需要一个固定的窗口标题
    MainRun := FindWindowByWindowName('{#MyDialogTitle}{#MyOutputBaseFilename}');
    if MainRun <> 0 then
    begin
      MsgBox('程序已启动!', mbInformation, MB_OK);
      result := true;
    end;
end;

//选择完安装模式才进入
function InitializeSetup(): Boolean;
var 
    uninstallString: String;
begin
    result := true;
    //已安装程序
    if Not UninstallApp(GetUninstallString()) then
    begin
      result := false;
      Exit;
    end;
    //已打开安装程序
    if InitializeSetUpOpened() then
    begin
      result := false;
      Exit;
    end;
end;

最后可以编译运行了

PS

  • isl中的路径都可以改为相对路径
  • 选择完安装模式才会进入InitializeSetup

安装时遇到的问题

错误5:拒绝访问

在这里插入图片描述
原因:权限不足。
如果选择仅为当前用户安装,则执行时没有管理员权限。而需要打包的工程设置了需要管理员权限,如下图的vs工程的属性页中
requireAdministrator
需要修改inno的设置。下载reshacker
reshacker安装包下载 http://www.angusj.com/resourcehacker/reshacker_setup.exe
reshacker官网 http://www.angusj.com/resourcehacker/
运行 resource_hacker.exe,打开SetupLdr.e32
open
setupldr.e32
modify
再次编译,得到的安装包图标会带有一个盾,即以管理员方式运行

卸载时检测软件是否打开(没有满意的解决方法)

卸载时如何检测程序是否打开?默认的卸载方法是删除没有被打开的程序占用的文件,留下一些无法删除文件让用户自己删除。

  • 经过一番实践,发现网上istask.dll和psvince.dll的例子无法检测我的软件是否打开(明明网上一大堆这些例子,不知道为什么我这么惨。而且这些dll无法检测外,双击打开安装程序时还会卡上个5秒,总之很慢);
  • 另一个FindWindowByWindowName是通过窗口标题查找程序的,但hyper3d的标题会随着打开的工程文件名变化,貌似也没用;
  • 还有一个FindWindowByClassName查找窗口,但不知道哪个是窗口的className( ̄▽ ̄)”;
  • 最后还有一个方法是在setup中设置appMutex值,在c++程序中createMutex和releaseMutex,这种方法只支持程序单开(有人讲现在很多程序都是单开的,但我觉得双开的多,如word之类的,难道是手机程序!?不知道手机程序如何打包)。

终于找到一个卸载时强制关闭所有程序的代码段
[Code]
function InitializeUninstall(): Boolean;
var ErrorCode: Integer;
begin
ShellExec(‘open’,‘taskkill.exe’,’/f /im {#MyAppExeName}’,’’,SW_HIDE,ewNoWait,ErrorCode);
ShellExec(‘open’,‘tskill.exe’,’ {#MyAppName}’,’’,SW_HIDE,ewNoWait,ErrorCode);
result := True;
end;

关于上面提到的安装时检测安装程序有冇打开,因为安装程序的windowName固定,所以可以用FindWindowByWindowName。O( ̄▽ ̄)ブ

[1]: reshacker: https://blog.csdn.net/longji/article/details/53523808
[2]: 中文 https://www.cnblogs.com/leochan007/p/8203675.html
[3]: 窗口标题 https://blog.csdn.net/chenlu5201314/article/details/54963255
[4]: 注册表 https://blog.csdn.net/yushanddddfenghailin/article/details/17250871

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值