Как включить KB2670838 в установщик с InstallShield 2013?

Я использую InstallShield 2013 для создания базового установщика MSI для приложения, для которого требуется обновление платформы Windows KB2670838.

Для.NET-фреймворков и других требований я выбираю их в InstallShield в разделе Redistributables. KB2670838 не доступен.

Если я загружаю KB2670838 от Microsoft, я получаю .msu файл. Можно ли это как-то включить в установщик, чтобы он автоматически устанавливался при необходимости? Если нет, есть ли способ остановить установку и сообщить пользователю, что "KB2670838 требуется, но не установлен. Получить его здесь..."?

5 ответов

Решение

@Glytzhkof Хороший вопрос. Так как же заставить InstallShield прервать работу и дать пользователю приятное сообщение, чтобы он знал, что делать? - Shoelzer 1 час назад

Тогда я просто добавлю новый ответ - слишком долго, чтобы писать в комментарии.

  • Найдите сведения о файле, которые необходимо отсканировать, в разделе "Дополнительная информация: информация о файле" в этой статье kdb: http://support.microsoft.com/kb/2670838/en
  • Выберите несколько файлов для поиска и добавьте их в поиске файлов в Installshield (см. Скриншот ниже). Вы указываете свойство для каждого файла (FILE1FOUND, FILE2FOUND, FILE3FOUND и т. Д.), И, если поиск соответствует деталям файла (версия, размер, дата и т. Д.), Для свойства устанавливается полный путь к файлу. файл. В противном случае свойство не определено или имеет значение по умолчанию (на снимке экрана показан предварительно заданный поиск, а не поиск по файлу, но вы поняли идею).
  • Наконец, вы добавляете записи LaunchCondition для каждого файла, чтобы убедиться, что все файлы, которые вы выбрали для проверки, имеют правильную версию или выше. Я предполагаю, что это в Предварительных условиях или подобном - я не могу вспомнить. Откройте скомпилированный MSI и убедитесь, что он выглядит как таблица LaunchConditon.

Installshield's Search View

Для записи: (не является частью вышеупомянутого предложения)

Лично я выступаю за кодирование одного скрипта для сложной логики, подобного этой, чтобы гарантировать, что логика может быть проверена в целом и критически протестирована в целом вне файла MSI. Также полезно добавлять комментарии к такому коду, чтобы объяснить, что проверяет скрипт и почему (помогает корпоративному развертыванию). Скрипт может быть запущен через десятки тестов на машине напрямую без перекомпиляции MSI. Это может сэкономить много времени, если логика сложна. Если вы пишете скомпилированную dll, вы можете показать окно сообщения и присоединить отладчик Visual Studio к процессу msiexec.exe (клиент или сервер в зависимости от контекста, в котором выполняется ваше настраиваемое действие) и пошагово пройти по коду, встроенному в MSI., но это, кажется, выходит за рамки вашего сценария. Просто хочу упомянуть это для других людей, которые могли бы прочитать это. Также проверьте Stefan Kruger на installsite.com для получения дополнительной информации об отладке сложных настроек, подобной этой.

Важно отметить, что использование сценариев обычно не рекомендуется для сценариев, в которых сценарий вносит изменения в систему - если есть встроенный способ MSI для достижения того же результата. Причина этого заключается в том, что для сценария, который вносит изменения в машину, потребуется отдельная операция отката, чтобы MSI следовал передовым методам. Это может быть впечатляющий объем работы и сложность, чтобы получить право. Приведенный выше скрипт будет проверять только системные условия, поэтому нет необходимости в поддержке отката.

Список " Установка и удаление программ" в реестре может помочь вам получить общее представление о том, что установлено:

  • HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall

Кажется, что это не дает полный список того, что установлено, хотя: http://social.technet.microsoft.com/Forums/windows/en-US/d913471a-d7fb-448d-869b-da9025dcc943/where-does-addremove-programs-get-its-information-from-in-the-registry?forum=w7itprogeneral

Другим способом может быть использование информации о файле из статьи базы знаний: http://support.microsoft.com/kb/2670838/en (Дополнительная информация: информация о файле) и использование функции AppSearch / LaunchCondition компании WIX / MSI. Это должно сработать, хотя я нахожу синтаксис немного нелогичным.

Другой подход - написать пользовательское действие и объединить эти два источника (добавить / удалить запись и информацию о файле). Такое настраиваемое действие не вносит никаких изменений в систему и, следовательно, является менее проблематичным, чем другие настраиваемые действия, которые вызывают проблемы отката. Мне легче тестировать и поддерживать настраиваемое действие, если в какой-то момент необходимы дополнительные предпосылки. Это вопрос вкуса, хотя. Я просто нахожу, что проще запустить необходимый сценарий для выбора файлов, чтобы проверить, правильно ли он их идентифицирует и выполнить, как ожидалось, чем продолжать запуск файла MSI для каждого теста.

