Извлечение файлов из модуля слияния

Все, что мне нужно, это инструмент командной строки, который может извлекать файлы из модуля слияния (.msm) на диск. Другими словами, мне нужна такая же функциональность «административной установки», которая возможна для MSI:

msiexec / a myProduct.msi TARGETDIR = "C: \ myInstallation" / qn

Вышеупомянутое работает только с msi (насколько я могу судить). Итак, чтобы получить тот же эффект для модуля слияния, я пробую msidb.exe и orca.exe. В документации для orca говорится:

Многие параметры модуля слияния можно указать из командной строки ...

Извлечение файлов из модуля слияния

Orca поддерживает три различных метода извлечения файлов, содержащихся в модуле слияния. Orca может извлекать отдельный CAB-файл, извлекать файлы в дерево модулей и извлекать файлы в исходное изображение после того, как оно было объединено в целевую базу данных ...

Извлечения файлов

Чтобы извлечь отдельные файлы из модуля слияния, используйте

... -x ... в командной строке, где указан желаемый путь к новому дереву каталогов.

Указанный путь используется как корневой путь для извлеченных файлов. Все файлы извлекаются из встроенного в модуль CAB-файла и помещаются по указанному пути. Структура каталогов для извлеченных файлов основана на дереве каталогов модуля слияния.

Это похоже на то, что мне нужно. Но когда я пробую это сделать, orca просто открывает редактор (с информацией о msm, которую я указал) , а затем ничего не делает. Я пробовал разные командные строки, обычно начиная с этого:

orca -x каталог theModule.msm

Я использую «theDirectory» как любую пустую папку, которую хочу. Как я уже сказал - ничего не произошло.

Затем я попробовал msidb, где несколько попыток выглядели так:

msidb -d theModule.msm -w {хранилище}

msidb -d theModule.msm -x MergeModule.CABinet

В первом случае я не знаю, что ставить за {хранилище}. Во втором случае оказывается, что буквальная строка «MergeModule.CABinet» необходима (это зарезервированное имя). Однако извлеченный кабинет не сохраняет иерархию файлов или «нормальные» имена файлов; поэтому я не могу использовать его в своих целях.

Может кто-нибудь объяснить, что я делаю не так с параметрами командной строки? Есть ли другой инструмент, который может это сделать?


person Brent Arias    schedule 23.04.2010    source источник
comment
Хит Стюарт написал инструмент, который извлекает файлы из исправлений (MSP). Будет ли это работать на МСМ? Понятия не имею, но попробовать стоит: blogs.msdn .com / heaths / archive / 2006/04/07 / 571138.aspx   -  person Matt Greer    schedule 24.04.2010


Ответы (5)


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

dark.exe myMergeModule.msm -x "path_to_extracted_files"

Файлы будут извлечены по пути, указанному в параметре -x.

Примечание. Файлы будут извлечены с использованием имен, указанных в таблице файлов базы данных установки, которые могут не совпадать с именами файлов, используемыми при фактической установке файлов. Если вам нужно извлечь файлы, используя фактические имена файлов, см. Мой другой ответ на этот вопрос: Извлечение файлов из модуля слияния

person BryanJ    schedule 27.07.2012
comment
Этот синтаксис кажется неправильным для темной версии 3.5? Я заставил этот пример работать: dark.exe -x c: \ msm \ extract c: \ msm \ myMergeModule.msm Параметр после -x - это путь для извлечения (темная версия 3.5). - person AH.; 11.06.2015

Мне просто нужно было сделать это, создав пустой msi, а затем использовать Orca, чтобы попытаться объединить модуль в мой msi, а затем извлечь файлы.

  1. Создайте пустой .msi-файл. Я использовал WiX 3.6 для создания .msi, и ниже приведен минимальный исходный код. Я назвал его «blank.msi».

    <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Product Id="*" Name="blank" Language="1033" Version="1.0.0.0" Manufacturer="blank" UpgradeCode="298878d0-5e7b-4b2e-84f9-45bb66541b10">
            <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
    
            <MediaTemplate />
    
            <Directory Id="TARGETDIR" Name="SourceDir">
                <Directory Id="ProgramFilesFolder"/>
            </Directory>
    
            <ComponentGroup Id="ProductComponents" Directory="ProgramFilesFolder" />
    
            <Feature Id="ProductFeature" Title="blank" Level="1">
                <ComponentGroupRef Id="ProductComponents" />
            </Feature>
         </Product>
    </Wix>
    
  2. Используйте Orca для извлеките файлы из модуля слияния.

    orca -m "myModule.msm" -f ProductFeature -x .\xdir blank.msi
    

