Simplest solution to replace a tiny file inside an MSI?

后端 未结 5 1167
情书的邮戳
情书的邮戳 2020-12-03 15:32

Many of our customers have access to InstallShield, WISE or AdminStudio. These aren\'t a problem. I\'m hoping there is some way I can provide our smaller customers w

5条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-03 15:58

    Okay, revisiting this question with my own answer providing nice little VB script that will do all heavy lifting. As mentioned in the original question, the aim was provide a simple solution for sysadmin users to make the updates/changes themselves.

    Below is a simplified version of the code I'm currently providing to customers

    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
    

    Update: The MakeCab.MakeCab.1 object has been depreciated, code updated to now work with Windows 7.

提交回复
热议问题