当前位置: 首页 > 编程笔记 >

VB.NET中调用MSI卸载软件的2个方法

邢昂然
2023-03-14
本文向大家介绍VB.NET中调用MSI卸载软件的2个方法,包括了VB.NET中调用MSI卸载软件的2个方法的使用技巧和注意事项,需要的朋友参考一下

最近在折腾组里面的那个破Lab,要自己写程序每天安装最新版本的build。而今天手头上没有任何任务,所以把用到的一些东西记下来以供今后参考。这篇日志来记录如何在.NET中卸载别的软件。

一、直接使用MSI安装

  如果你知道MSI安装程序的路径,那么显然可以直接使用即可:


msiexec /x "C:Table Manager Clients.msi" /quiet /qn

/quiet参数表示自动卸载,/qn表示 显示任何UI。

  这个方法很简单,推荐使用。但是如果软件的版本不对,或者安装程序做得有问题(比如我们这做的一个奇葩安装程序),那么就不行了。


msiexec /Option <Required Parameter> [Optional Parameter]

    

Install Options

    </package | /i> <Product.msi>

        Installs or configures a product

 但是这个序列号是不定的,对于相同程序的不同版本,序列号也不一定相同(可能会生成一个新的序列号)。为了得到需要产品的序列号,就只能去查注册表了。

二、使用产品序列号卸载程序

  所有用MSI安装的程序都会记录在HKEY_LOCAL_MACHINE的SOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Products子健下。S-1-5-18是系统通用的用户,可能有其他的用户目录(比如我这有S-1-5-21-2109753547-707883502-1543859470-98763),应该是对应的在安装时不共享的那些程序。

 如上图,在Products键下有一大堆十六进制的数字。在数字下可能有InstallProperties子键(注意不是每一个都有),然后有DisplayName用于标识产品的名称,DisplayVersion用于显示版本号等等。我们只需要关注会用到的就行了,这里就只关注产品名称吧。

在左侧显示的数字并不是用于msi卸载的产品序列号。我们注意到有一个UninstallString属性,这个属性就是卸载这个程序的命令及参数:


MsiExec.exe /X{4B9E6EB0-0EED-4E74-9479-F982C3254F71}

那么,我们要做的很显然是搜索这些键,查找哪一个才是我们要卸载的产品,然后用UninstallString把它卸掉就行了。另外我们需要在参数上加上/quiet和/qn参数,这样就能实现自动卸载了。


Private Sub UninstallMsi(productName As String)

    Dim reg_path As String = "SOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Products"

  

    Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey(reg_path)

  

    For Each temp_key_name As String In key.GetSubKeyNames()

        Dim temp_key As RegistryKey = key.OpenSubKey(temp_key_name & "InstallProperties")

  

        If temp_key IsNot Nothing Then

            If temp_key.GetValue("DisplayName").ToString.Trim.ToLower = productName.Trim.ToLower Then

  

                Dim uninstall_string As String = temp_key.GetValue("UninstallString").ToString

  

                uninstall_string = uninstall_string.ToLower.Replace("msiexec.exe", "").Replace("msiexec", "").ToUpper

  

                uninstall_string = uninstall_string.Replace("/I", "/x")

                uninstall_string = uninstall_string.Replace("/i", "/x")

  

                uninstall_string &= " /quiet /qn"

  

                Console.WriteLine("Uninstalling product " & uninstall_string)

                LogDataAccess.InsertApplicationLog(TMConfigrationManager.GetConfig("ServerType"), _

                                                 "Uninstalling " & productName & """" & uninstall_string & """ ...")

  

                Dim proc_start_info As New ProcessStartInfo("msiexec", uninstall_string)

  

                Dim proc As Process = Process.Start(proc_start_info)

  

                If (proc IsNot Nothing) Then proc.WaitForExit()

                If proc.ExitCode <> 0 Then

                    Dim err_message As String = "Uninstall " & productName & " failed."

 

                    LogDataAccess.InsertApplicationLog(TMConfigrationManager.GetConfig("ServerType"), err_message)

                    Console.WriteLine(err_message)

                End If

  

                LogDataAccess.InsertApplicationLog(TMConfigrationManager.GetConfig("ServerType"), "Uninstall previous version of " & productName & " successful.")

  

                Exit Sub

            End If

        End If

    Next

  

    Dim message As String = "Cannot find " & productName & " registry entries. Do not need to uninstall."

 

    LogDataAccess.InsertApplicationLog(TMConfigrationManager.GetConfig("ServerType"), message)

    Console.WriteLine(message)

End Sub

.NET中访问注册表的类封装在Microsoft.Win32命名空间下,直接使用即可(主要使用RegistryKey类,RegisitryKey类似树形结构)。

  这就是实现自动卸载的代码(里面有一些与输出日志相关的代码,可以不用管它)。

  程序首先在Products键下搜索所有的产品,如果有InstallProperties子键,就匹配DisplayName是否与要卸载的程序相同,如果相同,就生成一个卸载的命令并启动一个新的进程进行卸载。

  如果卸载失败,msiexec会返回一个不为0的数值,此时我们将错误信息输出。(注意:还有两个数值表示卸载成功但是需要重启,请自行查找相关手册。)

 类似资料:
  • 问题内容: 当我尝试从虚拟环境中卸载时,我看到它也尝试卸载更多软件包: 我想卸载 只 和没有别的降级。 我知道这些软件包都 依赖 于熊猫甚至 特定版本 的panda,但这完全可能吗? 部分动机 我的理解是,使用来从GitHub安装软件包并不容易。至少它不像使用单线纸那样容易。 由于我想在中使用该版本,因此我的计划是卸载该版本,并使用从正式仓库GitHub上的master安装。 我怎样才能做到这一点

  • 如何在Mac OS X中完全卸载(删除属于某个包的文件)?这可以使用终端中的命令来完成吗? 我已经安装了一个。在Mac上安装pkg软件包,我想知道如何在不使用第三方应用程序(如UninstallPKG)的情况下卸载整个软件包? 我想知道卸载. dmg文件是否也需要第三方应用程序,或者是否可以在终端中输入命令卸载它们?

  • 本文向大家介绍.NET Framework 从解决方案中的一个项目中卸载软件包,包括了.NET Framework 从解决方案中的一个项目中卸载软件包的使用技巧和注意事项,需要的朋友参考一下 示例            

  • 本文向大家介绍Android编程之软件的安装和卸载方法,包括了Android编程之软件的安装和卸载方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android编程之软件的安装和卸载方法。分享给大家供大家参考,具体如下: 安装:从sdcard 或者 安装或升级 从网络 需要的权限 卸载 希望本文所述对大家Android程序设计有所帮助。

  • 问题内容: 您可以简单地从python安装中删除目录,还是必须删除任何残留文件? 问题答案: 它取决于您传递给的选项以及系统/软件包中distutils配置文件的内容。我不相信会以这些方式在指定目录之外修改任何文件。 值得注意的是,distutils目前没有卸载命令。 还值得注意的是,删除程序包/鸡蛋可能会导致依赖关系问题,例如尝试减轻此类问题的实用程序。

  • 问题内容: 在软件包目录中使用安装节点软件包时,完成开发后如何卸载软件包? 将软件包安装为系统全局软件包位置(’/ usr / local / lib`)中的符号链接。这样,您就可以在仍在开发程序包的情况下对其进行测试,而不必一遍又一遍地安装它。 我需要运行哪个npm命令来再次删除链接? 问题答案: 可以使用可用于删除已安装软件包的相同 卸载 或 rm 命令来 卸载 软件包。唯一要记住的是,该链接