我们的许多客户都可以使用 InstallShield、WISE 或 AdminStudio。这些都不是问题。我希望有某种方法可以为我们的小型客户提供无需使用商业重新打包工具的免费工具集和步骤来自己进行文件替换。
只需要替换压缩 MSI 中的单个配置文件,可以假设目标用户已经安装了 Orca,知道如何使用它来自定义属性表(为 GPO 部署嵌入许可证详细信息)并生成了 MST 文件.
免责声明:这与另一个问题非常相似,但该线程中的问题和答案都不清楚。
我们的许多客户都可以使用 InstallShield、WISE 或 AdminStudio。这些都不是问题。我希望有某种方法可以为我们的小型客户提供无需使用商业重新打包工具的免费工具集和步骤来自己进行文件替换。
只需要替换压缩 MSI 中的单个配置文件,可以假设目标用户已经安装了 Orca,知道如何使用它来自定义属性表(为 GPO 部署嵌入许可证详细信息)并生成了 MST 文件.
免责声明:这与另一个问题非常相似,但该线程中的问题和答案都不清楚。
好的,用我自己的答案重新审视这个问题,提供很好的小 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 一起使用。
恕我直言,这种情况表明正在安装的应用程序中缺少功能,并且在应用程序中修复比使用 MSI 更容易修复。
首先让我说一个为您的用户“解决”这个问题的简单方法是告诉他们运行您的 MSI 的管理员安装。这实际上将从内部 CAB 中提取所有文件并将所有文件放在指定的文件夹中:
msiexec.exe /a myinstaller.msi TARGETDIR=C:\AdminImage
然后,您的用户可以直接进入提取的文件夹结构并更新相关文件,然后将目录映射到其他 PC 并安装 MSI。与在 MSI 中具有哈希值的文件有关(以避免欺骗),这可能会产生副作用,但在大多数情况下它可以正常工作。
新版本的部署工具(例如 Installshield 和 Wix)内置了对在安装期间运行 XPath 查询的支持,因此可以动态编写部分。
在 PC 上设置应用程序涉及几个步骤。首先是将内容部署到机器上——这应该使用 MSI 来完成,毫无疑问。但是,在大多数高级应用程序中,需要几个类似于此“配置文件更新”的“安装后配置任务”。
将这些配置任务推迟到应用程序启动几乎总是更好,而不是在 MSI 中实现功能。这有很多原因,但最重要的是只有应用程序 EXE 才能保证在正确的用户上下文中运行。MSI 文件可以使用系统权限、不同的用户帐户或通过某种其他机制运行。
我们通常推荐的是使用 MSI 将所有需要的内容下载到 PC 上。然后标记注册表以向应用程序指示它是第一次启动(对于更新,您可以增加一个计数器或将新版本号写入 HKLM)。然后应用程序可以在其启动例程中执行最后的配置步骤。它可以从 %ProgramFiles% 中的某个位置复制默认的 config.xml 文件并将其复制到用户配置文件中。然后它可以从 MSI 写入的 HKLM 中读取所需的值,然后用这些值更新 config.xml 文件。
一般来说:避免由 MSI 或任何其他设置机制执行的配置步骤。专注于将所需的文件和注册表项写入机器,然后让应用程序自己设置合适的运行时环境。这将允许更好的部署控制。如果你愿意,最好是“封装”。MSI 通过注册表向应用程序发送“消息”,应用程序根据该消息知道“如何正确设置自己”。
检查以下帖子: 如何替换 msi 安装程序中的文件?
哪里提到:
此命令提取 MSI 文件: msi2xml -c OutputDir TestMSI.MSI
打开 OutputDir 并修改文件。
要重建 MSI,请运行:xml2msi.exe -m TestMSI.xml
您需要 -m 来忽略修改 MSI 文件时失败的“MD5 校验和测试”。