Как я могу найти код обновления для установленного файла MSI?
В некоторых случаях может возникнуть необходимость получить коды обновления MSI для развернутых пакетов.
Общие сценарии:
- Я взял на себя чей-то проект MSI, и мне нужно определить, какие коды обновления использовались для предыдущих версий, которые уже находятся на свободе. Это необходимо для обработки сценариев обновления. У меня нигде нет архива релизов.
- Я случайно несколько раз менял код обновления для своего пакета WiX во время разработки, и мне нужно найти все версии кода обновления "в дикой природе". Я не знал, что коды обновлений должны оставаться стабильными между версиями.
Это вопрос стиля Q/A.
Этот вопрос уже задавался в разных воплощениях, но это не дубликат. Я размещаю способ сделать это, используя основной интерфейс автоматизации MSI (или, строго говоря, WMI). Он должен быть более надежным, чем основанные на реестре подходы из предыдущих ответов. Этот ответ также пытается обобщить другие поисковые подходы.
2 ответа
Обновление кода MSI Upgrade (через PowerShell / WMI)
Удаление?:
Via Upgrade Code, Via Product Code, Via Product Name, etc...
Сценарий PowerShell, приведенный ниже, должен извлечь все связанные коды продуктов, коды обновления и названия продуктов, установленные на вашем компьютере (вывод таблицы).
Скриншот вывода (полный скрипт ниже):
Это реальные, действительные значения непосредственно из базы данных установщика Windows на данном компьютере. Нет необходимости в каком-либо преобразовании или толковании. Мы проходим через соответствующие API.
Техническое примечание!: Помните, что проверка свойств непосредственно в исходном файле MSI (таблица свойств) или исходном файле WiX может не совпадать с фактическими установленными значениями, поскольку свойства могут быть переопределены во время установки с помощью преобразований (дополнительная информация приведена ниже) - или значений свойств, указанных в команде линия. Мораль этой истории: извлекайте значения свойств непосредственно из системы, когда это возможно.
Быстрый отказ от ответственности: в редких случаях запуск сценария может вызвать самовосстановление установщика Windows. Подробнее читайте в разделе об отказе от ответственности ниже. Просто потенциальная неприятность, но прочитайте заявление об отказе от ответственности, пожалуйста.
В качестве отступления есть также однострочная команда PowerShell, которая будет извлекать только коды продуктов и коды обновления - без указания имени пакета. Это может на самом деле быть достаточно для некоторых пользователей (однако я бы порекомендовал полный скрипт ниже). Ниже приведен скриншот вывода этой однострочника. Примечание. Эта команда отображается намного быстрее, чем скрипт большего размера (поле "Значение" - это код обновления). Также обратите внимание: коды продуктов без соответствующих кодов обновления не будут отображаться, насколько я могу судить, они будут отображаться в более крупном сценарии:
gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value
Чтобы запустить полный скрипт PowerShell ниже:
- Запустите PowerShell (удерживая клавишу Windows, нажмите "R", отпустите клавишу Windows, введите "powershell" и нажмите "ОК" или нажмите "Ввод").
- Скопируйте приведенный ниже сценарий полностью, а затем просто щелкните правой кнопкой мыши в окне PowerShell.
- Это должно запустить скрипт, и для его запуска потребуется много времени.
- Пожалуйста, сообщайте о любых проблемах. Я не эксперт по PowerShell - я специалист по развертыванию, а не программист, но сценарий должен выполнить эту работу.
- Примечание о производительности: я просто получаю весь объект Win32_Product WMI
- Свойства выбора Cherry, по-видимому, делают его немного медленнее (тест VBScript).
- Я предполагаю, что нам все равно нужно собрать все ряды, а столбики сбора вишни - это просто дополнительный подъем?
- Для Win32_Property мы фильтруем как строки, так и столбцы (код обновления является лишь одним из многих типов строк). Будьте готовы к медленной работе, WMI очень медленный.
$wmipackages = Get-WmiObject -Class win32_product
$wmiproperties = gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'"
$packageinfo = New-Object System.Data.Datatable
[void]$packageinfo.Columns.Add("Name")
[void]$packageinfo.Columns.Add("ProductCode")
[void]$packageinfo.Columns.Add("UpgradeCode")
foreach ($package in $wmipackages)
{
$foundupgradecode = $false # Assume no upgrade code is found
foreach ($property in $wmiproperties) {
if ($package.IdentifyingNumber -eq $property.ProductCode) {
[void]$packageinfo.Rows.Add($package.Name,$package.IdentifyingNumber, $property.Value)
$foundupgradecode = $true
break
}
}
if(-Not ($foundupgradecode)) {
# No upgrade code found, add product code to list
[void]$packageinfo.Rows.Add($package.Name,$package.IdentifyingNumber, "")
}
}
$packageinfo | Format-table ProductCode, UpgradeCode, Name
# Enable the following line to export to CSV (good for annotation). Set full path in quotes
# $packageinfo | Export-Csv "[YourFullWriteablePath]\MsiInfo.csv"
# copy this line as well
Запуск на удаленных машинах
- Расширить сценарий выше для запуска на удаленных машинах должно быть относительно легко, но я не настроен для его проверки в настоящий момент.
- Приведенная ниже информация немного запуталась, дайте мне знать, если она не понятна или неясна.
- В реальном домене Windows это (теоретически) должно быть просто вопросом добавления удаленных машин к самим вызовам WMI (и циклического перебора списка машин - см. Макет ниже). И самое главное: вы должны использовать реальную учетную запись администратора домена для выполнения запроса. Возможно, что изменения, которые я перечислю ниже для обеспечения работы WMI в среде рабочей группы, также могут потребоваться для некоторых доменов, я не знаю (правило брандмауэра и подстройка реестра UAC). Я предполагаю, что реальная учетная запись администратора домена должна иметь права и требуемый доступ, хотя.
- На удаленные соединения в WMI влияют (как минимум) брандмауэр Windows, настройки DCOM, настройки CIMOM и контроль учетных записей (UAC) (плюс любые дополнительные факторы, не связанные с Microsoft, например, настоящие брандмауэры, сторонние программные брандмауэры, программное обеспечение безопасности различных виды и т.д...). Вот некоторые детали:
- В недоменных сетях (небольшой офис, дом и т. Д.) Вам, вероятно, придется добавлять учетные данные пользователя непосредственно в вызовы WMI, чтобы это работало. И вы, вероятно, должны иметь "настоящие права администратора" на рассматриваемых машинах, чтобы запросы выполнялись удаленно в домашней сети (рабочей группе). Я слышал, что у встроенной учетной записи администратора нет проблем с UAC, но я никогда не пробовал. На мой взгляд: не используйте этот аккаунт.
- В ходе тестирования мне пришлось (1) обновить правила брандмауэра Windows и (2) отключить фильтрацию маркеров доступа к удаленному UAC и использовать реальную локальную учетную запись администратора в удаленной системе. Обратите внимание, что я не рекомендую ни одно из этих изменений, просто сообщаю, что сработало для меня.
- Изменение 1: Брандмауэр Windows, запустите команду (cmd.exe, запустите от имени администратора):
netsh advfirewall firewall set rule group="windows management instrumentation (wmi)" new enable=yes
( источник - смотрите эту ссылку для командной строки, чтобы снова отключить это новое правило, если вы только тестируете. По сути, просто установите enable=no). См. Связанный источник для потенциально более ограничительных правил, которые также могут работать. - Изменение 2: Отключить фильтрацию маркеров доступа к удаленному UAC: необходимо установить следующее значение реестра:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\ LocalAccountTokenFilterPolicy = 1
( источник - середина страницы, вторая половина). Я установил 32-битный DWORD.
После внесения этих изменений в удаленную систему я также добавил учетные данные пользователя к каждому вызову, предложив пользователю $Cred = Get-Credential
, Есть также более продвинутые опции для определения учетных данных пользователя, как описано здесь: Передать пароль в -credential (и здесь). Чтобы выполнить тест, вот небольшой тестовый скрипт. Скопируйте все строки ниже, измените имя удаленного компьютера и вставьте в PowerShell, щелкнув правой кнопкой мыши (вам будет предложено ввести учетные данные):
$Cred = Get-Credential
gwmi -ComputerName RemoteMachineName -credential $Cred -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value
# copy this line too
Для большого сценария PowerShell, описанного выше, базовые дополнения для удаленного запуска на нескольких машинах в домене Windows могут выглядеть примерно так (я не буду обновлять вышеописанный сценарий, так как не могу проверить это должным образом). Не забудьте обновить список имен удаленных компьютеров в верхней части скрипта и запустить с учетной записью администратора домена:
# DOMAIN NETWORK: mock-up / pseudo snippet ONLY - lacks testing, provided "as is"
$ArrComputers = "Computer1", "Computer2", "Computer3"
foreach ($Computer in $ArrComputers)
{
# here we modify the WMI calls to add machine name
$wmipackages = Get-WmiObject -Class win32_product -ComputerName $Computer
$wmiproperties = gwmi -ComputerName $Computer -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'"
# the rest of the above, large script here (minus the first 2 WMI lines)
}
Чтобы адаптировать тот же машинный цикл для не доменной сети, вы можете добавить учетные данные для вызовов WMI. Примерно так (вам будет предложено ввести учетные данные для каждой машины - что может сбивать с толку). Не забудьте обновить список имен удаленных компьютеров в верхней части скрипта и использовать учетную запись с правами локального администратора в поле назначения:
# WORKGROUP NETWORK: mock-up / pseudo snippet ONLY - lacks testing, provided "as is"
$ArrComputers = "Computer1", "Computer2", "Computer3"
foreach ($Computer in $ArrComputers)
{
$Cred = Get-Credential
# here we modify the WMI calls to add machine name AND credentials
$wmipackages = Get-WmiObject -Class win32_product -ComputerName $Computer -credential $cred
$wmiproperties = gwmi -ComputerName $Computer -credential $cred -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'"
# the rest of the above, large script here (minus the first 2 WMI lines)
}
Настоящий ответ заканчивается здесь. Я полагаю, что приведенный выше более новый скрипт должен охватывать большинство сценариев использования, но я оставлю и его содержание ниже, поскольку он не устарел, просто, вероятно, менее эффективен, чем приведенный выше скрипт. Чтение этого, вероятно, будет скучным.
Приведенные ниже сценарии для получения отдельных кодов обновления, а не всего списка, могут быть интересны, если вы хотите получить один код обновления из вашего собственного приложения во время выполнения. Я оставлю этот старый контент в.
Отказ от ответственности: приведенный выше скрипт использует WMI, и когда вы обращаетесь к классу Win32_Product, он запускает проверку целостности установленных пакетов. Это довольно медленно и в особых случаях может вызвать самовосстановление MSI. Это не хорошо, если вы собираетесь на важную встречу:-). К счастью, у вас должна быть возможность отменить все инициированные самостоятельные ремонтные работы (но ваш запрос, вероятно, не будет завершен, пока вы не дадите завершить ремонт). Быстрая контекстная ссылка (для сохранности).
ИМХО: не позволяйте этому мешать вам использовать WMI - это просто раздражение. Примечание: оба подхода PowerShell и VBScript, описанные ниже, используют WMI и могут также вызвать эту проблему.
Получение кодов обновления для файлов MSI, которые не установлены
Если вам нужен код обновления для пакета MSI, который не установлен на вашем компьютере, ознакомьтесь с разделом " Извлечение кодов обновления вручную " внизу, чтобы найти несколько вариантов (по сути, посмотрите сам файл MSI или его исходный файл, используемый для скомпилируйте это).
Получить код обновления для установленных пакетов небезопасно из самого исходного установочного файла MSI или из (WiX) источников, использованных для компиляции MSI, поскольку коды обновления могут быть переопределены во время установки с помощью преобразований (подробности в тексте ниже - преобразования небольшие фрагменты базы данных, применяемые во время установки, см. эту ссылку в Symantec).
Программный поиск кодов обновления основан на WMI, и вы можете использовать PowerShell или VBScript для вызова WMI. Оба метода представлены ниже. По сути, следующий запрос WMI выполняется для получения кода обновления для указанного кода продукта:
SELECT * FROM Win32_Property WHERE Property='UpgradeCode' AND ProductCode='{YourProdGuid}'
Это один и тот же запрос, используемый как для VBScript, так и для PowerShell. Вы также можете запустить его как прямой запрос WMI, используя такой инструмент, как WMIExplorer.exe
, Очень полезный инструмент - очень рекомендуется. Я считаю, что это их сайт: https://github.com/vinaypamnani/wmie2/releases
Получить единый код обновления через PowerShell / WMI
Вместо вывода всей таблицы со всеми кодами продуктов и кодами обновления вы можете получить один код обновления для указанного кода продукта. Это хорошо, если вы пытаетесь выполнить поиск из собственного кода приложения (тогда это просто стандартный запрос WMI и не имеет ничего общего с PowerShell).
Ниже приведен единый поиск кода обновления, выполняемый с помощью PowerShell (для запуска PowerShell: нажмите и удерживайте клавишу Windows, нажмите R, отпустите клавишу Windows, введите "powershell" и нажмите OK или нажмите "Ввод"):
gwmi -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' AND ProductCode='{YourGuid}'" | Format-Table Value
Вывод должен быть примерно таким (возможно, немного сложным для чтения, я должен был использовать более крупные шрифты):
Код продукта, указанный в запросе выше, предназначен для " Windows SDK Intellidocs ". Очевидно, вы должны заменить его на свой собственный код продукта. Чтобы найти код продукта, который вам нужно передать, вы также можете использовать запрос PowerShell, как описано здесь: Как найти GUID продукта с установленной установкой MSI?
Возвращенный код обновления поступает прямо из реальной базы данных реестра установщика Windows. Не требует дальнейшей обработки, интерпретации или ручного преобразования. Это также будет правильным, даже если преобразование изменило исходный код обновления при установке MSI (подробности о проблемах преобразования приведены ниже).
Обновление, специальное уведомление: не усложняя вещи без необходимости, я считаю, что нашел ошибку в WMI, которая является очень специфической. Если исходный MSI не имеет установленного кода обновления и вы добавляете его с помощью преобразования, то WMI, похоже, вообще не сообщает код обновления. Однако: если исходный MSI имеет код обновления, и вы переопределяете его в преобразовании, WMI сообщает код обновления преобразования (что ожидается). Я определенно видел это, но мне нужно будет проверить еще один тестовый пакет. Мораль этой истории: всегда устанавливайте код обновления в MSI! Тогда вы навсегда избегаете всей проблемы. И не генерируйте его автоматически - запрограммируйте его жестко (см. "Ручной поиск кодов обновления" ниже для объяснения).
Получить одиночный код обновления с использованием VBScript / WMI (устаревший подход)
В решении VBScript, представленном ниже, нет ничего плохого - оно даже имеет некоторые преимущества по сравнению с PowerShell - несмотря на то, что VBScript уже является устаревшей технологией. Преимущества заключаются в том, что он должен работать на всех машинах, даже если платформа.NET отсутствует (или заблокирована), и на машинах, где PowerShell отсутствует (или заблокирован). Это устаревшее, но жизнеспособное решение, которое достаточно гибкое (если только VBScript также не заблокирован, но все современные версии ОС полностью поддерживают VBScript).
Чтобы максимально упростить получение кода обновления, я создал " голый VBScript ", который должен помочь. Он не был протестирован для таргетинга на удаленные компьютеры, даже если WMI должен быть в состоянии сделать это специально. Сценарий предназначен для запуска в системе, где установлен ваш загадочный MSI с неизвестным кодом обновления.
Для этого VBScript требуется вводить код продукта (диалоговое окно ввода отображается при запуске скрипта), а затем он продолжает поиск соответствующего кода обновления (если есть). Как указано выше, чтобы найти код продукта для вашего MSI, вы можете использовать этот подход: Как я могу найти GUID продукта установленной установки MSI?, Когда у вас есть код продукта (guid), вы можете запустить этот VBScript на целевом компьютере, и вы должны получить код обновления, возвращенный вам через несколько секунд. Извлечение WMI может быть очень медленным.
'
' Purpose: Barebone / minimal VBScript implementation to allow retrieval of MSI UpgradeCodes via WMI.
'
' Version: 0.2, September.2017 - Stein Åsmul.
'
' Notes:
'
' - As it stands, this script is intended to be run interactively (WScript).
' - Conversion to run via CScript should be trivial (nothing ever is...)
' - The script will ask the user to provide a valid product GUID for an installed MSI.
' - To find a valid product GUID for your system, perhaps see this SO answer: https://stackru.com/a/29937569/129130
' - The script does not RegEx anything to check for valid GUID format (this is barebone - as terse as possible,
' with as little as possible included that can break).
'
' UPDATE: for information on remote running, check "Running on remote machines" section here:
' https://stackru.com/a/46637095/129130 (firewall and registry change seems to be needed).
strComputer = "."
' Remote connections was NOT tested for this script. In principle you should just add the machine name to "strComputer" above.
' AFAIK you must have "real" admin rights on the box you try to connect to. Many users report intermittent problems running remote WMI.
' Remote connections in WMI are affected by the Windows Firewall, DCOM settings, and User Account Control (UAC).
' - Setting up a Remote WMI Connection: https://msdn.microsoft.com/en-us/library/aa822854(v=vs.85).aspx
' - Connecting to WMI on a Remote Computer: https://msdn.microsoft.com/en-us/library/aa389290(v=vs.85).aspx
' - Perhaps useful: https://social.technet.microsoft.com/Forums/lync/en-US/05205b52-0e43-4ce3-a8b8-58ec4c2edea5/wmi-generic-failure-when-accessing-win32product-remotely?forum=winserverManagement
' - Maybe it is also worth noting that I think WMI queries can be slow enough to trigger timeouts,
' and then you have the old favorite: intermittent bugs.
Set owmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' User interaction
productcode = InputBox("Please paste or type in the product code for the product whose upgrade code you want " + _
"to retrieve (not case sensitive, a blank product code will abort the script)." + vbNewLine + vbNewLine + _
"Please note that the script can take up to a minute to run due to WMI's slowness.", "UpgradeCode retrieval:")
If productcode = vbCancel Or Trim(productcode) = "" Then
WScript.Quit(0)
End If
' Run WMI call and verify that it completes successfully.
On Error Resume Next
Set upgradecode = owmi.ExecQuery("SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' AND ProductCode='" & productcode & "'")
If (Err.number <> 0) Then
MsgBox "The WMI query failed, this is a critical error - aborting.", vbCritical, "Fatal error."
WScript.Quit(2) ' Following exit code "standard" from MSI SDK automation samples
End If
On Error GoTo 0
' Report results.
Select Case upgradecode.count
Case 0
' We have to provide a separate message for this state, since some packages may not have an UpgradeCode.
' However, the product GUID could also have been misspelled.
MsgBox "No UpgradeCode was found, are you sure you entered the correct product GUID?" & vbNewLine & vbNewLine & _
"Note: It is possible for a product to NOT have an UpgradeCode.", vbInformation, "No UpgradeCode found."
Case 1
' The "default state" - should cover almost all normal packages.
' Only one upgrade code should have been retrieved, and it can be referenced by upgradecode.ItemIndex(0).Value on newer systems
' (Vista and later), but on XP this apparently does not work (never tested by me), for compatibility we use a standard For Each
' enumeration instead. Source: https://stackru.com/questions/2378723/get-first-record-from-wmi-execquery
For Each u in upgradecode
Msgbox "The Upgrade Code is: " & u.Value & vbNewLine & vbNewLine & _
"Just press CTRL + C to copy all text in this dialog (then paste to notepad or similar to extract the GUID).", _
vbInformation, "UpgradeCode found."
' Exit For
Next
Case Else
' Should never get here - let us know if you do get this message.
MsgBox "An error occurred, the query returned more than one result. There can only be one UpgradeCode. " & _
"Please report this error on Stackru", vbInformation, "Error while retrieving UpgradeCode."
End Select
Получение всех кодов обновления и кода продукта на машине
Я должен упомянуть, что у меня есть большой VBScript, который будет генерировать полный отчет HTML для всех установленных пакетов MSI на компьютере, на котором он работает. Сюда входят все коды обновления и список соответствующих кодов продуктов (коды продуктов, которые имеют один и тот же код обновления). Тем не менее, я не слишком доволен кодом (я специалист по развертыванию, а не программист). Сценарий слишком большой, слишком медленный и слишком непроверенный для использования, поэтому я создаю простой VBScript, найденный выше, чтобы выполнять поиск только для одного пакета. Этот скрипт гораздо проще протестировать и изменить для собственного использования. Я могу предоставить этот большой VBScript для тестирования, если это интересно. Он доступен только для чтения, за исключением вывода одного HTML-файла в "Мои документы". Должна быть предусмотрена возможность адаптации этого сценария для использования на удаленных компьютерах.
Существует однострочная команда PowerShell для извлечения всех кодов продуктов и соответствующих кодов обновления, но в этом выводе отсутствует название продуктов. Я включаю это здесь для полноты:
gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value
Вывод будет похож на это (поле "Значение" - это код обновления - насколько я могу судить, коды продуктов без соответствующих кодов обновления не будут отображаться):
Ручной поиск кодов обновления
В этом разделе перечислены некоторые "ручные способы" получения кодов обновления, которые не требуют кодирования или командных строк. Эти ручные подходы не рекомендуются. Я включаю их только потому, что это пытается быть " справочным ответом ". Несколько различных вариантов должны быть предоставлены. Я рекомендую использовать PowerShell или VBScript, представленные выше.
При этом коды обновления, как правило, никогда не должны меняться в зависимости от версии вашего продукта, поэтому скорее всего вы можете попробовать ту, которую вы найдете в самом файле MSI или в источнике, использованном для его компиляции, как описано ниже. Проблема, о которой уже упоминалось несколько раз, заключается в том, что преобразование может изменять коды обновления во время установки, поэтому вам нужно получить код обновления программно, если вы хотите быть уверенным, что найдете правильный код. Если вы не пытаетесь получить код обновления от MSI, который не установлен в вашей системе. Тогда вам просто нужен просмотрщик файлов MSI, как описано ниже в пункте 1.
Преобразование - это просто фрагмент базы данных с изменениями, которые применяются к исходному MSI во время установки. Это инструмент, используемый в основном для упаковки корпоративных приложений для изменения установщиков без непосредственного изменения файлов MSI. Преобразования имеют расширение .mst
, Изменение кода обновления с помощью преобразования необычно, но не случайно - особенно для корпоративной переупаковки. В редких случаях упаковщики приложений могут преднамеренно изменить руководство по обновлению, чтобы они могли доставлять свои собственные обновления к установленным пакетам (вместо того, чтобы полагаться на обновления поставщика напрямую). Редко, но я видел, как это было сделано. Является ли это хорошо или не очень спорно.
Простой, ручной способ найти коды обновления MSI:
Хотя это оскорбительно очевидно, самый простой способ найти код обновления - это открыть исходный MSI, использованный для установки продукта, и найти код обновления в таблице свойств. Все, что вам нужно, это инструмент, способный открывать файлы MSI. Вот несколько инструментов: Какой установочный продукт использовать? InstallShield, WiX, Wise, Advanced Installer и т. Д. Ваша самая быстрая ставка, вероятно, Orca, если у вас установлена Visual Studio (найдите
Orca-x86_en-us.msi
и установите его - это собственный Microsoft, официальный просмотрщик и редактор MSI) или Super Orca, если у вас не установлена Visual Studio (перейдите по ссылке выше, чтобы найти ее).Если вы разработчик, использующий WiX (или любой другой инструмент развертывания), вы можете легко найти код обновления в исходном файле WiX, который вы использовали для компиляции MSI (или источника Installshield, источника Advanced Installer или любого другого инструмента развертывания, которым вы являетесь. с помощью).
- Давайте не будем упускать из виду здесь слишком много хорошо продуманных советов, которые загромождают основную проблему, но вы, очевидно, должны жестко зашифровать код обновления в вашем источнике и никогда не генерировать его автоматически!
- Коды обновления определяют " семейства связанных продуктов " и должны оставаться стабильными в разных выпусках (версиях). В большинстве случаев он также должен оставаться стабильным во всех языковых версиях. Точная настройка зависит от требований к развертыванию.
- Если продукты должны существовать бок о бок, у вас обычно есть разные коды обновления для продуктов, которые должны сосуществовать.
- Практическое правило: сохраняйте коды обновления стабильными как можно дольше, когда это возможно. Измените их, когда требования абсолютно этого требуют.
- Подводя итог: никогда не используйте один и тот же код обновления для разных продуктов, имеющих собственный " жизненный цикл " и не имеющих реального отношения друг к другу. Они не связаны. Это так же важно, как сохранить стабильный код обновления для связанных продуктов. Подумайте о требованиях " жизненного цикла " и " семейных отношений " и " сосуществования ".
- Это было большое отступление, возвращаясь к проблеме под рукой: поиск кодов обновления.
Даже если у вас нет оригинального MSI, вы можете найти кэшированный MSI из оригинальной установки в
%SystemRoot%\Installer
папка. Здесь файлы MSI имеют загадочное шестнадцатеричное имя, но они являются просто копиями исходных файлов MSI, использованных для установки различных продуктов, - они хранятся в безопасном месте, доступном для операций изменения, восстановления и удаления. Что бы вы ни делали, не балуйтесь в этой папке. Никогда, никогда ничего не удаляй. Вы можете найти MSI, который установил ваш продукт, выбрав первый файл MSI и проверив строку состояния проводника Windows, как называется продукт для более старой версии Windows. В Windows 10 кажется, что вы можете навести указатель мыши на MSI и получить всплывающее окно с некоторыми подробностями MSI. Затем вы просто нажимаете на список, пока не найдете нужный продукт, откроете MSI и найдете код обновления в таблице свойств.Некоторые люди используют реестр для чтения кодов обновления. Как найти код обновления для установленного приложения в C#?, На мой взгляд, это не очень хороший подход, есть лучшие способы, такие как просто использование PowerShell, как описано выше. Нет необходимости во всем этом преобразовании и интерпретации упакованных идентификаторов GUID (формат GUID, используемый в базе данных реестра установщика Windows).
Это должно завершить основные "ручные методы" для быстрого получения кода обновления. Просто некоторые методы для арсенала, которые иногда достаточно хороши. Вероятно, есть еще несколько способов, которые я забыл.
Предпочитаю программные подходы, но если вы спешите и работаете без всех доступных инструментов, некоторые ручные варианты хороши. Однако некоторые из этих ручных методов требуют большего количества инструментов, чем командная строка PowerShell (вам необходим просмотрщик файлов MSI, который не всегда доступен на коробке, если вы выполняете "миссию поддержки" на чьей-либо машине). Пришло время использовать PowerShell (да, я тоже чувствую себя устаревшим).
Между прочим, файлы MSI, по сути, удаляются из баз данных SQL Server, хранящихся в виде файлов хранения с COM-структурой (формат файлов MS Office). По сути, файловая система в файле с потоками хранения различных типов.
Если вы застряли на компьютере без средства просмотра MSI, вы можете запрашивать кэшированные базы данных MSI непосредственно из PowerShell:
Чтобы удовлетворить ваши требования по использованию WMI напрямую, или для тех случаев, когда вам просто нужен одноразовый пакет без Powershell (или вам нужно использовать.bat или что-то еще), используйте wmic:
C:\WINDOWS\system32>wmic product list brief
Caption IdentifyingNumber Name Vendor Version
Sourcetree {1B05DFFD-1DB9-48CD-9265-F3976512A579} Sourcetree Atlassian 2.6.10.0
Microsoft Office Access database engine 2007 (English) {90120000-00D1-0409-0000-0000000FF1CE} Microsoft Office Access database engine 2007 (English) Microsoft Corporation 12.0.4518.1031
Office 16 Click-to-Run Extensibility Component {90160000-008C-0000-0000-0000000FF1CE} Office 16 Click-to-Run Extensibility Component
Есть несколько вариантов форматирования и вывода.