InstallShield之残留文件删除与快捷方式自定

InstallShield用了好几个月了,其便捷的操作,完善的功能很是让人爱不释手,可是用了几个月也发现了些小问题:偶用的 IS12,有时会出现卸载软件后残留开始菜单与桌面图标问题(只是极其个别电脑,但这种现象存在),还有的就是在更改几次安装程序后原安装程序的残留信息,某些情况下会对新生成的安装文件运行产生干扰,因此需要在新安装程序运行时强制删除残留信息(不是卸载,已经卸载过)。现将解决这些小问题的思路整理如下:
1)开始菜单及桌面图标残留
可以用 LaunchAppAndWait来运行 cmd进行文件夹及文件的删除,也可以用 IS自带的 DeleteProgramFolderDeleteFolderIcon进行显示删除,这里记住几个常量以对特殊文件夹路径进行读取
WINSYSDIRSystemFolder读取 %windir%\system32文件夹 (c:\windows\system32)
WINDIRWindowsFolder读取 %windir%文件夹 (c:\windows)
FOLDER_DESKTOPDesktopFolder读取桌面文件夹
INSTALLDIRTARGETDIR读取文件安装路径
FOLDER_PROGRAMSProgramMenuFolder读取程序菜单文件夹
@PRODUCT_NAME获取安装程序名称
@PRODUCT_GUID获取安装程序的 ID
一般来说这几个常量就能够满足我们的操作了,如果还要了解更多,可以在 <ISProductFolder>\Script\isrt\Include\SysVars.h<ISProductFolder> Script\iswi\Include\SysVarsConv.h,记不住? IS的安装文件里面搜 .h文件,找一个你知道的关键字,总不会记一个关键字也难吧?
因此 DeleteFile ( FOLDER_DESKTOP^@PRODUCT_NAME+".lnk" );DeleteProgramFolder ( FOLDER_PROGRAMS^@PRODUCT_NAME );这两句话加在 OnMaintUIAfter()里就可满足清除残留图标的要求了。
       2)自定义快捷方式
       IS自带有向导来让你指定快捷方式及其图标,但是这样一来必须把你指定的每一个图标作为一个资源强加载到安装程序中,在 %windir%\Installer\[ProductCode]文件夹内生成 NEXEICO文件,二来也不能根据系统本身的情况作出适当调整,比如你有几个 WORD文档,几个 TXT文档和几个 PDF文档,那么你用指定快捷方式向导的话你就得在上述文件夹内生成 N个图标程序,而不管是否它们中几个文件类型是相同的,更别说某些用户系统类对该类文档的解析程序可能不同,它们的文件图标也可能根本跟你指定的不一样。对于这个问题,当然最灵活的方式就是用脚本添加快捷方式了。
完全从脚本添加快捷方式 :
       CreateProgramFolder ( @PRODUCT_NAME );
然后 AddFolderIcon (szProgramFolder, szItemName, szCommandLine, szWorkingDir, 
   szIconPath, nIcon, szShortCutKey, nFlag); 
就可以添加快捷方式到相应的位置了,使用时请注意用 LongPathToQuote处理有空格的路径。这里有一点麻烦的就是查找已知文件的图标关联,起初我想的是找到相应的解析程序,然后从其应用程序里面提取图标。在 IS里面调用一个批处理来获得该 EXE路径,以查找 PDF相应关联程序为例 :
批处理脚本 :
@echo off
setlocal enabledelayedexpansion
echo "%1"
for /f "tokens=2 delims==" %%i in ('assoc .pdf') do (
       for /f "tokens=2 delims==" %%j in ('ftype %%i') do (
              set "strPath=%%j"
              set strPath=!strPath: "%%1"=!
              echo !strPath!
              echo !strPath!>"%1"
       )
)
 
IS相应脚本 :
       szBATFile = SUPPORTDIR^"getPath.bat";
       szTXTFile = FOLDER_TEMP^"PDFRdr.txt";
       LongPathToQuote( szBATFile, TRUE );
       LongPathToQuote( szTXTFile, TRUE );
       LaunchAppAndWait (  szBATFile , szTXTFile , LAAW_OPTION_HIDDEN|LAAW_OPTION_WAIT );
       if ( FindFile ( FOLDER_TEMP , "PDFRdr.txt" , svResult ) = 0 ) then
              OpenFileMode ( FILE_MODE_NORMAL );                  
              OpenFile ( nvFileHandle , FOLDER_TEMP , svResult ); 
              GetLine ( nvFileHandle , svExePath );
              CloseFile ( nvFileHandle );
       endif;              
       if ( StrCompare ( svExePath , "" ) = 0 ) then
              MessageBox ( "当前未查到有任何 PDF阅读软件 ", SEVERE );
       else
              MessageBox ( svExePath, INFORMATION );
       endif;   
