代码之家  ›  专栏  ›  技术社区  ›  saschabeaumont

替换MSI中的小文件的最简单解决方案?

  •  11
  • saschabeaumont  · 技术社区  · 17 年前

    我们的许多客户都可以访问InstallShield、WISE或AdminStudio。这些都不是问题。我希望有办法为我们的小客户提供服务 无法使用商业重新包装工具 一套免费提供的工具和步骤,用于自己进行文件替换。

    只需替换压缩MSI中的单个配置文件,就可以假定目标用户已经安装了Orca,知道如何使用它来自定义属性表(嵌入GPO部署的许可证详细信息)并生成MST文件。



    : another question 但这方面的问题和答案都不清楚。

    5 回复  |  直到 9 年前
        1
  •  9
  •   Stein Åsmul    12 年前

    好的,用我自己的答案重新讨论这个问题,提供了一个很好的小VB脚本,可以完成所有繁重的工作。正如原始问题中提到的,目的是为系统管理员用户提供一个简单的解决方案,让他们自己进行更新/更改。

    Option Explicit
    
    Const MY_CONFIG = "MyConfigApp.xml"
    Const CAB_FILE = "config.cab"
    Const MSI = "MyApp.msi"
    
    Dim filesys : Set filesys=CreateObject("Scripting.FileSystemObject")
    
    If filesys.FileExists("temp.tmp") Then filesys.DeleteFile("temp.tmp")
    filesys.CopyFile MSI, "temp.tmp"
    
    Dim installer, database, database2, view
    Set installer = CreateObject("WindowsInstaller.Installer")
    Set database = installer.OpenDatabase ("temp.tmp", 1)
    Set database2 = installer.OpenDatabase (MSI, 1)
    
    If Not filesys.FileExists(MY_CONFIG) Then WScript.Quit 2 ' No config file, abort!
    
    Dim objFile, size, result, seq, objCab
    
    ' MakeCab object has been depreciated so we fallback to makecab.exe for with Windows 7
    On Error Resume Next ' Disable error handling, for a moment
    Set objCab = CreateObject("MakeCab.MakeCab.1") 
    On Error Goto 0  ' Turn error handling back on
    
    If IsObject(objCab) Then ' Object creation successful - use XP method   
        objCab.CreateCab CAB_FILE, False, False, False
        objCab.AddFile MY_CONFIG, filesys.GetFileName(MY_CONFIG)
        objCab.CloseCab
        Set objCab = Nothing
    Else ' object creation failed - try Windows 7 method
        Dim WshShell, oExec
        Set WshShell = CreateObject("WScript.Shell")
        Set oExec = WshShell.Exec("makecab " & filesys.GetFileName(MY_CONFIG) & " " & CAB_FILE)
    End If
    
    Set objFile = filesys.GetFile(MY_CONFIG)
    size = objFile.Size
    
    Set view = database.OpenView ("SELECT LastSequence FROM Media WHERE DiskId = 1")
    view.Execute
    Set result = view.Fetch
    seq = result.StringData(1) + 1 ' Sequence for new configuration file
    
    Set view = database.OpenView ("INSERT INTO Media (DiskId, LastSequence, Cabinet) VALUES ('2', '" & seq & "', '" & CAB_FILE & "')")
    view.Execute
    
    Set view = database.OpenView ("UPDATE File SET FileSize = " & size & ", Sequence = " & seq & ", FileName = 'MYC~2.CNF|MyConfigApp.xml' WHERE File = '" & MY_CONFIG & "'")
    view.Execute
    
    database.GenerateTransform database2, "CustomConfig.mst"
    database.CreateTransformSummaryInfo database2, "CustomConfig.mst", 0, 0
    filesys.DeleteFile("temp.tmp")
    
    Set view = nothing
    Set installer = nothing
    Set database = nothing
    Set database2 = nothing
    Set filesys = Nothing
    WScript.Quit 0
    

    更新: 这个 MakeCab.MakeCab.1 对象已折旧,代码已更新,现在可以使用Windows 7。

        2
  •  3
  •   Stein Åsmul    17 年前

    IMHO这种情况表明正在安装的应用程序中缺少一个功能,并且在应用程序中修复该功能比使用MSI进行黑客攻击更容易。


    让我首先说,一个简单的方法来“解决”你的用户,是告诉他们运行你的MSI管理员安装。这将从内部CAB中提取所有文件,并将所有文件放在指定的文件夹中:

    然后,用户可以直接进入提取的文件夹结构并更新有问题的文件,然后将目录映射到其他PC并安装MSI。这可能会对MSI中具有哈希值的文件产生副作用(以避免欺骗),但在大多数情况下效果良好。


    运行XML XPath查询

    新版本的部署工具(如Installshield和Wix)内置了对安装期间运行XPath查询的支持,因此可以动态编写节。


    应用程序更新

    在PC上设置应用程序需要几个步骤。首先是将内容部署到机器上——这应该使用MSI来完成,毫无疑问。但是,在大多数高级应用程序中,需要几个类似于此“配置文件更新”的“安装后配置任务”。

    ,而不是在MSI中实现功能。原因有很多,但最重要的是只有应用程序EXE才能保证在正确的用户上下文中运行。MSI文件可以使用系统权限、不同的用户帐户或通过其他机制运行。

    我们通常建议使用MSI来 将所有必需的内容下载到电脑上 . 然后标记注册表,向应用程序表明这是第一次启动(对于更新,您可以增加计数器或将新版本号写入HKLM)。然后,应用程序可以在其启动例程中执行最后的配置步骤。它可以从%ProgramFiles%中的某个位置复制默认config.xml文件,并将其复制到用户配置文件中。然后它可以从MSI编写的HKLM中读取所需的值,然后用这些值更新config.xml文件。

    一般情况下:避免由MSI或任何其他设置机制执行配置步骤。集中精力将所需的文件和注册表项写入计算机,然后让应用程序本身设置适当的运行时环境。这将允许更好的部署控制。如果你喜欢,最好是“封装”。MSI通过注册表向应用程序发送“消息”,应用程序根据这些消息知道“如何正确设置自身”。

        3
  •  2
  •   wimh    17 年前

    我建议您自己创建msi文件(?)

    当你使用 Wix 要生成msi,客户只需在替换文件后重新生成整个msi即可(wix是免费的)。否则,应该可以使用未嵌入msi的未压缩文件。在wix中,您必须添加一个 media element 没有内阁属性。缺点是您必须分发两个文件,而不是单个msi。

        4
  •  1
  •   Martin v. Löwis    17 年前

    您需要将一个条目添加到 Media 表中,添加了另一个没有CAB文件的介质,并且LastSequence比CAB文件的最后一个序列多一个。然后,您需要在 File 使用新文件列出文件的序列,并更新可能已更改的所有其他文件属性。

        5
  •  1
  •   Cesar Albino Flores    8 年前

    How to replace a file in a msi installer?

    此命令提取MSI文件: msi2xml-c OutputDir TestMSI.MSI

    打开OutputDir并修改文件。

    要重建MSI运行,请执行以下操作: xml2msi.exe-m TestMSI.xml

    您需要使用-m忽略修改MSIs文件时失败的“MD5校验和测试”。

    https://msi2xml.sourceforge.io/

    推荐文章