使用 msiexec 静默卸载而不关闭 explorer.exe

使用 msiexec 静默卸载而不关闭 explorer.exe

我正在尝试使用 msi 卸载程序卸载 Inventor 2011,但静默卸载会导致 Explorer 关闭且不会重新启动。我有一个 Autodesk 的 VB 脚本,它可以工作,但即使经过适当修改,它也不是静默的。我想要一个静默卸载,不会关闭 Explorer 并等待重新启动。我该怎么做?

以下是来自 AutoDesk 的 VBScript。

    '============================================================================
    '  Uninstall_ACAD_2011.vbs
    '  This script is designed to uninstall AutoCAD 2011 and remove installed plug-ins
    '
    '  Copyright © 2010 by Autodesk, Inc. All Rights Reserved.                            
    '
    '  You are hereby granted permission to use, copy and modify this    
    '  software without charge, provided you do so exclusively for       
    '  your own use or for use by others in your organization in the     
    '  performance of their normal duties, and provided further that     
    '  the above copyright notice appears in all copies and both that    
    '  copyright notice and the limited warranty and restricted rights   
    '  notice below appear in all supporting documentation.              
    '                                                                    
    '  Incorporation of any part of this software into other software,   
    '  except when such incorporation is exclusively for your own use    
    '  or for use by others in your organization in the performance of   
    '  their normal duties, is prohibited without the prior written      
    '  consent of Autodesk, Inc.                                         
    '                                                                    
    '  Copying, modification and distribution of this software or any    
    '  part thereof in any form except as expressly provided herein is   
    '  prohibited without the prior written consent of Autodesk, Inc.    
    '                                                                    
    '  AUTODESK PROVIDES THIS SOFTWARE "AS IS" AND WITH ALL FAULTS.      
    '  AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF           
    '  MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK,       
    '  INC. DOES NOT WARRANT THAT THE OPERATION OF THE SOFTWARE          
    '  WILL BE UNINTERRUPTED OR ERROR FREE.                              
    '                                                                    
    '  Restricted Rights for US Government Users.  This software         
    '  and Documentation are provided with RESTRICTED RIGHTS for US      
    '  US Government users.  Use, duplication, or disclosure by the      
    '  Government is subject to restrictions as set forth in FAR         
    '  12.212 (Commercial Computer Software-Restricted Rights) and       
    '  DFAR 227.7202 (Rights in Technical Data and Computer Software),   
    '  as applicable.  Manufacturer is Autodesk, Inc., 111 McInnis       
    '  Parkway, San Rafael, California 94903.                            
    '
    '============================================================================

    Option Explicit
    On Error Resume Next 

    dim bProdFound, b64bitOS, bRemovePlugins
    dim strInstallFolder, strProductName, strMainProductName
    dim strTitle, strMsg
    dim languageCode, languageAbbv
    dim heroProductPrefix, heroProductSuffix
    dim objShell
    dim intMsgRet

    dim x64products(4)
    dim x86products(4)

    const HKEY_CURRENT_USER = &H80000001
    const HKEY_LOCAL_MACHINE = &H80000002

    '============================================================================
    ' set the GUID prefix and suffix for the main product being uninstalled
    heroProductPrefix = "{7F4DD591-1564"
    heroProductSuffix = "7107D70F3DB4}"

    ' set the product language code and abbreviation
    ' English
    languageCode = "409"
    languageAbbv = "enu"

    '============================================================================
    ' initialize the arrays with the GUIDs and names for all products we may need to uninstall

    ' AutoCAD 2011 English (x64)
    x64products(0) = heroProductPrefix & "-0" & languageCode & "-0000-" & heroProductSuffix
    ' AutoCAD 2011 English language pack (x64)
    x64products(1) = heroProductPrefix & "-0" & languageCode & "-1102-" & heroProductSuffix
    ' AutoCAD 2011 Subscription Advantage Pack (x64)
    x64products(2) = "{ADF5CB42-ACFD-41EF-0133-871E54505C1D}"
    ' AutoCAD WS plug-in for AutoCAD 2011 (x64)
    x64products(3) = "{BF780694-C47E-4122-0196-B89B22F3387C}"
    ' AutoCAD 2011 VBA Enabler (x64)
    x64products(4) = "{68519E09-4927-46AE-01E2-8D60D0CF41BC}"

    ' AutoCAD 2011 English (x86)
    x86products(0) = heroProductPrefix & "-0" & languageCode & "-0002-" & heroProductSuffix
    ' AutoCAD 2011 English language pack (x86)
    x86products(1) = heroProductPrefix & "-0" & languageCode & "-1002-" & heroProductSuffix
    ' AutoCAD 2011 Subscription Advantage Pack (x86)
    x86products(2) = "{42E572CC-6D4C-4A3E-B937-7594D36B2B44}"
    ' AutoCAD WS plug-in for AutoCAD 2011 (x86)
    x86products(3) = "{B96F1390-23DD-4002-B183-EF0560D784E9}"
    ' AutoCAD 2011 VBA Enabler (x86)
    x86products(4) = "{ED7DFC69-2B9A-4A1F-9F50-8AB89B688EBA}"

    'initialize status variants
    bProdFound = False
    b64bitOS = False
    bRemovePlugins = False

    ' start by determing if we have a valid product installed
    Set objShell = CreateObject("Wscript.Shell")

    ' look for the x64 version first
    bProdFound = getProductInfo(x64products(0), False)
    b64bitOS = bProdFound
    ' if we didn't find it, look for the x86 version
    if bProdFound = False then
       bProdFound = getProductInfo(x86products(0), False)
    end if

    ' if we found an installed product, report it and get uninstall confirmation
    if bProdFound then
       strTitle = "AutoCAD 2011 Uninstall Script"
       strMainProductName = strProductName

       ' get approval to uninstall AutoCAD
       intMsgRet = uninstallACAD2011WarningMsg()
       ' if the user approved uninstall, proceed
       if intMsgRet = vbYes Then
          ' get approval to uninstall plugins
          intMsgRet = uninstallPluginsWarningMsg()

          ' if the user did not cancel the whole operation, proceed
          if intMsgRet <> vbCancel then
             if intMsgRet = vbYes Then
                bRemovePlugins = True
             end if

             if b64bitOS = True then
                uninstallProducts(x64products)
             else
                uninstallProducts(x86products)
             end if

             deleteProductFolders()    
             deleteProductRegKeys()

             strMsg = strMainProductName & " Uninstall Complete." & Vbcrlf & Vbcrlf & _
                      "We recommend restarting your system to help ensure complete cleanup."

             intMsgRet = msgbox(strMsg, vbOkonly+VBExclamation, strTitle)
          end if
       end  if
    Else
       strMsg = "No installation of AutoCAD 2011 was found."
       intMsgRet = msgbox(strMsg, vbOkonly+VBExclamation, strTitle)
    end if

    '============================================================================
    ' uninstall each product code it finds
    '============================================================================
    function uninstallProducts(aProductList)
       dim pos, retVal
       dim installer : Set installer = nothing
       dim strGUID, strModuleName 
       Const msiUILevelNone = 2         '/qn
       Const msiUILevelHideCancel = 32   '/!
       Const msiInstallStateAbsent = 2

       On Error Resume Next 
       Err.Clear

       Set installer = CreateObject("WindowsInstaller.Installer")
       installer.UILevel = msiUILevelNone

       for pos = 0 to UBound(aProductList)
          strGUID = aProductList(pos)
          retVal = getProductInfo(strGUID, True)
          if retVal = True then
             strModuleName = strProductName

             if installer.productstate (strGUID) > 0 Then
                ' if the user did not approve removal of plug-ins, bail
                if pos > 1 and bRemovePlugins = False then
                   Exit For
                end If

                'WScript.Echo "Uninstalling " & strGUID & Vbcrlf & Vbcrlf & strModuleName

                installer.ConfigureProduct strGUID, 65535, msiInstallStateAbsent

                if Err.Number <> 0 then
                   WScript.Echo "Error uninstalling " & strModuleName & Vbcrlf & Vbcrlf & _
                                "Error: " & Err.Number & " - " & Err.Description
                   Err.Clear
                Else
                   'WScript.Echo "Uninstalled " & strModuleName
                end if
             end if
          end if
       next

       set installer = Nothing
    end function

    '============================================================================
    ' delete folders
    '============================================================================
    function deleteProductFolders()    
       dim pos
       dim loopCtr
       dim sUsrProfile
       dim productFolders(6)
       dim objFileSys

       On Error Resume Next        

       Set objFileSys = CreateObject("Scripting.FileSystemObject")
       'Expand Environment
       sUsrProfile = objShell.ExpandEnvironmentStrings("%UserProfile%")

       ' actual installation location as retrieved from registry
       productFolders(0) = strInstallFolder
       ' windows vista/win7 related AutoCAD program paths
       productFolders(1) = "C:\ProgramData\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv
       productFolders(2) = sUsrProfile & "\AppData\Local\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv
       productFolders(3) = sUsrProfile & "\AppData\Roaming\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv
       ' windows XP related AutoCAD program paths
       productFolders(4) = sUsrProfile & "\Application Data\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv
       productFolders(5) = sUsrProfile & "\Local Settings\Application Data\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv
       productFolders(6) = "C:\Documents and Settings\All Users\Application Data\Autodesk\AutoCAD 2011\R18.1\" & languageAbbv

       Err.Clear

       for pos = 0 to UBound(productFolders)
          loopCtr = 0 
          ' delete the folder within a 30-second loop to account for system lock issues
          do While objFileSys.FolderExists(productFolders(pos)) And loopCtr < 6
             objFileSys.DeleteFolder productFolders(pos), True
             if Err.Number <> 0 then
                WScript.Echo "Folder not deleted: " & productFolders(pos) & Vbcrlf & Vbcrlf & _
                             "Error: " & Err.Number & " - " & Err.Description
                Err.Clear
                WScript.Sleep 5000 ' sleep 5 seconds
                loopCtr = loopCtr + 1 
             Else
                'WScript.Echo "Folder deleted: " & productFolders(pos)
             end if
          Loop 
       next

       Set objFileSys = Nothing
    end function

    '============================================================================
    ' delete registry keys for the specific installed product and language
    '============================================================================
    function deleteProductRegKeys()
       dim pos
       dim HKCURegKeys(3)
       dim HKLMRegKeys(3)

       HKCURegKeys(0) = "Software\Autodesk\AutoCAD\R18.1\ACAD-9001:" & languageCode
       HKCURegKeys(1) = "Software\Autodesk\AutoCAD\R18.1\AutoCAD 2011 Subscription Advantage Pack"
       HKCURegKeys(2) = "Software\Autodesk\AutoCAD\R18.1\AutoCAD 2011 VBA Enabler"
       HKCURegKeys(3) = "Software\Autodesk\AutoCAD\R18.1\AutoCAD WS plug-in for AutoCAD 2011"

       HKLMRegKeys(0) = "Software\Autodesk\AutoCAD\R18.1\ACAD-9001:" & languageCode
       ' the following modules are English-only so the language code is hard-coded
       HKLMRegKeys(1) = "Software\Autodesk\AutoCAD 2011 Subscription Advantage Pack:409"
       HKLMRegKeys(2) = "Software\Autodesk\AutoCAD 2011 VBA Enabler:409"
       HKLMRegKeys(3) = "Software\Autodesk\AutoCAD WS plug-in for AutoCAD 2011:409"

       ' delete the AutoCAD product reg keys
       deleteRegKey HKEY_CURRENT_USER, HKCURegKeys(0)
       deleteRegKey HKEY_LOCAL_MACHINE, HKLMRegKeys(0)
       ' delete the AutoCAD EULA reg key
       deleteRegKey HKEY_LOCAL_MACHINE, "Software\Autodesk\AutoCAD 2011 - English"

       if bRemovePlugins then
          for pos = 1 to UBound(HKCURegKeys)
             deleteRegKey HKEY_CURRENT_USER, HKCURegKeys(pos)
             deleteRegKey HKEY_LOCAL_MACHINE, HKLMRegKeys(pos)
          next
       end if
    end function

    '============================================================================
    ' delete registry key
    '============================================================================
    sub deleteRegKey(rootKey, delKey)
       dim strComputer, strRootKey
       dim objRegistry : set objRegistry = Nothing
       strComputer = "."

       On Error Resume Next 
       Err.Clear

       if rootKey = HKEY_CURRENT_USER then
          strRootKey = "HKCU\"
       else
          strRootKey = "HKLM\"
       end if

       Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
        strComputer & "\root\default:StdRegProv")

       if regKeyFound(strRootKey & delKey & "\") Then        
          objRegistry.DeleteKey rootKey, delKey
          if Err.Number <> 0 then
             WScript.Echo "DeleteKey failed: " & delKey & Vbcrlf & Vbcrlf & _
                          "Error: " & Err.Number & " - " & Err.Description
             Err.Clear
          else
             'Wscript.Echo "Deleted: " & strRootKey & delKey
          End If
       Else
          'WScript.Echo "Key not found: " & strRootKey & delKey    
       End If

       Set objRegistry = Nothing
    end sub

    '============================================================================
    ' search for installed product and get the installation folder and name
    '============================================================================
    function getProductInfo(prodCode, bNameOnly)
       dim strKeyPath, strValueName, strComputer
       dim objRegistry : set objRegistry = Nothing
       strComputer = "."

       Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
        strComputer & "\root\default:StdRegProv")

       strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & prodCode

       ' determine if the product is installed
       if regKeyFound("HKLM\" & strKeyPath & "\") Then        
          ' Get the name of the product being uninstalled
          strValueName = "DisplayName"
          objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strProductName

          if bNameOnly = False then
             strKeyPath = "SOFTWARE\Autodesk\AutoCAD\R18.1\ACAD-9001:" & languageCode

             if regKeyFound("HKLM\" & strKeyPath & "\") Then        
                ' Get the actual installation location before uninstalling
                strValueName = "AcadLocation"
                objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strInstallFolder
             End If
          end if

          getProductInfo = True    
       Else
          getProductInfo = False
       End If

       Set objRegistry = Nothing
    end function

    '============================================================================
    ' returns true if a registry key exists
    '============================================================================
    function regKeyFound(regkey)
       Dim retVal
       On Error Resume Next    
       Err.Clear
       retVal = objShell.RegRead(regkey)    
       if Err.Number <> 0 then
          'WScript.Echo "Error reading key: " & regkey & Vbcrlf & Vbcrlf & _
          '             "Error: " & hex(Err.Number) & " - " & Err.Description
          Err.Clear
          regKeyFound = False
       else
          regKeyFound = True    
       End If
    end function

    '============================================================================
    ' display the initial warning message and get OK to continue
    '============================================================================
    function uninstallACAD2011WarningMsg()
       dim strMsg

       strMsg = "WARNING!" & Vbcrlf & Vbcrlf & _
                strMainProductName & " is currently installed at" & Vbcrlf & _
                strInstallFolder & Vbcrlf & Vbcrlf & _
                "This script will remove " & strMainProductName & " and related folders and registry keys from your computer." & Vbcrlf & Vbcrlf & _
                "This script should be run an as Administrator and we strongly recommend backing up any custom files before proceeding." & Vbcrlf & Vbcrlf & _
                "Do you want to continue?"

       uninstallACAD2011WarningMsg = msgbox(strMsg, vbYesNo+VBExclamation, strTitle)
    end function

    '============================================================================
    ' get the OK to uninstall plug-ins
    '============================================================================
    function uninstallPluginsWarningMsg()
       dim strMsg

       strMsg = "This script can also remove the VBA Enabler," & Vbcrlf & _
                "Subscription Advantage Pack, and WS Plug-in." & Vbcrlf & Vbcrlf & _
                "These modules should NOT be uninstalled if they" & Vbcrlf & _
                "are shared by another AutoCAD installation." & Vbcrlf & Vbcrlf & _
                "Do you want to uninstall these modules?"

       uninstallPluginsWarningMsg = msgbox(strMsg, vbYesNoCancel+VBExclamation, strTitle)
    end function

答案1

对于卸载应用程序来说,这个脚本似乎有点大材小用。对于简单的卸载(没有上面看起来相当可疑的清理脚本条目),您只需从命令行卸载即可执行程序(下面使用的模拟 GUID):

msiexec.exe /X {00000000-0000-0000-0000-000000000000} /QN

或者你也可以通过以下方式卸载其他卸载机制(此链接还将向您展示如何找到用于卸载的正确 GUID)。如果 explorer.exe 最后关闭,您是否可以通过同一个批处理文件重新启动它?

相关内容