InstallShield 卸载旧版本并安装新版本

本文介绍了如何使用InstallShield实现程序安装时自动卸载旧版本并安装新版本的过程。主要步骤包括在初始化阶段调用卸载函数,判断是否存在旧版本并询问用户,删除文件夹、快捷方式及注册表项,最后启动新版本安装程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、主要思想是:

1、在初始化OnSetTARGETDIR函数中,if( MAINTENANCE ) then的条件中调用卸载函数(UninstallOldVersion);

2、在卸载函数中需要判断是否装有旧版本,给出提示框,访问用户是否要卸载;

3、卸载函数主要是通过GUID找到对应的程序安装路径、InstallShield卸载文件夹路径、将这些文件夹删除,然后删除快捷方式,再删除对应的注册表;

4、删除完成后,通过进程ID找到对应安装EXE的全路径,运行这个EXE程序,然后退出当前EXE程序。

注:GUID一定要是固定的。

 

二、相关卸载函数

1、函数声明:

prototype NUMBER KillProcess(string);
prototype BOOL GetProcessRunning(string, int, BYREF string);
prototype  UninstallOldVersion();
prototype  DeleteUninstallShortcut(); 
prototype Shell32.SHChangeNotify(LONG, LONG, POINTER, POINTER);
prototype Kernel32.GetCurrentProcessId();

 

2、函数定义:

function DeleteUninstallShortcut()  
 string strCmdLine, strProductFolder, strIconPath, strItemName,svPath;
begin                                   
  strProductFolder = "产品名称";
     DeleteFolderIcon(FOLDER_PROGRAMS ^ strProductFolder,"产品名称");       
     DeleteFolderIcon(FOLDER_PROGRAMS ^ strProductFolder,"卸载产品名称"); 
     DeleteFolderIcon(FOLDER_DESKTOP,"产品名称"); 
     DeleteProgramFolder(FOLDER_PROGRAMS ^ strProductFolder);
end;

                 
function UninstallOldVersion() 
 string szPath,UninstallString;
 string szNumName,szNumValue;
 number nType,nSize,nIgnore,nResult; 
 string szmsg1;
  int nIndex;
  string oldGuid;
  string szTARGETDIR;
  
  STRING noUse;
  NUMBER szProcessId;
  STRING szModuleName; // Module filename
begin

oldGuid = "{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}";    
szPath=WINDIR+"Installer\\"+oldGuid;
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
UninstallString="\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+oldGuid;
nType=REGDB_STRING;
szNumName="UninstallString";
nResult = VerProductCompareVersions();
RegDBGetKeyValueEx(UninstallString,szNumName,nType,szNumValue,nSize); //获取卸载脚本   
if(RegDBKeyExist(UninstallString)>0 && nResult != VERSION_COMPARE_RESULT_SAME) then   
 if(AskYesNo("检测到旧版本存在,是否卸载?",NO)=YES) then
   if ProcessRunning("Onekeyrom") then
        MessageBox("程序正在运行中,请先关闭程序.", INFORMATION);       
        abort;
      endif; 
   
   SdShowMsg("正在卸载旧版本, 请稍等...",TRUE); 
   Delay(1);
  
   LaunchAppAndWait(szNumValue, " /S",  LAAW_OPTION_WAIT);
   szNumName = "InstallLocation";
   nSize = 0;
   RegDBGetKeyValueEx(UninstallString,szNumName,nType,szmsg1,nSize); //获取卸载脚本
   KillProcess("aaa");
    if (nSize > 0) then;
        DeleteDir(szmsg1, ALLCONTENTS);
      endif;
        
   nIndex = StrFind(szNumValue,"}\\");
   if nIndex >=0 then
    StrSub(szmsg1,szNumValue,0,nIndex + 2);
    LongPathToQuote(szmsg1, FALSE );
    DeleteDir (szmsg1, ALLCONTENTS);
   endif;
   DeleteUninstallShortcut();
   RegDBDeleteKey(UninstallString);
   RegDBDeleteKey("\\SOFTWARE\\公司名称");    //  主要是看InstallShield设置注册表的路径  
   FeatureRemoveAllInMediaAndLog();   
         
   //刷新注册表      
   LaunchAppAndWait ( "","cmd /c gpupdate /force /wait:0 ",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);  
   SdShowMsg("", FALSE);  
   SdShowMsg("卸载旧版本成功",TRUE);    
   Delay(2);      
   SdShowMsg("", FALSE);  
   LaunchAppAndWait(WINSYSDIR^"cmd.exe", "/c rd /s/q \""+szPath+"\"", LAAW_OPTION_WAIT | LAAW_OPTION_HIDDEN); 
         
      szProcessId = GetCurrentProcessId();
      if szProcessId != 0 then
       if GetProcessRunning(noUse, szProcessId, szModuleName) = TRUE then
         LaunchApp(szModuleName, "");
         abort;
      else
         MessageBox("安装新版本遇到问题,请再次运行安装文件完成安装。", MB_OK);
     endif;
      else
         MessageBox("安装新版本遇到问题,请再次运行安装文件完成安装。", MB_OK);
      endif;        
   else
      abort;

  endif;

  endif;
end;            


