杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3490|回复: 0

Inno Setup 制作升级包必须面临的几个问题

[复制链接]
发表于 2017-6-16 00:04:38 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 升级包安装程序如何不再产生新的安装、卸载程序
    Inno_setup中AppId是用来标识某个应用程序的唯一标识,因此升级包中的AppId字段应该和原始安装程序的AppId相同。
    CreateUninstallRegKey字段,改值设置为no则安装程序将不会在控制面板的“添加/删除程序”中再创建一个。当这个关键字设置为 no时,UpdateUninstallAppName通常也设置为 no。
    UpdateUninstallAppName如果为 yes, 当添加到一个已存在的卸载记录时,安装程序将以当前的安装程序的 AppName 替换在卸载记录中的 AppName。卸载记录中的 AppName决定了卸载程序显示的标题。如果你的安装程序只是一个升级或附加到一个已存在的程序,并且你不想改变卸载程序的标题,那么你可以设置该值为no。
2. 如何检测以前的应用程序正在运行
    判断某个应用程序是否正在运行,这里可以采用两种方式:一种是应用程序的进程是否正在运行;一种是通过窗口名称来检测。采用第一种方式时要引入ISTask.dll文件(它通常可以在Inno_setup安装包里面找到),实例代码如下:
    1) 通过进程检测是否正在运行
         首先确保ISTask.dll文件和脚本文件位于同一目录:
          1.jpg
        其次确保[Files]段中添加:
         2.jpg
        最后code段中加入一下函数调用:
         3.jpg
    2) 通过窗口检测是否正在运行,主要是通过FindWindowByWindowName()函数,下面以检测有道词典是否正在运行为例:
          4.jpg
    以上两种情况可以依据自己的实际情况来选择,如果你的应用程序窗口固定那么采用第二种检测方式会方便一些;但是如果你无法确定窗口名称或你的窗口名称是会变化的,则采用第一种方式会更好。

3. 如何修改控制面板里原有程序的版本信息
    制作升级包不得不面对的问题是版本升级,那么像下面所示如何修改控制面板中存在的版本信息是我们不得不面对的问题:
    5.jpg
    如何修改呢?看看我们的注册表就知道了:
    6.jpg
    图中标识的就是控制面板中可以看到的所有信息,那么解决方案就是修改注册表中的信息,具体代码如下:
    7.jpg
   具体涉及的两个操作就是:RegQueryStringValue()查询注册表和RegWriteStringValue()修改注册表,具体使用一看便知。

4. 如何修改控制面板里原有程序的显示图标
    有了上面的如何修改控制面板里的版本信息,相信你已经猜到了,修改控制面板里应用程序的显示图标也是通过修改注册表来实现的,这里要提到的是:DisplayIcon字段,用来定义控制面板中应用程序图标的显示路径,代码如下:
    8.jpg
    升级包程序运行之后,控制面板中的信息为:
    9.jpg
    可以看到应用程序的显示图标和版本信息都已经修改了,再看下注册表里面,添加了DisplayIcon字段,其它信息也已经修改:
    10.jpg

5. 如何检测浏览器正在运行
     适用于当前主流浏览器,代码如下:
      11.jpg

6. 如何进行文件查找及拷贝
    不管是在安装包制作或升级包制作过程中,通常面临着文件的拷贝,除了[Files]段中的文件拷贝,请看如下的查找及拷贝操作:
    12.jpg
   FileSearch('rdp.tmp' , ExpandConstant('{app}'))表示查找应用程序安装目录下是否存在rdp.tmp文件,如果存在则返回该文件的绝对路径,如果不存在则返回' '
   FileCopy(ExpandConstant('{tmp}\rdp.tmp') , ExpandConstant('{app}\rdp.tmp') , false)是将临时目录下的rdp.tmp文件拷贝到应用程序安装目录下,这里要注意两点:
   1> 第二个参数目标文件,一定要带着最终的文件名,如果只是一个目录的路径,则拷贝操作会出错。
   2> 第三个参数为true代表如果最终文件存在则拷贝操作失败,如果为false则拷贝操作会覆盖原有文件。