Вот аналогичный вопрос с некоторыми указателями от superuser.com: https://superuser.com/questions/521175/determine-if-windows-hotfix-has-been-applied

И еще одна ссылка на serverfault.com (сайт системного администрирования). Хороший подход с использованием PowerShell, который, безусловно, можно перенести на пользовательское действие: https://serverfault.com/questions/312778/determine-if-user-has-hotfix-981889-installed

Еще больше материала serverfault.com, включающего update.exe, WMI и скрипт Powershell для просмотра всех установленных исправлений: https://serverfault.com/questions/263847/how-can-i-query-my-system-via-command-line-to-see-if-a-kb-patch-is-installed. Рекомендуем прочитать. Microsoft: http://technet.microsoft.com/en-us/library/hh849836.aspx

PSInfo, похоже, может показать установленные исправления: http://technet.microsoft.com/en-us/sysinternals/bb897550

В InstallShield вы обычно должны доставлять такого рода обновления в качестве обязательного компонента (Инструменты> Редактор обязательных компонентов) или в виде пакета, включенного в комплект (ссылка [SystemFolder]wusa.exe установить .msu файл). В обоих случаях это позволяет распространять распространяемую установку логически отдельно от установки вашего пакета, предоставляя пользователям единый опыт установки.

Глитжкоф упоминает несколько действительно хороших моментов о том, как определить, было ли установлено обновление. Вы захотите включить их в свои условия (в пакете предварительных требований или пакета), а также в обнаружение обновления или его отсутствия в вашем .msi пакет, поэтому он может прервать работу, если требуемое обновление не было установлено к .msi запущен.

Позвольте мне попытаться добавить ответ эталонного стиля, так как мой другой ответ немного мягче, если не сказать больше - я оставлю его, поскольку он содержит обсуждение MSI. См. Рекомендацию MSI в средней части ниже:

WMI:

wmic qfe where "HotfixID = 'KB973687'"

PowerShell: (просто получить исправление для полного списка)

get-hotfix | findstr "981889"

SystemInfo (удалить аргументы для формата списка):

systeminfo /fo csv

PSInfo (кажется, не перечисляет все на всех машинах, и может работать некорректно):

PSinfo -h

Реестр (видимо, не полный список исправлений):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

Для использования настраиваемых действий MSI я бы фактически использовал настраиваемое действие, которое проверяет версии файлов, как описано в моем другом ответе. Очень надежный и учитывает, что исправление может устареть, пока файлы еще не обновлены.


Рекомендации:

Возникла та же проблема и была решена путем добавления необходимого сценария PowerShell и командного файла для его выполнения.

Файл pre.ps1 выглядит примерно так:

function TestConnection
{
    Test-Connection -ComputerName "8.8.8.8" -Quiet
}

get-hotfix -id KB2670838
if(!$?){
    #SourceURI = "https://download.microsoft.com/download/1/4/9/14936FE9-4D16-4019-A093-5E00182609EB/Windows6.1-KB2670838-x64.msu";
    #$FileName = $SourceURI .Split('/')[-1]
    #$BinPath = Join-Path $DownloadPath -ChildPath $FileName
    Invoke-Webrequest -Uri $SourceURI -OutFile $BinPath
    #Start-Process -FilePath $BinPath -ArgumentList "/q /norestart" -Wait -NoNewWindow
}

файл pre.cmd выглядит примерно так:

@echo off
::set PS_FILE=%~dp0Prerequisite.ps1
set PS_FILE=%~dpn0.ps1
set PS_EXEC_PATH=%SystemRoot%\sysnative\WindowsPowerShell\v1.0\
set PS_EXEC_PATH=%SystemRoot%\System32\WindowsPowerShell\v1.0\
::set PS_EXEC_PATH=%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\
set PS_EXEC_PATH=
set PS_EXEC=%PS_EXEC_PATH%powershell.exe
echo %PS_EXEC%
echo %PS_FILE%

::%PS_EXEC% -file %PS_FILE% set-executionpolicy remotesigned
::%PS_EXEC% -NoProfile -ExecutionPolicy Bypass -Command "& '%PS_FILE%'"
::This is with admin rights
%PS_EXEC% -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%PS_FILE%""' -Verb RunAs}"

::pause
Другие вопросы по тегам