如何构建WiX以便根据安装.msi的位置复制文件?

时间:2011-04-11 14:30:51

标签: wix

我必须使用WiX构建一个.msi,它可以部署到多个环境中。每个环境。有自己的配置文件。现在,我们为每个环境构建一个msi,我想摆脱这种做法。有没有办法只构建一个MSI,它可以根据特定文件的运行位置进行智能复制?

3 个答案:

答案 0 :(得分:6)

根据您定义的任何特征,确定了 的目标环境后,您可以为每个环境要部署的每个配置文件创建一个离散组件,并为每个组件只为该目标环境评估为true的条件,否则为false。

如果环境可能发生变化,您还需要使组件条件具有传递性,以便repair \ upgrade将部署正确的配置文件。

您可能面临的一个难题是组件应该代表独特的资源。但看起来你可能有很多不同的配置文件都具有相同的名称并且发往同一个目标文件夹。您可能会发现更容易为配置文件提供所有不同的“伪”名称,并使用CopyFile将伪版本复制到其终端目标。

答案 1 :(得分:1)

就我而言,我宣布了这样一个属性:

<Property Id="MACHINE_ENVIRONMENT" Admin="yes" />

从现在开始,每个组件都有一个&#34;条件&#34;设置为:

的元素
<Component Id="Log4Net_config" Guid="{666}">
  <Condition>MACHINE_ENVIRONMENT = "dev"</Condition>
  <File Id="Log4Net_config" Source="$(var.dir)\Log4Net.config.$(var.Environment)" Name="Log4Net.config" />
</Component>

通过命令行执行安装:

msiexec.exe /i "C:\mymsi.msi" MACHINE_ENVIRONMENT="dev"

这样我的单个MSI包含所有不同的log4net配置文件,但只根据提供的标志安装相关的文件。

答案 2 :(得分:0)

MSI File Table需要指定要安装的文件的字节大小,根据安装源位置执行某些操作需要自定义操作(通常是承认失败)

请参阅我的问题Simplest solution to replace a tiny file inside an MSI? - 我得到的解决方案是创建一个MSI转换(MST)。我发布的原始代码段在Windows 7上不起作用,所以这是一个更新:

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