将获得的应用程序图径代入 AddFolderIcon,作为图标路径。结果发现诸如 PDF文档的图标未必就在 EXE里面, FoxitReader的图标在 EXE文件里,可 AdobeExe里面只有一个图标, PDF文档图标根本没有,没办法,还只有从注册表一途来查找了 :
/*****************************
 *取得系统 PDF文件关联类型图标
 *****************************/ 
function STRING GetPDFIcon()
    NUMBER nStart, nvType, nvSize;     
    STRING szStart;
    STRING svResult, svValue, svKey;
    STRING svIconPath;
    NUMBER nvIconIndex;
begin
       RegDBSetDefaultRoot ( HKEY_CLASSES_ROOT );
       svKey = ".pdf";
       if ( RegDBKeyExist ( svKey ) = 1 ) then
              RegDBGetKeyValueEx ( svKey , "" , nvType , svValue , nvSize );
              svKey = svValue;
              if ( RegDBKeyExist ( svKey ) = 1 ) then
                  //子键存在 ,查找 DefaultIcon,如果有 ,读取 ,如果没有 ,读取它的 Version,再读注册表
                  if ( RegDBKeyExist ( svKey + "\\DefaultIcon" ) = 1 ) then
                            RegDBGetKeyValueEx ( svKey + "\\DefaultIcon" , "" , nvType , svValue, nvSize );
                            return svValue;
                     else
                            //未发现关联类型的 DefaultIcon,则查找其 CurVer,查其版本号
                            if ( RegDBKeyExist ( svKey + "\\CurVer" ) = 1 ) then
                                   RegDBGetKeyValueEx( svKey + "\\CurVer", "" , nvType, svValue, nvSize );
                                   svKey = svValue;
                                   if  ( RegDBKeyExist ( svKey ) = 1 ) then 
                                          if ( RegDBKeyExist ( svKey + "\\DefaultIcon" ) = 1 ) then
                                                 RegDBGetKeyValueEx( svKey + "\\DefaultIcon" , "" , nvType, svValue, nvSize );
                                                 return svValue;
                                          else
                                                 return "";
                                          endif; //endif check ICON value
                                   else        
                                          return "";
                                   endif; //endif check CurVer value
                            else
                                   return "";
                            endif; //endif check CurVer Exist
                  endif;  //endif check DefaultIcon Exist
              endif; //end if check .pdf filetype exist
       endif;  //endif check .pdf key exist
end;
 
然后在 OnFirstUIAfter()里面调用该函数取得文件关联路径 :
       //查找 PDF文件关联 ,并取得关联类型图标
       svDefaultIcon = GetPDFIcon(); 
       if ( StrCompare ( svDefaultIcon , "" ) != 0 ) then 
              nStart = StrFind ( svDefaultIcon , "," );
              if ( nStart > 0 ) then
                     StrSub ( svPDFIconPath , svDefaultIcon , 0 , nStart );
                     StrSub ( svPDFIconIndex , svDefaultIcon , nStart+1 , 10 );
                     //MessageBox ( "图标路径为 :" + svPDFIconPath + "   索引号为 :" + svPDFIconIndex , INFORMATION );
              endif; 
              StrToNum ( nvPDFIconIndex , svPDFIconIndex );
       else                                
              svPDFIconPath = WINSYSDIR^"shell32.dll";
              nvPDFIconIndex = 0;
       endif;
       svResult = "";                    
       nvResult = FindAllFiles ( INSTALLDIR , "*.pdf" , svResult , RESET );
       while ( !nvResult )      
              LongPathToQuote ( svResult , TRUE );
              ParsePath ( svPDFFileName , svResult , FILENAME_ONLY );                    
              AddFolderIcon ( FOLDER_PROGRAMS^@PRODUCT_NAME , 
                     svPDFFileName , 
                     svResult , 
                     "" , 
                     svPDFIconPath , nvPDFIconIndex , 
                     "" , 
                     REPLACE );
              nvResult = FindAllFiles ( INSTALLDIR , "*.pdf" ,svResult , CONTINUE );
       endwhile;
 
