Как извлечь .msi функции из командной строки? - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть .msi, который содержит некоторые файлы разработки (файлы разработки gstreamer), и я хочу извлечь некоторые функции из .msi в какую-то папку без установки из командной строки.

Я знаю, как установить некоторые функциииспользуя свойство ADDLOCAL msiexec:

msiexec /i gstreamer.msi /qb TARGETDIR=some\folder ADDLOCAL=_gstreamer_1.0_system,_gstreamer_1.0_libav

Но когда я пытаюсь извлечь файлы без установки с использованием административной установки, кажется, что свойство ADDLOCAL не работает и извлекает все файлы в пакете:

msiexec /a gstreamer.msi /qb TARGETDIR=some\folder ADDLOCAL=_gstreamer_1.0_system,_gstreamer_1.0_libav

Кто-нибудь знает, как извлечь из MSI только выбранные функции, не устанавливая их в систему?

1 Ответ

0 голосов
/ 11 декабря 2018

Краткий ответ : выполните преобразование, установите Feature Table => Level Column to 0 для функций, которые вы хотите исключить из извлечения файла.Запустите административную установку следующим образом:

msiexec.exe /a MySetup.msi TRANSFORMS=MyTransform.mst TARGETDIR=C:\MyExtractPath\

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

Уровень возможностей : в MSI есть особенность, при которой функция имеет свой уровень возможностей , установленный на0 не будут извлечены во время административной установки.Мне это кажется ошибкой (хотя это и задумано), но вы можете использовать ее, чтобы достичь того, чего вы хотите, - думаю, - но это не совсем красиво.

  1. Преобразование : Создайте преобразование, которое задает для столбца Уровень в таблице объектов значение 0 для всех объектов, которые вы не хотите извлекать.
  2. msiexec.exe : применить преобразование к MSI через командную строку следующим образом:

    msiexec.exe /a MySetup.msi TRANSFORMS=MyTransform.mst TARGETDIR=C:\MyExtractPath\
    

Инструменты : вам нужен инструмент, чтобы помочь вам сделать это преобразование.Возможно, у вас уже есть, но для других: я рекомендую Orca.exe - собственный инструмент Microsoft SDK.Тем не менее, есть ряд инструментов, которые вы можете использовать бесплатно.Большинство (я думаю) описаны здесь: Как я могу сравнить содержимое двух (или более) файлов MSI? (прокрутите вниз к списку вниз - dark.exe - это декомпилятор, а не MSIсредство просмотра - ссылка описывает сравнение файлов MSI, а не их изменение).

Orca.exe уже будет на диске (скорее всего), если у вас установлена ​​ Visual Studio ,Попробуйте поискать Orca-x86_en-us.msi - под Program Files (x86).Просто установите его и найдите Orca в меню «Пуск» (или выполните поиск).


Advanced : существует VBScript (widiffdb.vbs), ссылка на которую приведена в ответе "Сравнить MSI".Это позволяет сравнивать два файла MSI.Существует еще один VBScript, который позволяет обновлять MSI с помощью операторов SQL.Смотрите здесь: WiRunSQL.vbs .Эти сценарии вы можете найти на диске, если у вас установлен SDK, или вы можете найти их на github.com .Смотрите пример использования сценария в нижней части в этот ответ . Попробуйте, если у вас есть огромное количество Функциональных уровней, которые можно установить на 0 .Очевидно, установите все функции на 0, а затем вручную включите те, которые вам нужны, вернув их в нормальное состояние (1 или выше - зависит от MSI).

Макет : Пример кода VBScript для установки всех Feature levels на 0:

Примечание! Не запускайте это на вашем основном файле MSI. Сделайте копию!

Нет обработки ошибок в этом сценарии . Чтобы сгенерировать преобразование, см. Пример здесь (сгенерируйте преобразование на основе различий между исходным и измененным файлом MSI).

Const msiOpenDatabaseModeTransact = 1
Const msiViewModifyReplace = 4

Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase("Test.msi", msiOpenDatabaseModeTransact)

' Allow user to cancel operation
If MsgBox ("Only run this on a COPY of your MSI!" & vbNewLine & vbNewLine & "Continue?", vbYesNo + vbInformation, "Warning!") = vbNo Then
   MsgBox "Update Aborted.", vbOKOnly + vbInformation, "Aborted" 
   WScript.Quit(0)
End If

sql = "SELECT * FROM `Feature`"
Set view = database.OpenView(sql)
view.Execute()

Do
   Set record = view.Fetch()
   If record Is Nothing Then Exit Do
   record.IntegerData(6) = 0
   view.Modify msiViewModifyReplace, record
Loop

view.Close()
database.Commit()

MsgBox "Update Complete.", vbOKOnly + vbInformation, "Completed"
...