使用 WiX 为 InstallShield 安装程序创建 msi 包装器
Posted
技术标签:
【中文标题】使用 WiX 为 InstallShield 安装程序创建 msi 包装器【英文标题】:Create msi wrapper for InstallShield installer using WiX 【发布时间】:2013-07-31 11:52:42 【问题描述】:我们使用 InstallShield 技术为客户准备了安装程序。安装程序工作正常,但客户希望此安装程序采用 msi 技术。我们决定使用 WiX 创建包装器。 Msi 安装程序应该做几件事:
-
将 IS 安装程序解压到临时目录中。
运行 InstallShield setup.exe。
IS 完成后删除临时目录。
我们之前没有做过 WiX 技术的安装程序,这些是我们的问题:
-
我们不知道如何使用 WiX 将目录及其所有文件(安装程序)嵌入到 msi 中。
我们不知道如何只运行 msi(它不应该安装数据,只在安装过程中运行嵌入的 IS setup.exe 并在之后删除)。
我们不知道如何在安装过程中运行 exe。
这是我目前创建的 *.wxs 文件:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="ISSetupPackeger" Language="1033" Version="1.0.0.0" Manufacturer="MyCompany" UpgradeCode="8804d459-2ea5-4bbc-85f7-dfc8419cafe4">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Id="*" InstallPrivileges="elevated" />
<!-- TODO setup.exe starts but we don't want to run it using cmd -->
<CustomAction Id="LaunchInstaller" Directory="InstallerDir" ExeCommand="cmd /C setup.exe" Impersonate="yes" Return="ignore" />
<InstallExecuteSequence>
<Custom Action="LaunchInstaller" After="InstallFinalize" />
</InstallExecuteSequence>
<Media Id='1' Cabinet='data.cab' EmbedCab='yes'/>
<Feature Id="ProductFeature" Title="WixInstallerProject" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!-- TODO How to extract files to temp dir? Is there some TEMP constant? -->
<Directory Id="TARGETDIR" Name="SourceDir" >
<Directory Id="TempDir" Name="inst">
<Directory Id="InstallerDir" Name="Installer"/>
</Directory>
</Directory>
<!-- component group which will be installed into tempdir -->
<ComponentGroup Id="ProductComponents" Directory="InstallerDir">
<Component Id="Installer" Guid="7b8bd37f-7eda-4c3a-8155-9dae1a6bbf98">
<!-- TODO How to embed directory with all its files/subdirectories? -->
<File Id="_Setup.dll" Name="_Setup.dll" DiskId="1" Source="installer\_Setup.dll"/>
<File Id="data1.cab" Name="data1.cab" DiskId="1" Source="installer\data1.cab"/>
<File Id="data1.hdr" Name="data1.hdr" DiskId="1" Source="installer\data1.hdr"/>
<File Id="data2.cab" Name="data2.cab" DiskId="1" Source="installer\data2.cab"/>
<File Id="data2.hdr" Name="data2.hdr" DiskId="1" Source="installer\data2.hdr"/>
<File Id="ISSetup.dll" Name="ISSetup.dll" DiskId="1" Source="installer\ISSetup.dll"/>
<File Id="layout.bin" Name="layout.bin" DiskId="1" Source="installer\layout.bin"/>
<File Id="setup.exe" Name="setup.exe" DiskId="1" Source="installer\setup.exe"/>
<File Id="setup.ini" Name="setup.ini" DiskId="1" Source="installer\setup.ini"/>
</Component>
</ComponentGroup>
</Product>
</Wix>
【问题讨论】:
【参考方案1】:一些替代方案:
从文件来看,您使用 InstallShield 创建的安装程序似乎是 InstallScript 非 MSI 安装程序。您可能能够使用 InstallShield 转换器将其转换为 InstallScript MSI 安装程序。请参阅此问题和answer。
我阅读转换为 MSI 的要求与您不同。对于任何有价值的包装或转换,都应该利用 Windows Installer 管理实际安装的文件的安装。为此,如果转换不可行,您必须从头开始重写安装程序。您的方法只是将 MSI 用作捆绑包。你应该清楚你想做什么。
如果您应该选择捆绑路线,WiX 现在提供了一个名为 Burn 的引导程序/下载程序/链接程序/捆绑程序。有了它,您可以创建一个 .exe 来提取并运行您现有的安装程序。而且,如果需要,您可以创建一个 InstallShield 响应文件,以便可以静默运行现有安装。 (请参阅 InstallShield 文档。)
【讨论】:
我们不想创建 InstallShield MSI,因为在不久的将来我们希望将其更改为其他一些技术(可能是 WiX)。我们现在也不想从头开始写,因为我们没有足够的时间。我们要做的是创建 msi 包装器,它将提取 InstallShield 非 MSI 安装程序,运行它并在安装后删除其文件。 跳过复杂的自定义操作。只需编写一个应用程序,安装它和 InstallShield 设置文件,在安装结束时运行该应用程序(请参阅 WiX howto 文档)。它可以运行 InstallShield 安装程序,然后启动msiexec
以删除自己的安装并在 Windows Installer 启动时快速退出。
如果您的安装程序的活动不太依赖于目标机器的特定状态,您也许可以通过“重新打包程序”构建 MSI。一些重新打包者通过观察安装程序所做的工作并创建一个 MSI 来模仿它。这是Flexera's 的信息。但是话又说回来,如果它足够简单,重写安装程序将是最有效和最可靠的途径。无论哪种方式都需要开发和测试时间。【参考方案2】:
您可以使用 WiX Bootstrapper 嵌入现有的 InstallShield 可执行文件。无需转换。
在我们的例子中,从 InstallShield 构建的 Setup.exe 实际上有一个 MSI。 (我认为通常是这种情况)。那么你有两个选择: - 您可以提取该 MSI(谷歌“从 InstallShield 提取 MSI”)并使用 MsiPackage 将其嵌入到引导程序中 - 或者您可以使用 ExePackage 嵌入整个 Setup.exe
向 MSI 传递参数:简单
<MsiPackage Id="bla" SourceFile="path-to-msi>
<MsiProperty Name="PUBLIC_PROPERTY_IN_UPPERCASE" value="yourvalue"/>
</MsiPackage>
将参数传递给 InstallShield Setup.exe:棘手 在我们的例子中,Setup.exe 最终将参数传递给 MSI,请使用 /v"the-parameters-go-here-but-you-have-to-escape-properly" 听起来很简单,但正确转义斜杠 (\)、单引号 (')、双引号 (") 很复杂。此外,如果整个 InstallArgument 包含在 '(单引号)或 "(双引号)中,WiX 以不同方式转义 \引号)。我从单引号开始,因为它看起来更容易,但最终使用双引号。使用安装日志查看实际通过每一层的内容。
<Wix>
<Bundle>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
<bal:WixStandardBootstrapperApplication
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
LicenseUrl=""/>
</BootstrapperApplicationRef>
<!-- rumor has it Windows Installer needs the trailing slash for paths -->
<Variable Name="InstallPath" Value="C:\path\to\destination\on\target\machine\" Type="string" bal:Overridable="yes"/>
<Chain>
<MsiPackage Id="package_your_msi"
SourceFile="path-to-msi"
DisplayInternalUI="no"
ForcePerMachine="yes"
Compressed="yes"
After="package_some_other_msi">
<MsiProperty Name="TEST_PROPERTY_5" Value="5"/>
</MsiPackage>
<ExePackage Id="package_installshield_setup_exe"
SourceFile="C:\path\to\Setup.exe"
Compressed="yes"
PerMachine="yes">
<CommandLine InstallArgument="/s /v"/qn INSTALLDIR=\"[InstallPath] \" HOST_ADDRESS=[HostAddress] HOST_PORT=[HostPort] SCANNER_MODEL=[ScannerType]""
Condition="use_registry_values=1 AND other_cond=1"/>
</ExePackage>
</Bundle>
</Wix>
来源:https://social.msdn.microsoft.com/Forums/windows/en-US/1a113abd-dca1-482b-ac91-ddb0dcc5465c/is-it-possible-to-pass-commandline-arguments-to-an-installshield-executable?forum=winformssetup
http://helpnet.installshield.com/installshield22helplib/helplibrary/IHelpSetup_EXECmdLine.htm
【讨论】:
以上是关于使用 WiX 为 InstallShield 安装程序创建 msi 包装器的主要内容,如果未能解决你的问题,请参考以下文章