【问题标题】:Having difficulty installing a device driver (packaged in .exe) from my WiX installer从我的 WiX 安装程序安装设备驱动程序(打包在 .exe 中)时遇到困难
【发布时间】:2012-03-05 22:27:47
【问题描述】:

我一直在努力构建一个新的 WiX 安装程序,我对此非常满意,除了我还需要安装设备驱动程序。

理想情况下,我希望能够通过使用RegistrySearch 来检测此驱动程序的存在,例如

<Property Id="DRIVERINSTALLED">
    <RegistrySearch Id="DriverInstalledSearch" Root="HKLM" Key="SOFTWARE\DriverCompany\Settings" Name="InstallPath" Type="raw" />
</Property>

如果 InstallPath 注册表项有值,那么我想继续安装设备驱动程序。我还没有弄清楚那部分,但现在这是次要的,因为我什至无法每次都安装设备驱动程序。

网络上有各种各样的例子,对应于 WiX v3.5 的例子似乎遵循这种模式:

<CustomAction Id="InstallDeviceDrivers" Execute="deferred" Directory="INSTALLLOCATION" ExeCommand="setup.exe" Return="check" />
.
.
.
<InstallExecuteSequence>
    <Custom Action="InstallDeviceDrivers" After="InstallFiles" />
</InstallExecuteSequence>

每当我运行我的 msi 时,我都会收到错误消息“无法运行完成此安装所需的程序”。

setup.exe 被复制到我的 INSTALLLOCATION,当我的 msi 失败时,我通过查看该文件夹来验证这一点。

我使用了After 属性的值,但InstallFiles 似乎是正确的,因为它维护了提升的用户权限。我最初尝试过InstallFinalize,但失败了,我认为它没有以提升的权限运行。问题是,我尝试过的其他操作都不起作用。

然后我使用msiexec /i installer.msi /l*v install.log 运行我的安装程序并查看输出文件。这就是我看到一个更具体的错误的地方:

MSI (s) (74:CC) [14:06:10:098]: Executing op: ActionStart(Name=InstallDeviceDrivers,,)
Action 14:06:10: InstallDeviceDrivers. 
MSI (s) (74:CC) [14:06:10:098]: Executing op: CustomActionSchedule(Action=InstallDeviceDrivers,ActionType=1058,Source=C:\Program Files\MyCompany\MyProduct\,Target=setup.exe,)
MSI (s) (74:CC) [14:06:10:108]: Note: 1: 1721 2: InstallDeviceDrivers 3: C:\Program Files\MyCompany\MyProduct\ 4: setup.exe 
MSI (s) (74:CC) [14:06:10:108]: Note: 1: 2205 2:  3: Error 
MSI (s) (74:CC) [14:06:10:108]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1721 
Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: InstallDeviceDrivers, location: C:\Program Files\MyCompany\MyProduct\, command: setup.exe 
MSI (s) (74:CC) [14:06:11:800]: Note: 1: 2205 2:  3: Error 
MSI (s) (74:CC) [14:06:11:800]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1709 
MSI (s) (74:CC) [14:06:11:800]: Product: Installer -- Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: InstallDeviceDrivers, location: C:\Program Files\MyCompany\MyProduct\, command: setup.exe 

根据一些搜索,听起来我只需要以管理员身份运行,但我的安装程序已经触发 UAC...果然,从提升的命令提示符运行安装程序没有帮助。

谁能推荐我下一步的操作来调试它?如果您还有关于如何根据注册表项的存在有条件地安装的信息,那也很棒。谢谢!

编辑——我已经在 Windows XP 32 位和 Windows 7 32 位上运行了我的安装程序,但在两者上都失败了。另一个相信它与权限无关的理由。

EDIT #2 -- 我不知道为什么我之前没有尝试过,但是我从 setup.exe 更改为 notepad.exe,然后记事本启动了。所以显然 CustomAction 有效。我将再次尝试使用 Process Monitor 来查看它在哪里寻找 setup.exe... 或者我只是无法从另一个安装程序中运行安装程序?

