更新时间:2024-04-12 GMT+08:00
分享

应用程序改造

对应用程序进行静默安装和静默卸载改造。改造后,工业软件可通过ISCDesk实现一键下载、安装和卸载。

针对工业软件在ISCDesk中安装/卸载异常的场景,提出以下几点建议:

  • 建议工业软件的安装脚本支持覆盖安装,即在出现安装中断之后,可以继续安装或者全新安装。
  • 建议工业软件的卸载脚本支持继续卸载,即在出现任何卸载异常之后,可以继续卸载。
  • 建议将安装/卸载异常原因补充到进度文件。
  • 不建议采取先清空进度文件再写进度文件的机制,避免ISCDesk读取不到进度。

静默安装改造

  1. 本地新建“InstallApp.vbs”文件,并复制以下代码至新建文件中,用于调用安装程序的静默安装命令。

    ' 获取命令行参数 
    Set objArgs = WScript.Arguments 
     
    ' 获取文件夹路径 
    folderPath = objArgs(0) 
    ' 移除路径末尾的斜杠 
    If Right(folderPath, 1) = "\" Then 
       folderPath = Left(folderPath, Len(folderPath) - 1) 
    End If 
    ' 构建命令 
    Set fso = CreateObject("Scripting.FileSystemObject") 
    ' 获取当前脚本所在目录的路径 
    scriptFolder = fso.GetParentFolderName(WScript.ScriptFullName) 
     
    ProgressPath = folderPath & "\installProgress.log"
    ' 若progress文件已存在,则删除
    If fso.fileExists(ProgressPath) Then
    	fso.DeleteFile(ProgressPath)
    End If
    
    ' 构建cmd命令  
     
    ' ①假设此vbs文件在D:\test中,安装程序文件名称为install.exe,目标安装目录(传进来的folderPath,无需改动)为D:\installpath。 
    ' 假如您的安装程序需要接受到的静默安装命令格式为: 
    ' "D:\test\install.exe" D:\installpath 
    ' installPath,parameters改为如下所示: 
    ' installPath = fso.BuildPath(scriptFolder, "install.exe") 
    ' parameters = folderPath 
     
    ' ②假设此vbs文件在D:\test中,安装程序文件名称为setup.exe,目标安装目录(传进来的folderPath,无需改动)为D:\installpath。 
    ' 假如您的安装程序需要接受到的静默安装命令格式为: 
    ' "D:\test\setup.exe" "D:\installpath" 
    ' 则installPath,parameters改为如下所示: 
    ' installPath = fso.BuildPath(scriptFolder, "setup.exe") 
    ' parameters ="""" & folderPath & """"  
     
    ' ③假设此vbs文件在D:\test中,安装程序文件名称为安装.exe,目标安装目录(传进来的folderPath,无需改动)为D:\installpath。 
    ' 假如您的安装程序需要接受到的静默安装命令格式为: 
    ' "D:\test\安装.exe" /quiet InstallPath="D:\installpath" /isinstall  
    ' installPath,parameters改为如下所示: 
    ' installPath = fso.BuildPath(scriptFolder, "安装.exe") 
    ' parameters =" /quiet"  & " InstallPath=" & """" & folderPath & """" & " /isinstall"  
     
    ' ◆◆◆◆◆具体什么参数应根据您的安装程序而决定,请根据您所接受的指令格式对下面installPath,parameters进行修改。◆◆◆◆◆ 
     
    installPath = fso.BuildPath(scriptFolder, "setup.exe") 
    parameters = folderPath 
     
    ' 创建 Shell 对象执行
    Set shell = CreateObject("wscript.shell")
    command = installPath & parameters & " 1"
    shell.run command
     
    ' 赋值uninstall.vbs中的folderPath
    Dim filePath
    filePath = scriptFolder & "\uninstall.vbs"
     
    ' 读取文件内容
    Dim objStream
    Set objStream = CreateObject("ADODB.Stream")
    objStream.Charset = "GB2312"
    objStream.Open
    objStream.LoadFromFile filePath
     
    Dim content
    content = objStream.ReadText
     
    objStream.Close
     
    ' 替换第一行代码
    Dim newCode
    newCode = "folderPath=" & """" & folderPath & """"
    content = Replace(content, Split(content, vbCrLf)(0), newCode)
     
    ' 使用GB2312编码写入文件
    Set objStream = CreateObject("ADODB.Stream")
    objStream.Charset = "GB2312"
    objStream.Open
    objStream.WriteText content
    objStream.SaveToFile filePath, 2 
    objStream.Close
     
    ' 将uninstall.vbs卸载脚本拷贝至卸载程序的同级目录下
    ' 假设卸载程序位置在安装目录下
    ' 卸载路径 = folderPath 
    ' 假设卸载程序位置在安装目录下的program文件夹内
    ' 卸载路径 = folderPath & "\program"
    fso.CopyFile scriptFolder & "\uninstall.vbs", folderPath & "\uninstall.vbs"
    

  2. 应用安装时需要生成“install.json”文件,记录安装进度。文件格式如下:

    {"status":1,"progress":100,"errorMsg":""}

    “status”表示安装是否完成,“1”代表安装完成,“0”代表安装未完成;“progress”代表应用安装进度从“0~100”“errorMsg”代表安装过程中的错误信息,如果没有出错则填空值即可。

    本文提供一种“install.json”文件生成方法作为参考:

    本方法中使用的软件安装程序通过innosetup安装包制作软件制作,因此安装进度获取依赖Inno Setup Compiler。

    1. 在安装打包程序“.iss”文件的[Code]代码段增加如下代码,在安装时可实时记录安装进度。
      var
      lastPercent: Integer;
       
      procedure InitializeWizard;
      begin
        lastPercent := -1;
      end;
       
      procedure WriteLog(logContent: String; fileName: String);
      var
        bExist:Boolean;
        myFileName:String;
        svArray:TArrayOfString;
        MyFile: TFileStream;
      begin            
          myFileName := ExpandConstant('{app}') + '\' + fileName;
          SetLength(svArray, 1);
          svArray[0] := logContent;
          SaveStringsToFile(myFileName, svArray, true);
      end;
       
      procedure CurInstallProgressChanged(CurProgress, MaxProgress: Integer);
      var 
      percent: Integer;
      begin
        percent :=  CurProgress * 100 / MaxProgress;
        if lastPercent >= percent then
        else
        begin
          WriteLog(Format('Installing...:%d', [percent]), 'installProgress.log');
          lastPercent := percent;
        end  
      end;
    2. “InstallApp.vbs”文件增加如下代码,生成“install.json”文件。
      Set objFSO = CreateObject("Scripting.FileSystemObject")
       
      ' 目标文件夹路径
      strFolderPath = folderPath
       
      ' 创建JSON文件函数
      Sub CreateJsonFile(progress)
          Dim objJson, jsonObj, outFile
          
          Set objJson = CreateObject("Scripting.Dictionary")
          Set jsonObj = CreateObject("Scripting.Dictionary")
          
          ' 设置JSON对象的属性
       
          If CInt(progress) >= 100 Then
              jsonObj.Add "status", 1
          Else
              jsonObj.Add "status", 0
          End If
          jsonObj.Add "progress", CInt(progress) '将进度值转换为整数类型
          jsonObj.Add "errorMsg", """"""
          
          ' 将JSON对象添加到顶级对象
          objJson.Add "", jsonObj
          
          ' 打开输出文件
          Set outFile = objFSO.CreateTextFile(strFolderPath & "\install.json", True)
          
          ' 创建JSON字符串
          Dim jsonString
          jsonString = "{"
          For Each key In jsonObj.Keys
              jsonString = jsonString & """" & key & """:" & jsonObj(key) & ","
          Next
          jsonString = Left(jsonString, Len(jsonString) - 1) ' 移除最后一个逗号
          jsonString = jsonString & "}"
          
          ' 将JSON数据写入文件
          outFile.Write jsonString
          
          ' 关闭文件
          outFile.Close
      End Sub
          
      ' 获取当前进度函数
      Function GetProgress()
          Dim Progress 
          Progress = 0
          
          If fso.fileExists(ProgressPath) Then
              Dim content
              Dim pos
              Set file = fso.OpenTextFile(ProgressPath, 1)
       
              Do Until file.AtEndOfStream
                  content = file.ReadLine
                  If Len(content) = 0 Then
                      Exit Do
                  End If
                  
                  pos = InStr(content, "Installing...:")
                  If pos > 0 Then
                      Progress = CInt(Mid(content, pos + 14))
                  End If
              Loop
              
              file.Close
          End If
          
          GetProgress = Progress
      End Function
       
      Function FindSetupProcess()
          Dim bExist,WMI,Objs,Process,processPath
          bExist = 0
          Set WMI=GetObject("WinMgmts:")
          Set Objs=WMI.InstancesOf("Win32_Process")
          Process=""
          For Each Obj In Objs
              Process = Obj.Description
              processPath = Obj.ExecutablePath
              
              If Process = "NotePad--_setup.exe" And processPath = installPath Then
                  bExist = 1
              End If
          Next
          
          FindSetupProcess = bExist
      End Function
       
      ' 主循环
      Do While True
          Dim bExist
          bExist = FindSetupProcess()
          
          ' 获取安装进度,安装程序退出时进度置为100
          If bExist = 1 Then
              progress = GetProgress()
          Else
              progress = 100
          End If
       
          ' 创建JSON文件
          CreateJsonFile(progress)
       
          If bExist = 1 Then
          ' ◆◆◆◆◆等待1秒,读取安装进度◆◆◆◆◆
              WScript.Sleep 1000
          Else 
              fso.DeleteFile(ProgressPath)
              Exit Do
          End If
      Loop

  3. 修改“InstallApp.vbs”参数。

    1. 鼠标右键打开编辑“InstallApp.vbs”
    2. 参考静默安装命令示例①、②、③,修改“installPath”“parameters”
      图1 修改参数

  4. “InstallApp.vbs”复制至安装程序同级目录。

    图2 复制粘贴InstallApp.vbs

