Возникли проблемы при установке драйвера устройства (упакованного в .exe) из моего установщика WiX - PullRequest
1 голос
/ 06 марта 2012

Я изо всех сил пытался создать новый установщик 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-битной, и он не работает на обоих.Еще одна причина полагать, что это не связано с разрешениями.

РЕДАКТИРОВАТЬ # 2 - я не знаю, почему я не пробовал это раньше, но я изменил с setup.exe на notepad.exe и Блокнотзапущен.Так что, очевидно, CustomAction работает.Я попробую еще раз с Process Monitor, чтобы увидеть, где он ищет файл setup.exe ... или, возможно, я просто не могу запустить установщик из другого установщика?

Ответы [ 2 ]

3 голосов
/ 06 марта 2012

Я хотел бы пересмотреть свой ответ, чтобы охватить то, что я узнал, что относится к тому, что я считаю типичным сценарием:

  • Вы хотите настроить растровые изображения в диалоговых окнах
  • Вы также можете пропустить лицензионное соглашение.
  • Вы хотите обнаружить наличие некоторой предпосылки, например .NET Framework 4.0.
  • Вы хотите написать установщик, который может установить другое программное обеспечение, например драйвер устройства, в конце процесса установки.
  • Вы хотите использовать наличие раздела реестра, чтобы сделать ранее упомянутый флажок невидимым
  • Возможно, вам потребуется включить модуль слияния, например распространяемый VC ++ 2010

Перво-наперво:

  • Вся информация в интернете. Я просто часами разбирался с информацией и пробовал что-то.
  • Будьте терпеливы и не сдавайтесь!
  • Не полагайтесь только на Google. Документация WiX (в .chm) содержит огромное количество информации. Я предлагаю вам поискать там, если не сначала.
  • Я уже говорил это: "наберись терпения и не сдавайся!"

Скелет WXS

Каждый из разделов ниже содержит только информацию, непосредственно связанную с самим собой. В самом конце ответа я опубликую скелет (частично полный) .wxs.

Обнаружение .NET Framework 4.0

Сначала вам нужно добавить ссылку на проект в WixNetFxExtension. Затем добавьте этот XML к вашему <Product> узлу: (ищите .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>

Настройка растровых изображений

Найдено в Настройка встроенных диалоговых наборов WixUI в .chm. Я только изменил следующее:

  • WixUIBannerBmp

Просто установите их под элементом <Product>:

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

Я просто создаю папку Bitmaps в своем проекте установщика WiX в Visual Studio 2010 .

Пропуск диалога EULA и установка места установки

Существует несколько встроенных способов определить внешний вид и порядок работы вашего установщика, но для тех из нас, кто ленив, вам понадобятся только WIXUI_MINIMAL и WIXUI_INSTALLDIR. Первый предназначен только для крайне ленивых (это то, что я изначально отправлял людям!), Но он не позволяет пользователю ничего делать, кроме как нажать «Да» для установки программы. Он также не скажет вам, что установка завершена. WIXUI_INSTALLDIR обеспечивает хороший баланс, ИМО. Вы получаете типичное диалоговое окно приветствия, нажимаете кнопку «Далее» в более типичных диалоговых окнах и получаете кнопку «Готово» в конце процесса.

Добавьте ссылку на проект в WixUIExtension, затем используйте следующий XML:

Установка драйвера устройства в конце

Если вы хотите установить драйвер устройства в конце вашей установки, я думаю, что самый простой способ - просто убедиться, что файл setup.exe драйвера скопирован в вашу папку установки и затем выполнен оттуда. По крайней мере, так я и сделал. Тогда вам просто нужно использовать CustomAction:

Но что, если вы хотите разрешить пользователю решать, устанавливать драйвер или нет? Затем вы делаете это:

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

и ваш <UI> узел теперь будет выглядеть так:

<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>

и затем используйте <SetProperty> вместо <Property>, как показано ранее:

Как создать условное свойство в WiX?(Почти как If-Then)

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

Модуль слияния

Наконец, что если вам нужно добавить распространяемый пакет VC ++ 2010?Я не был уверен в лучшем способе сделать это, и хотя мое приложение работало, когда я это делал (где раньше этого не было), мне показалось странным, что в разделе «Установка и удаление программ» ничего не упоминалось о том, что оно действительно установлено.,Итак, для этой части, YMMV.

Поскольку я запускаю сервер с непрерывной интеграцией (CI), на котором не обязательно установлена ​​Visual Studio 2010, я поместил файл модуля слияния в установщик WiXпроект.Я сделал папку с именем MergeModules и поместил ее туда.Файл находится в папке Program Files \ Common Files \ Merge Modules и называется Microsoft_VC100_CRT_x86.msm.Теперь поместите следующую строку в ваш <Directory> узел:

Как: установить распространяемый Visual C ++ с помощью вашего установщика (WiX на SourceForge)

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

и следующую строку в вашем <Feature> узле:

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

Skeleton WXS

Я предоставляю неполный скелет .wxs ниже.Это неполно, потому что я только предоставляю имена элементов для материала, который не связан непосредственно с этим постом.Недостающую информацию легко найти.

1 голос
/ 06 марта 2012

Могу ли я предложить другой подход. Используйте загрузчик, такой как 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 и Определение поиска с использованием переменных объясняет, как вы можете использовать расширение util для поиска в реестре. в вашем загрузчике, аналогично тому, как вы делаете это в установщике. Преимущество этого подхода состоит в том, что вы не портите свой установщик пользовательскими действиями.

...