总结:以上就是2天的收获,升级包制作完成。Inno_setup是个比较强大的工具,里面还可以运行cmd命令。

相关代码:
  1. // 卸载时判断浏览器是否正在运行  
  2. function InitializeUninstall(): Boolean;  
  3. var  
  4.     iehWnd, ffhWnd, chrhWnd, b360hWnd, safhWnd, i: Integer;  
  5. begin  
  6.     result:=true;  
  7.     iehWnd := FindWindowByClassName('IEFrame');  
  8.     ffhWnd := FindWindowByClassName('MozillaWindowClass');  
  9.     b360hWnd := FindWindowByClassName('360se6_Frame');  
  10.     chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');  
  11.     safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');  
  12.     i := 0;  
  13.       
  14.     while (iehWnd>0) or (ffhWnd>0) or (b360hWnd>0) or (chrhWnd>0) or (safhWnd>0) do  
  15.     begin  
  16.       if i > 0 then  
  17.       begin  
  18.          Msgbox('请确保所有浏览器都已关闭!', mbInformation, MB_OK);  
  19.       end;  
  20.         
  21.       if Msgbox('插件更新程序检测到浏览器正在运行。'  #13#13 '请您先关闭所有浏览器,单击“是”继续更新,否则按“否”退出安装', mbConfirmation, MB_YESNO) = idNO then  
  22.       begin  
  23.            Result:=false;  
  24.            iehWnd :=0;  
  25.            ffhWnd :=0;  
  26.            b360hWnd :=0;  
  27.            chrhWnd :=0;  
  28.            safhWnd :=0;  
  29.       end else begin  
  30.         Result :=true;  //卸载程序继续  
  31.         iehWnd := FindWindowByClassName('IEFrame');  
  32.         ffhWnd := FindWindowByClassName('MozillaWindowClass');  
  33.         b360hWnd := FindWindowByClassName('360se6_Frame');  
  34.         chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');  
  35.         safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');  
  36.       end;  
  37.       i := i+1;  
  38.     end;  
  39. end;  
  40.   
  41.   
  42. // 检测应用服务是否正在使用  added by houqd 2013/12/17  
  43. // 该函数利用FindWindowByWindowName(),只能通过窗口的名字来判断  
  44. // 不适合现在的情况,采用另一种方式判断后台进程是否正在进行  
  45. function ifRunningDesktop():Boolean;  
  46. var  
  47.    isRunning:Integer;  
  48.    cycleCount:Integer;  
  49. begin  
  50.     Result:=true;  
  51.     cycleCount:=0;  
  52.     isRunning:=FindWindowByWindowName('有道词典');  
  53.     while isRunning <> 0 do  
  54.     begin  
  55.         if cycleCount > 0 then  
  56.         begin  
  57.            Msgbox('请确保客户端已关闭!', mbInformation, MB_OK);  
  58.         end;  
  59.         if MsgBox('升级程序检测到客户端正在运行。' #13#13 '您必须先关闭客户端然后单击“是”继续安装,或按“否”退出安装!',mbConfirmation, MB_YESNO) = idNO then  
  60.         begin  
  61.            Result:=false;  
  62.            isRunning:=0;  
  63.         end else begin  
  64.            Result:=true;  
  65.            isRunning:=FindWindowByWindowName('VSODesktop');  
  66.         end;  
  67.         cycleCount:=cycleCount +1 ;  
  68.     end;  
  69. end;  
  70.   
  71. // 判断某个进程是否正在运行,利用安装包里面自带的ISTask.dll插件  
  72. function RunTask(FileName: string; bFullpath: Boolean): Boolean;  
  73. external 'RunTask@files:ISTask.dll stdcall delayload';  
  74.   
  75. function ifBrowserIsRunning():Boolean;  
  76. var  
  77.    iehWnd, ffhWnd, chrhWnd, b360hWnd, safhWnd, i: Integer;  
  78. begin  
  79.     iehWnd := FindWindowByClassName('IEFrame');  
  80.     ffhWnd := FindWindowByClassName('MozillaWindowClass');  
  81.     b360hWnd := FindWindowByClassName('360se6_Frame');  
  82.     chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');  
  83.     safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');  
  84.   
  85.     if (iehWnd>0) or (ffhWnd>0) or (b360hWnd>0) or (chrhWnd>0) or (safhWnd>0) then  
  86.     begin  
  87.        Result:=true;  
  88.     end else begin  
  89.        Result:=false;  
  90.     end;  
  91. end;  
  92.   
  93.   
  94. // 检测vsodesktop进程是否正在运行,即正在打开这vso应用软件  
  95. // added by houqd 2013/12/18  
  96. function ifVsoIsRunning():Boolean;  
  97. var  
  98.     pstate:Boolean;  
  99. begin  
  100.     Result:= RunTask('VSODesktop.exe', false);  
  101. end;  
  102.   
  103.   
  104. // 升级包通过修改注册表,更改控制面板中已安装软件的版本信息  
  105. // added by houqd 2013/12/18  
  106. function updateVersion():Boolean;  
  107. var  
  108.    ResultStr:String;  
  109.    nDisplayName:String;  
  110.    nVersion:String;  
  111. begin  
  112.   
  113.    Result:=true;  
  114.    nDisplayName:='{#PreDisplayName}'+'{#MyAppVersion}';  
  115.    nVersion:='{#MyAppVersion}';  
  116.   
  117.    // 修改版本信息  
  118.    if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayName',ResultStr) then  
  119.    begin  
  120.       if nDisplayName <> ResultStr then  
  121.       begin  
  122.           RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayName', nDisplayName);  
  123.       end;  
  124.    end;  
  125.      
  126.    if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayVersion',ResultStr) then  
  127.    begin  
  128.       if nVersion <> ResultStr then  
  129.       begin  
  130.           RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayVersion', nVersion)  
  131.       end;  
  132.    end;  
  133. end;  
  134.   
  135. // 升级包通过修改注册表,更改控制面板中已安装软件的显示图标  
  136. // added by houqd 2013/12/18  
  137. function updateDisplayIcon():Boolean;  
  138. var  
  139.   ResultStr:String;  
  140.   nDisplayIcon:String;  
  141.   installLocation:String;  
  142. begin  
  143.   Result:=true;  
  144.    
  145.   RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','InstallLocation',installLocation);  
  146.   nDisplayIcon:=installLocation+'VSODesktop.exe';  
  147.    
  148.   // 如果DisplayIcon该键值存在则说明它原本就有图标,现在要对比更新  
  149.   if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayIcon',ResultStr) then  
  150.   begin  
  151.      if nDisplayIcon <> ResultStr then  
  152.      begin  
  153.         RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayIcon', nDisplayIcon)  
  154.      end;  
  155.   end else begin  
  156.         RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayIcon', nDisplayIcon)  
  157.   end;  
  158. end;  
  159.   
  160. rdpFileExsits:=FileSearch('rdp.tmp',ExpandConstant('{app}'));    // 如果文件存在则返回绝对路径,如果不存在则返回空  
  161.       if rdpFileExsits = '' then  
  162.       begin  
  163.          Exec(ExpandConstant('{cmd}'), '/c wmic qfe get hotfixid | find "KB2592687" > '+ExpandConstant('{tmp}\rdp.tmp'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);  
  164.          FileCopy(ExpandConstant('{tmp}\rdp.tmp'),ExpandConstant('{app}\rdp.tmp'),false);  
  165.       end;  
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-4-27 12:05 , Processed in 0.140307 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表