function BOOL GetProcessRunning(szAppName, nvFindProcessId, szFindModName)
 BOOL bvRunning; // Process is running
 NUMBER nvProcessIDs(512); // Array of process IDs
 NUMBER nvBytesReturned; // Number of bytes returned in process ID array
 NUMBER nvProcesses; // Number of processes running
 NUMBER nvIndex; // Loop index
 NUMBER nvProcessHandle; // Handle to a process
 NUMBER nvModuleHandle; // Handle to a process module
 NUMBER nvBytesRequired; // Number of bytes required to store values
 POINTER pvProcessIDs; // Pointer to process ID array
 STRING svModuleName; // Module name
 STRING svFileName; // Module filename
 begin
 // The psapi.dll reads the Windows NT performance database. The DLL
 // is part of the Win32 SDK.

 if UseDLL(WINSYSDIR ^ PSAPI_FILE) < 0 then
 // Could not load psapi.dll.

 MessageBox("ERROR: Could not load [" + WINSYSDIR ^ PSAPI_FILE +
 "].", SEVERE);

 return FALSE;
 endif;

 // Get the PIDs of all currently running processes.

 pvProcessIDs = ArrayToPointer(nvProcessIDs);

 EnumProcesses(pvProcessIDs, 512, nvBytesReturned);

 // Determine the number of process IDs retrieved. Each process ID
 // is PROCESSID_LENGTH bytes.

 nvProcesses = nvBytesReturned / PROCESSID_LENGTH;

 // Get the executable associated with each process, and check if
 // its filename matches the one passed to the function.

 for nvIndex = 1 to nvProcesses
 // Get a handle to the process.

 nvProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION |
 PROCESS_VM_READ, 0, nvProcessIDs(nvIndex));

 if nvProcessHandle != 0 then
 // Get a handle to the first module in the process, which
 // should be the executable.

 if EnumProcessModules(nvProcessHandle, nvModuleHandle,
 PROCESSID_LENGTH, nvBytesRequired) != 0 then
 // Get the path of the module.

 if GetModuleFileNameExA(nvProcessHandle, nvModuleHandle,
 svModuleName, SizeOf(svModuleName)) != 0 then
 // Extract the filename (without an extension) from
 // the path.

 //Add by QianShi at 2010.6.23
 //Get module name by process id.
 if nvProcessIDs(nvIndex) = nvFindProcessId then
 szFindModName = svModuleName;
 bvRunning = TRUE;
 goto ProcessRunningEnd;
 endif;

 ParsePath(svFileName, svModuleName, FILENAME_ONLY);

 if StrCompare(svFileName, szAppName) = 0 then
 // The process module matches the application
 // name passed to the function.

 bvRunning = TRUE;

 goto ProcessRunningEnd;
 endif;
 endif;
 endif;
 endif;
 endfor;

 ProcessRunningEnd:

 if UnUseDLL(PSAPI_FILE) < 0 then
 MessageBox("ERROR: Could not unload [" + WINSYSDIR ^ PSAPI_FILE +
 "].", SEVERE);

 return FALSE;
 endif;


 return bvRunning;
 end;
 
 
 function NUMBER KillProcess(szAppName)
    NUMBER  nvReturn;           // Number of processes terminated
    NUMBER  nvProcessIDs(512);  // Array of process IDs
    NUMBER  nvBytesReturned;    // Number of bytes returned in process ID array
    NUMBER  nvProcesses;        // Number of processes running
    NUMBER  nvIndex;            // Loop index
    NUMBER  nvProcessHandle;    // Handle to a process
    NUMBER  nvModuleHandle;     // Handle to a process module
    NUMBER  nvBytesRequired;    // Number of bytes required to store values
    POINTER pvProcessIDs;       // Pointer to process ID array
    STRING  svModuleName;       // Module name
    STRING  svFileName;         // Module filename
    STRING  szCmdLine, szTemp;
begin
    // The psapi.dll reads the Windows NT performance database. The DLL
    // is part of the Win32 SDK.
   
    if UseDLL(WINSYSDIR ^ PSAPI_FILE) < 0 then
        // Could not load psapi.dll.
       
        MessageBox("ERROR: Could not load [" + WINSYSDIR ^ PSAPI_FILE +
                "].", SEVERE);
       
        return -1;
    endif;
   
    // Get the PIDs of all currently running processes.
   
    pvProcessIDs = ArrayToPointer(nvProcessIDs);

    EnumProcesses(pvProcessIDs, 512, nvBytesReturned);

    // Determine the number of process IDs retrieved. Each process ID
    // is PROCESSID_LENGTH bytes.
   
    nvProcesses = nvBytesReturned / PROCESSID_LENGTH;
   
    // Get the executable associated with each process, and check if
    // its filename matches the one passed to the function.
   
    for nvIndex = 1 to nvProcesses
        // Get a handle to the process. The OpenProcess function
        // must have full (all) access to be able to terminate
        // processes.
       
        nvProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION |
                PROCESS_ALL_ACCESS, 0, nvProcessIDs(nvIndex));
               
        if nvProcessHandle != 0 then
            // Get a handle to the first module in the process, which
            // should be the executable.
           
            if EnumProcessModules(nvProcessHandle, nvModuleHandle,       
                    PROCESSID_LENGTH, nvBytesRequired) != 0 then
                // Get the path of the module.
               
                if GetModuleFileNameExA(nvProcessHandle, nvModuleHandle,
                        svModuleName, SizeOf(svModuleName)) != 0 then
                    // Extract the filename (without an extension) from
                    // the path.
                   
                    ParsePath(svFileName, svModuleName, FILENAME_ONLY);

                    if StrCompare(svFileName, szAppName) = 0 then
                        // The process module matches the application
                        // name passed to the function.
                       
                        if TerminateProcess(nvProcessHandle, 0) > 0 then
                            nvReturn++;
                        endif;
                    endif;
                endif;
            endif;
        endif;
    endfor;
           
    if UnUseDLL(PSAPI_FILE) < 0 then
        MessageBox("ERROR: Could not unload [" + WINSYSDIR ^ PSAPI_FILE +
                "].", SEVERE);
               
        return -1;
    endif;
       
    return nvReturn;
end;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值