首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >卸载软件时Windows如何查找安装位置

卸载软件时Windows如何查找安装位置
EN

Stack Overflow用户
提问于 2020-02-11 16:03:48
回答 2查看 2.4K关注 0票数 2

当我运行允许自定义安装位置/路径的安装程序时,文件将正确地放置在我选择的位置。

当我运行相同的MSI并选择remove (或从add/remove程序中卸载)时,它如何知道安装位置以便删除正确的文件?

我原以为它会存储在'Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{GUID}',,但当我看到我安装的软件的位置,'InstallLocation‘键为空

但是,不管我如何卸载它,它都知道要删除哪个文件夹,不管我把它放在哪里。该信息是存储在注册表的其他地方,还是存储在MSI文件本身中?

EN

回答 2

Stack Overflow用户

发布于 2020-02-11 16:21:55

这是一个非常复杂的问题,因为MSI可以配置为在您告诉它的任何地方删除它的卸载文件。通常默认情况下,它将在C:\Windows\Installer中创建一个具有特定名称的卸载.msi文件。

但是,不要依赖于将卸载.msi放在这个目录中,也不依赖于卸载注册表项中有卸载路径。这把钥匙和其他任何东西一样,对终端用户来说是很方便的。

卸载信息通常包含在MSI文件中,但是它不需要,并且在安装期间它可以创建键来帮助升级和卸载。安装将留在注册表中的信息完全取决于您如何配置.msi数据库。

再加上一些东西..。许多安装程序,比如Nullsoft、InstallAware和InstallShield,都喜欢做自己的事情,并将卸载信息放在其他地方。因此,InstallShield喜欢创建InstallShield安装信息文件夹,Nullsoft喜欢创建.dat文件和uninstall.exe。但除此之外,这些安装程序仍在调用MSI并创建安装表和数据库。因此,卸载信息的位置并不是一门精确的科学!

票数 3
EN

Stack Overflow用户

发布于 2020-02-15 20:17:14

更新: 查找组件的安装位置有没有办法检测安装位置而不卸载注册表或C:\Windows\Installer?

Implementation :MSI如何存储这些东西是不应该被干预、试图修改或直接用于任何目的的实现细节--这一点非常清楚。您应该阅读MSI ,它是以Win32 functions的形式实现的,具有互补的COM wrappers,以便通过脚本语言进行访问。

MSI数据库主要存储在注册表中,但磁盘上也有组件--例如,%SystemDrive%\Windows\Installer (一个不应该以任何方式修改的超级隐藏文件夹)。MSI数据库存储在整个注册表的多个位置:

  • HKCR\Installer
  • HKCU\Software\Microsoft\Installer
  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer
  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Installer
  • Etc...

有些是真实的,有些是别名,有些是合并。一切都有点模糊。再说一遍:implementation details --这是我们大家都熟知的委婉说法:“现在放弃吧,你?”:-)只需应用MSI获取所需的信息即可。

MSI API:上面要阅读的东西很多,可以通过MSI获取有关目录解析的信息。我们要做的是有点异国情调,我们必须为已安装的产品旋转一个会话对象,并运行两个标准操作(来自微软的内置MSI操作),以便解析所涉MSI (关于“成本”)的目录表和安装目录。以下是一个实际的样本:

请记录在案:

代码语言:javascript
复制
Set installer = CreateObject("WindowsInstaller.Installer")

' Other test product codes: {2F73A7B2-E50E-39A6-9ABC-EF89E4C62E36}

productcode = Trim(InputBox("Please paste or type in the product code you want to look up details for:", _
              "Find Product Details (test GUID provided):", "{766AD270-A684-43D6-AF9A-74165C9B5796}"))
If search = vbCancel Or Trim(productcode) = "" Then
   WScript.Quit(0)
End If

Set session = installer.OpenProduct(productcode)

' Crucially, resolve the directory table and properties by running "MSI Costing"
session.DoAction("CostInitialize")
session.DoAction("CostFinalize")

' Can be any directory property from the Directory table in the MSI:
MsgBox session.Property("INSTALLFOLDER")

' Open the MSI in Orca to find the directory folder property names

如何列出MSI文件中的表上添加一个指向旧答案的链接。

解决了所有的:有点抓走了,然后再进行一次更新来解析所有已安装的软件包的所有目录。下面是一个脚本(测试不多):

代码语言:javascript
复制
' https://stackoverflow.com/questions/17543132/how-can-i-resolve-msi-paths-in-vbscript
' On Error resume Next

Set installer = CreateObject("WindowsInstaller.Installer")

' Other test product codes: {2F73A7B2-E50E-39A6-9ABC-EF89E4C62E36}

const READONLY = 0
Dim DirList

productcode = Trim(InputBox("Please paste or type in the product code you want to look up details for:", _
              "Find Product Details (test GUID provided):", "{766AD270-A684-43D6-AF9A-74165C9B5796}"))
If search = vbCancel Or Trim(productcode) = "" Then
   WScript.Quit(0)
End If

Set session = installer.OpenProduct(productcode)
session.DoAction("CostInitialize")
session.DoAction("CostFinalize")

set view = session.Database.OpenView("SELECT * FROM Directory")
view.Execute
set record = view.Fetch

Do until record is Nothing
    
    ResolvedDir = session.Property(record.StringData(1))
    DirList = DirList + record.StringData(1) + " => " + ResolvedDir + vbCrLf
    set record = view.Fetch

Loop

' Dismiss dialog with ESC key if it falls off screen 
WScript.Echo DirList ' Use WScript.Echo due to MsgBox restrictions (number of characters)

链接

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60172976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档