问题描述
在powershell上,我正在执行以下命令:
$objWMI = wmic product where "name like 'app' " get PackageCache
echo $objWMI
输出:
PackageCache
C:\Windows\Installer\file.msi
解决方法
Colin's helpful answer提供了有效的解决方案,尽管有两个使用不同方法的充分理由:
-
wmic.exe
CLI是deprecated(PowerShell的*-Wmi*
cmdlet,例如Get-WmiObject
) -
作为外部程序,它只能将 text 与PowerShell通讯,然后PowerShell需要 parsing 来获取信息。既麻烦又脆弱。
使用 Get-CimInstance
cmdlet 可以避免两个问题:建议使用CIM cmdlet与WMI进行交互,并且作为本机PowerShell cmdlet, Get-CimInstance
返回对象,而不是文本,您可以通过强大的方式访问其属性:
# Get the Win32_Product instance of interest and output its
# .PackageCache propertly value.
(Get-CimInstance Win32_Product -Filter 'Name like "app"').PackageCache
上面的代码直接输出一个字符串,例如C:\Windows\Installer\file.msi
;只需添加$packagePath =
之类的内容,即可将其捕获到变量中。
注意事项:
如果可能的话,应避免使用Win32_Product
CIM / WMI类,因为its use is excessively slow and can have side effects(添加了重点):
,Win32_product类未针对查询进行优化。诸如“从Win32_Product中选择*,其中(名称类似于'Sniffer%')之类的查询”要求WMI使用MSI提供程序枚举所有已安装的产品,然后依次解析完整列表以处理“ where”子句。此过程还启动对已安装软件包的一致性检查,以验证和修复安装。对于仅具有用户特权的帐户,由于该用户帐户可能无法访问多个位置,因此可能会导致应用程序启动延迟以及事件11708指出安装失败。。
成功运行命令后,示例中的变量将转换为数组,并且路径始终显示在第三行,因此您可以简单地调用$ objWMI [2]仅提供目录(我们使用数字2,因为如果我们想要第一行,我们将使用[0])。
总的来说,可能像下面这样简单。
$objWMI = wmic product where "name like 'app' " get PackageCache
$directory=$objWMI[2]
echo $directory