我可以使用msilib或其他Python库从.msi文件提取一个文件?(Can I use msil

2019-08-17 19:26发布

我真正想要做的是确定在MSI特定文件是否存在,是否包含一个特定的字符串。

我现在的想法是运行:

 db = msilib.OpenDatabase('c:\Temp\myfile.msi',1)
 query = "select * from File"
 view = db.OpenView(query)
 view.Execute(None)
 cur_record = view.Fetch()     # do this until I get the record I want
 print cur_record.GetString(3) # do stuff with this value

然后,如果它的存在,使用提取所有文件

msiexec /a c:\Temp\myfile.msi /qn TARGETDIR=c:\foo

和使用任何解析器看到我的字符串是否是存在的。 但我希望不那么笨重的方式存在。

Answer 1:

需要注意的是,作为文档msilib说,“读取.cab文件的支持尚未实现”。 和。 更一般地,该库是专门为建筑的.msi文件,而不是阅读。 还有没有别的在STDLIB会做你想要什么。

因此,有以下几种可能:

  1. 查找并安装另一个库,像pycabinet 。 我对此一无所知特定库; 这只是第一个搜索命中我; 你可能想在自己的搜索。 但它宣称提供一个zipfile的CAB文件式的API,这听起来像正是你缺少的部分。
  2. 使用win32com (如果你有pywin32 )或ctypes (如果你是一个受虐狂)交谈的基础COM接口和/或经典内阁API(我认为这是现在已经过时,但仍然有效)。
  3. 使用IronPython的而不是CPython的,所以你可以使用简单的.NET接口。

因为我没有Windows中在这里,我不能对此进行测试,但这里的克里斯托弗画家写在IronPython的,而不是C#.NET解决方案的草图:

import clr
clr.AddReference('Microsoft.Deployment.WindowsInstaller')
clr.AddReference('Microsoft.Deployment.WindowsInstaller.Package')
from Microsoft.Deployment.WindowsInstaller import *
from Microsoft.Deployment.WindowsInstaller.Package import *

def FindAndExtractFiles(packagePath, longFileName):
    with InstallPackage(packagePath, DatabaseOpenMode.ReadOnly) as installPackage:
        if installPackage.FindFiles(longFileName).Count() > 0:
            installPackage.ExtractFiles()


Answer 2:

要知道,在使用Python,你必须处理Windows安装程序(COM)自动化接口。 这意味着你必须做所有的数据库连接,查询和处理自己。

如果你可以移动到C#(或者说PowerShell的),你可以利用存在于Windows安装程序XML的一些高级别类(WiX的)部署工具基金会(DTF)。

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Package;

static void FindAndExtractFiles(string packagePath, string longFileName)
{
    using (var installPackage = new InstallPackage(packagePath, DatabaseOpenMode.ReadOnly))
    {
        if(installPackage.FindFiles(longFileName).Count() > 0 )
            installPackage.ExtractFiles();
    }
}

你也可以这样写标记有ComVisible特性(真)和Python的调用它。



Answer 3:

微星的API本身是笨重的,所以它只能是在哪里抽象躺着一个问题。 请记住,如果你只需要这几次,它可能是更容易浏览CAB文件(S)在资源管理器中手动。 (文件由文件密钥,而不是文件名保存)。



文章来源: Can I use msilib or other Python libraries to extract one file from an .msi file?