静默卸载改造

  1. 本地新建“uninstall.vbs”文件,并复制以下代码至新建文件中,用于调用卸载程序的静默卸载命令。

    folderPath="D:\123" 
    ' folderPath无需关注与修改,会自动由install.vbs在安装过程中赋值 
    ' 构建命令 
    Set fso = CreateObject("Scripting.FileSystemObject") 
    ' 获取当前脚本所在目录的路径 
    scriptFolder = fso.GetParentFolderName(WScript.ScriptFullName) 
    ProgressPath = folderPath & "\uninstallProgress.log"
    ' 如果progress文件已存在,则删除
    If fso.fileExists(ProgressPath) Then
        fso.DeleteFile(ProgressPath)
    End If
    
    ' ①假如您的卸载程序所接受到的静默卸载命令格式为: 
    ' "D:\installpath\uninstall.exe" 
    ' installPath,parameters改为如下所示 
    ' installPath = fso.BuildPath(scriptFolder, "uninstallApp.exe") 
    ' parameters ="" 
    ' ②假如您的卸载程序所接受到的静默卸载命令格式为: 
    ' "D:\installpath\uninstall.exe" /uninstall /quiet  
    ' installPath,parameters改为如下所示 
    ' installPath = fso.BuildPath(scriptFolder, "uninstallApp.exe") 
    ' parameters =" /uninstall" & " /quiet" 
    ' ◆◆◆◆◆具体什么参数应根据您的卸载程序而决定,请根据您所接受的指令格式对下面uninstallPath,parameters进行修改。◆◆◆◆◆ 
     
    uninstallPath = fso.BuildPath(scriptFolder, "uninstallApp.exe") 
    parameters =" /uninstall" & " /quiet" 
     
    Set shell = CreateObject("wscript.shell")
    command = """" & uninstallPath & """" & parameters
    shell.run command

  2. 应用卸载时需要生成“uninstall.json”文件,记录卸载进度,文件格式如下:

    {"status":1,"progress":100,"errorMsg":""}

    “status”表示卸载是否完成,“1”代表卸载完成,“0”代表卸载未完成;“progress”代表应用卸载进度从0~100;“errorMsg”代表卸载过程中的错误信息,如果没有出错则填空值即可。

    本文提供一种“uninstall.json”文件生成方法作为参考:

    本方法中使用的软件安装程序通过innosetup安装包制作软件制作,因此卸载进度获取依赖Inno Setup Compiler。

    1. 在安装打包程序“.iss”文件的[Code]代码段下增加如下代码,在卸载时可实时记录卸载进度。
      procedure WriteLog(logContent: String; fileName: String);
      var
        bExist:Boolean;
        myFileName:String;
        svArray:TArrayOfString;
        MyFile: TFileStream;
      begin            
          myFileName := ExpandConstant('{app}') + '\' + fileName;
          SetLength(svArray, 1);
          svArray[0] := logContent;
          SaveStringsToFile(myFileName, svArray, true);
      end;
       
      procedure TimerProc(h: LongWord; AMsg: LongWord; IdEvent: LongWord; dwTime: LongWord);
      begin
        WriteLog(Format('Uninstalling...:%d',[UninstallProgressForm.ProgressBar.Position * 100 /UninstallProgressForm.ProgressBar.Max]), 'uninstallProgress.log');
      end;
       
      function SetTimer(hWnd: LongWord; nIDEvent, uElapse: LongWord;
        lpTimerFunc: LongWord): LongWord;
        external 'SetTimer@user32.dll stdcall';
       
      procedure InitializeUninstallProgressForm();
      begin
        SetTimer(0, 0, 100, CreateCallback(@TimerProc)); { every 100 ms }
      end;
       
      procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
      var
        Progress: Integer;
      begin
        case CurUninstallStep of
          usUninstall:
            begin
              WriteLog('Uninstalling...:0', 'uninstallProgress.log');
            end;
          usPostUninstall:
            begin
              WriteLog('Uninstalling...:100', 'uninstallProgress.log');
            end;
        end;
      end;
       
    2. “uninstallApp.vbs”中增加如下代码,生成“uninstall.json”文件。
      ' 目标文件夹路径
      strFolderPath = folderPath
       
      ' 创建JSON文件函数
      Sub CreateJsonFile(progress)
          Dim objJson, jsonObj, outFile
          
          Set objJson = CreateObject("Scripting.Dictionary")
          Set jsonObj = CreateObject("Scripting.Dictionary")
          
          ' 设置JSON对象的属性
          If progress >= 100 Then
              jsonObj.Add "status", 1
          Else
              jsonObj.Add "status", 0
          End If
          jsonObj.Add "progress", CInt(progress) '将进度值转换为整数类型
          jsonObj.Add "errorMsg", """"""
          
          ' 将JSON对象添加到顶级对象
          objJson.Add "", jsonObj
          
          ' 打开输出文件
          Set outFile = fso.CreateTextFile(strFolderPath & "\uninstall.json", True)
          
          ' 创建JSON字符串
          Dim jsonString
          jsonString = "{"
          For Each key In jsonObj.Keys
              jsonString = jsonString & """" & key & """:" & jsonObj(key) & ","
          Next
          jsonString = Left(jsonString, Len(jsonString) - 1) ' 移除最后一个逗号
          jsonString = jsonString & "}"
          
          ' 将JSON数据写入文件
          outFile.Write jsonString
          
          ' 关闭文件
          outFile.Close
      End Sub
          
      ' 获取当前进度函数
      Function GetProgress()
          Dim Progress 
          Progress = 0
          
          If fso.fileExists(ProgressPath) Then
              Dim content
              Dim pos
              Set file = fso.OpenTextFile(ProgressPath, 1)
       
              Do Until file.AtEndOfStream
                  content = file.ReadLine
                  If Len(content) = 0 Then
                      Exit Do
                  End If
                  
                  pos = InStr(content, "Uninstalling...:")
                  If pos > 0 Then
                      Progress = CInt(Mid(content, pos + 16))
                  End If
              Loop
              
              file.Close
          End If
          
          GetProgress = Progress
      End Function
       
      Function FindUnSetupProcess()
          Dim bExist,WMI,Objs,Process,processPath
          bExist = 0
          Set WMI=GetObject("WinMgmts:")
          Set Objs=WMI.InstancesOf("Win32_Process")
          Process=""
          For Each Obj In Objs
              Process = Obj.Description
              processPath = Obj.ExecutablePath
              If Process = "unins000.exe" And processPath = uninstallPath Then
                  bExist = 1
              End If
          Next
          
          FindUnSetupProcess = bExist
      End Function
       
      Dim count, lastProgress
      count = 0
      lastProgress = 0
       
      ' 主循环
      Do While True
          Dim bExist
          bExist = FindUnSetupProcess()
          
          ' 获取安装进度,安装程序退出时进度置为100
          If bExist = 1 Then
              progress = GetProgress()
          Else
              progress = 100
          End If
       
          ' 创建JSON文件
          CreateJsonFile(progress)
       
          If bExist = 1 Then
          ' ◆◆◆◆◆等待1秒,读取安装进度◆◆◆◆◆
              WScript.Sleep 1000
          Else 
              fso.DeleteFile(ProgressPath)
              'MsgBox(bExist)
              Exit Do
          End If
      Loop

  3. 修改“uninstall.vbs”参数。

    1. 鼠标右键打开编辑“uninstall.vbs”
    2. 参考静默卸载命令示例,修改“uninstallPath”“parameters”
      图3 修改参数

  4. “uninstall.vbs”复制至安装程序同级目录。

    图4 复制uninstall.vbs

打包安装程序

将安装程序、InstallApp.vbs和uninstall.vbs打包压缩为一个压缩包。

相关文档