Файлы будут извлечены в каталог, указанный параметром -x (в данном случае . \ Xdir).

Обратите внимание, что значение параметра -f «ProductFeature» соответствует имени функции, указанной в msi-файле выше.

person BryanJ    schedule 27.07.2012
comment
К сожалению, в xml не включено, как включить узлы Merge и MergeRef - person Gmt; 15.10.2015
comment
@Gmt приведенный выше xml используется только для создания пустого msi. Включение модели слияния происходит в вызове orca. -m объединяет модуль слияния, -f связывает его с функцией, а -x затем извлекает файлы. - person BryanJ; 15.10.2015

Библиотека классов DeploymentToolsFoundation в WiX имеет класс InstallPackage с методом ExtractFiles (), который должен делать именно то, что вы хотите. , но не работает для модулей слияния. Похоже, это ошибка.

Следующий сценарий PowerShell, который использует DTF для доступа к CAB в модуле слияния, должен делать то, что вы хотите. Приносим извинения, если сценарий немного шаткий, я новичок в PowerShell.

[Reflection.Assembly]::LoadFrom("[InsertPath]\Microsoft.Deployment.WindowsInstaller.dll")

function ExtractMSM([string]$file, [string]$targetDir)
{
    write-host "Extracting files from merge module: "$file

    if(![IO.Directory]::Exists($targetDir)) { new-item -type directory -path $targetDir }

    $cabFile = join-path $targetDir "temp.cab"
    if([IO.File]::Exists($cabFile)) { remove-item $cabFile }

    $db = new-object Microsoft.Deployment.WindowsInstaller.DataBase($file, [Microsoft.Deployment.WindowsInstaller.DataBaseOpenMode]::ReadOnly)
    $view = $db.OpenView("SELECT `Name`,`Data` FROM _Streams WHERE `Name`= 'MergeModule.CABinet'")
    $view.Execute()
    $record = $view.Fetch()
    $record.GetStream(2, $cabFile)
    $view.Dispose()

    expand -F:* $cabFile $targetDir

    remove-item $cabFile

    $extractedFiles = get-childitem $targetDir
    $hashFiles = @{}
    foreach($extracted in $extractedFiles)
    {
        try
        {
            $longName = $db.ExecuteScalar("SELECT `FileName` FROM `File` WHERE `File`='{0}'", $extracted.Name) 
        }
        catch 
        {
            write-host "$($extracted.Name) is not in the MSM file"
        }

        if($longName)
        {
            $longName = $LongName.SubString($LongName.IndexOf("|") + 1)
            Write-host $longName

            #There are duplicates in the 
            if($hashFiles.Contains($longName))
            {
                write-host "Removing duplicate of $longName"
                remove-item $extracted.FullName
            }
            else
            {
                write-host "Rename $($extracted.Name) to $longName"
                $hashFiles[$longName] = $extracted
                $targetFilePath = join-path $targetDir $longName
                if([IO.File]::Exists($targetFilePath)) {remove-item $targetFilePath}
                rename-item $extracted.FullName -NewName $longName    
            }
        }
    }
    $db.Dispose()
}
person user24770    schedule 16.12.2010

У меня была похожая проблема, но я подошел к ней с другой стороны.

Я установил InstallSheild Express из более ранней версии Visual Studio, создал новый проект, но добавил только тот файл MSM, который мне нужен.

После компиляции и запуска моей новой установки я смог получить файлы, содержащиеся в файле MSM.

person Eddie Mason    schedule 10.05.2012

MSI2XML

person Kyle Alons    schedule 23.04.2010
comment
По вашему предложению я использовал его: msi2xml -b streams -c files installation.msi ... и он имел в основном тот же результат, что и выполнение: msidb -d theModule.msm -x MergeModule.CABinet и разверните MergeModule.CABinet Итак, я ' м все еще застрял. Если бы только административная установка msiexec.exe могла работать с файлом msm. Это в основном то поведение при извлечении файлов, которое я ищу. - person Brent Arias; 24.04.2010