【问题讨论】:

    标签: wix windows-installer wix3.5 custom-action


    【解决方案1】:

    我想修改我的答案,以涵盖与我认为的典型场景相关的知识:

    • 您想要自定义对话框中的位图
    • 您可能还想跳过许可协议。
    • 您想要检测是否存在某些先决条件,例如 .NET Framework 4.0。
    • 您想编写一个安装程序,以便在安装过程结束时安装一些其他软件,例如设备驱动程序。
    • 您希望使用注册表项的存在来使前面提到的复选框不可见
    • 您可能需要包含一个合并模块,例如 VC++ 2010 可再发行组件

    第一件事:

    • 所有信息都在互联网上。我只是花了几个小时浏览信息并尝试了一些东西。
    • 要有耐心,不要放弃!
    • 不要只依赖 Google。 WiX 文档(在 .chm 中)包含大量信息。我建议你也去那里搜索,如果不是先搜索的话。
    • 我是否已经说过“耐心点,不要放弃!”

    骨架 WXS

    以下每个部分仅包含与其自身直接相关的信息。在答案的最后,我会发布一个骨架(部分完成).wxs。

    检测 .NET Framework 4.0

    首先,您需要添加对 WixNetFxExtension 的项目引用。然后将此 XML 添加到您的 &lt;Product&gt; 节点:(在 .chm 中搜索“.NET”)

    <PropertyRef Id="NETFRAMEWORK40FULL" />
    <Condition Message ="This application requires .NET Framework 4.0. Please install the .NET Framework and then run this installer again.">
        <![CDATA[Installed OR NETFRAMEWORK40FULL]]>
    </Condition>
    

    自定义位图

    在 .chm 中的自定义内置 WixUI 对话框集中找到。我只更改了以下内容:

    • WixUIBannerBmp
    • WixUIDialogBmp

    只需将它们设置在&lt;Product&gt; 元素下即可:

    <WixVariable Id="WixUIBannerBmp" Value="$(var.ProjectDir)\Bitmaps\mybanner.bmp"/>
    <WixVariable Id="WixUIDialogBmp" Value="$(var.ProjectDir)\Bitmaps\mydialog.bmp"/>
    

    我只是在 Visual Studio 2010 的 WiX 安装程序项目中创建了一个 Bitmaps 文件夹。

    跳过 EULA 对话框并设置安装位置

    有几种内置方法可以定义安装程序的外观和流程,但对于我们这些懒惰的人来说,您只会关心WIXUI_MINIMALWIXUI_INSTALLDIR。前者仅适用于极度懒惰的人(这是我最初发送给人们的!),但它不允许用户做任何事情,只能单击“是”安装程序。它也不会告诉您安装已完成。 WIXUI_INSTALLDIR 取得了很好的平衡,IMO。您会看到典型的欢迎对话框,在更多典型对话框中单击“下一步”,然后在流程结束时获得“完成”按钮。

    添加对 WixUIExtension 的项目引用,然后使用以下 XML:

    最后安装设备驱动

    如果您想在安装结束时安装设备驱动程序,我认为最简单的方法是确保将驱动程序的 setup.exe 复制到您的安装位置,然后从那里执行。至少,这就是我所做的。然后你只需要使用CustomAction:

    但是如果您想让用户决定是否安装驱动程序呢?然后你这样做:

    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Install device drivers when the installer exits." />
    

    你的&lt;UI&gt; 节点现在看起来像这样:

    <UI>
        <UIRef Id="WixUI_InstallDir" />
        <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="2">1</Publish>
        <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">1</Publish>
        <Publish Dialog="ExitDialog" Control="Finish" Order="1" Event="DoAction" Value="InstallDeviceDrivers">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
        <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    </UI>
    

    上面添加的逻辑只是检查复选框是否被选中,并且“未安装”是为了确保此操作仅在安装程序正在安装您的应用程序时运行,而不是卸载。

    使用注册表项控制复选框的可用性

    只需将以下 XML 添加到 Product

    <Property Id="DRIVERINSTALLED">
        <RegistrySearch Id="DriverInstalledSearch" Root="HKLM" Key="SOFTWARE\DriverCompany\Settings" Name="SomeRegistryKeyThatMustBePresentIfInstalled" Type="raw" />
    </Property>
    

    然后使用&lt;SetProperty&gt;而不是&lt;Property&gt;,如前所示:

    How do I create a conditional property in WiX? (Almost like an If-Then)

    <SetProperty Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Install device drivers when the installer exits." After="CostFinalize">
        <![CDATA[NOT DRIVERINSTALLED]]>
    </SetProperty>
    

    合并模块

    最后,如果您需要添加 VC++ 2010 Redistributable 包怎么办?我不确定执行此操作的最佳方法,尽管我的应用程序在我执行此操作时可以正常工作(以前没有),但我发现添加/删除程序没有提及实际安装的任何内容很奇怪.所以对于这一部分,YMMV。

    由于我运行的continuous integration (CI) 服务器不一定安装了 Visual Studio 2010,因此我将合并模块文件放入我的 WiX 安装程序项目中。我创建了一个名为 MergeModules 的文件夹并将其放在那里。该文件位于 Program Files\Common Files\Merge Modules 中,名为 Microsoft_VC100_CRT_x86.msm。现在将以下行放入您的 &lt;Directory&gt; 节点中:

    How To: Install the Visual C++ Redistributable with your installer(SourceForge 上的 WiX)

    <Merge Id="VCRedist" SourceFile="$(var.ProjectDir)\MergeModules\Microsoft_VC100_CRT_x86.msm" DiskId="1" Language="0"/>
    

    以及&lt;Feature&gt; 节点中的以下行:

    <Feature Id="VCRedist" Title="Visual C++ 10.0 Runtime" AllowAdvertise="no" Display="hidden" Level="1">
        <MergeRef Id="VCRedist"/>
    </Feature>
    

    骨架 WXS

    我在下面提供了一个不完整骨架.wxs。它不完整,因为我只提供与这篇文章没有直接关联的东西的元素名称。丢失的信息很容易找到。

    【讨论】:

      【解决方案2】:

      我可以建议一种不同的方法。使用引导程序(例如 WiX Burn)检查驱动程序是否已安装,如果未安装,请将其作为先决条件进行安装。然后启动您的MSI 安装程序。 WiX 捆绑包看起来像:

      <Fragment>
          <util:RegistrySearch 
              Variable="DriverInstalled"
              Root="HKLM,SOFTWARE\Microsoft\MyProduct\[UniqueId]\Setup"
              Key="InstallPath"
              Result="Exists" />
      
          <PackageGroup Id="DriverPackage">
            <ExePackage 
              SourceFile="Path_To_Driver\Setup.exe"
              InstallCondition="InstallPath" />
          </PackageGroup>
          <PackageGroup Id="MainMsi">
            <MsiPackage 
              SourceFile="Path_To_Msi\Installer.msi"
              After="DriverPackage" />
          </PackageGroup>
      </Fragment>
      

      注意:我没有测试上述内容,但是如果您走那条路,那应该可以帮助您入门。如果您有兴趣,我建议您查找 WiX bootstrapper bundlesDefine Searches Using Variables 解释如何使用 util 扩展在引导程序中搜索注册表,类似于在安装程序。这种方法的好处是不会用自定义操作搞砸您的安装程序。

      【讨论】:

      • 我很欣赏这个建议,今天会用它,谢谢!
      • Wix 3.6 正式发布后我会重新审核
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多