最后,添加卸载的快捷方式,就基本上大功告成了。
       //添加卸载快捷方式
       nStart = StrFind ( UNINSTALL_STRING , ".exe" );
       if ( nStart >= 0 ) then
              StrSub ( szUninstPath , UNINSTALL_STRING , 0 , nStart+4 );
              LongPathToQuote ( szUninstPath , FALSE ); 
              StrSub ( szUninstParam, UNINSTALL_STRING , nStart+4 , 200 );
              LongPathToQuote ( szUninstParam, FALSE );
       endif; 
       AddFolderIcon ( FOLDER_PROGRAMS^@PRODUCT_NAME , 
              "卸载 " + @PRODUCT_NAME , 
              "\"" + szUninstPath + "\"" + szUninstParam , 
              "" , 
              INSTALLDIR^"Uninstall.ico" , 
              0 , 
              "" , 
              REPLACE );
 
       3)残留安装信息的删除
       目前就发现一个 IS的安装信息在 [ProgramFilesFolder]\InstallShield Installation Information\[ProcuctCode][WindowsFolder]\Installer\[ProductCode]里面有相关的文件,于是安装之前先检测此两处文件夹是否存在,清除之,避免残留信息的干扰。
/*****************************
 *旧版残留信息清除
 *****************************/  
function NUMBER DealOldEdition()   
       STRING szPath;
begin          
       //删除 InstallSheild Installation Information信息
       szPath = PROGRAMFILES^"InstallShield Installation Information"^PRODUCT_GUID;
       if ( ExistsDir ( szPath ) = 0 ) then
              if (LaunchAppAndWait( WINSYSDIR^"cmd.exe", "/c rd /s/q \""+szPath+"\"", LAAW_OPTION_WAIT | LAAW_OPTION_HIDDEN) = 0) then
                     //MessageBox( "删除文件夹 "+szPath+"成功 ", INFORMATION );
              else
                     return 0;
                     //MessageBox( "删除文件夹 "+szPath+"失败 ", INFORMATION );
              endif;
       endif;
       //删除 Installer信息
       szPath = WINDIR^"Installer"^PRODUCT_GUID;
       if ( ExistsDir ( szPath ) = 0 ) then
              if (LaunchAppAndWait( WINSYSDIR^"cmd.exe", "/c rd /s/q \""+szPath+"\"", LAAW_OPTION_WAIT | LAAW_OPTION_HIDDEN) = 0) then
                     //MessageBox( "删除文件夹 "+szPath+"成功 ", INFORMATION );
              else
                     return 0;
                     //MessageBox( "删除文件夹 "+szPath+"失败 ", INFORMATION );
              endif;
       endif;
       return 1;
end;
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在InstallShield中设置开机自启动程序,可以按照以下步骤操作: 1. 打开您的InstallShield项目,并导航到“组织视图”选项卡。 2. 从左侧的“行动”窗格中,选择“文件文件夹”选项。 3. 在右侧的“文件文件夹”窗格中,选择您希望在启动时自动运行的可执行文件。 4. 在选中该文件之后,转到“属性”窗格并将其“Permanent”属性设置为“True”,以确保文件安装过程中一直存在。 5. 接下来,从“行动”窗格中选择“注册表”选项。 6. 在右侧的“注册表”窗格中,选择您希望将启动项添加到的注册表项。例如,您可以选择“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run”。 7. 在选中注册表项后,单击“新建值”按钮并输入要创建的值的名称。 8. 将新创建的值的数据设置为您要自动启动的可执行文件的路径。 9. 保存您的更改并重新构建安装程序,然后进行安装即可。 这样,您的安装程序将在系统启动时自动启动指定的可执行文件。 ### 回答2: 在InstallShield中设置开机自启动有以下步骤: 1. 打开InstallShield并打开您的项目。在“项目视图”下选择“维护”或“转换设置”。 2. 在“转换设置”对话框中,选择“文件位置”选项卡。然后选择“工作站”(如果项目类型为Basic MSI)或“目标计算机”(如果项目类型为InstallScript)下的“系统配置”。 3. 在“系统配置”窗口中,选择“自动启动”选项。这将允许您设置开机自启动功能的相关设置。 4. 在“自动启动”面板中,选择“启用自动启动”复选框。这将启用安装程序在操作系统启动时自动运行的功能。 5. 您可以选择指定自动启动程序的名称和说明。这些信息将显示在Windows任务管理器中。 6. 在“启动文件”字段中,指定安装程序启动时要打开的文件的路径。 7. 您还可以选择是否在登录时运行自动启动程序,以及选择使用当前用户或所有用户安装。 8. 关闭“系统配置”窗口并保存更改。 9. 重新构建您的安装程序,并确保生成的安装程序已正确设置开机自启动功能。 通过按照上述步骤设置,您的InstallShield项目将具有开机自启动功能。请记住,在部署到实际计算机之前,最好在测试环境中进行验证和调试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值