Извлечение файлов из модуля слияния - PullRequest
8 голосов
/ 23 апреля 2010

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

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

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

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

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

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

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

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

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

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

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

orca -x theDirectory theModule.msm

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

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

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

msidb -d theModule.msm -x MergeModule.CABinet

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

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

Ответы [ 5 ]

9 голосов
/ 27 июля 2012

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

dark.exe myMergeModule.msm -x "path_to_extracted_files"

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

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

2 голосов
/ 27 июля 2012

Мне просто нужно было сделать это, создав пустую 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-файле выше.

1 голос
/ 16 декабря 2010

Библиотека классов 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()
}
1 голос
/ 10 мая 2012

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

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

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

0 голосов
/ 24 апреля 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...