10
votes

Extraire des fichiers du module de fusion

Tout ce que je veux, c'est un outil de ligne de commande pouvant extraire des fichiers à partir d'un module de fusion (.msm) sur le disque. Dit différemment, je veux la même fonctionnalité "administrative d'installation" possible pour un MSI:

MSIEXEC / A myProduct.msi cibledir = "c: \ myInstallation" / qn

Ce qui précède ne fonctionne que sur un MSI (près que je puisse dire). Donc, pour obtenir le même effet pour un module de fusion, j'essaie MSIDEB.EXE et ORCA.EXE la documentation pour l'ORCA:

De nombreuses options de module de fusion peuvent être spécifié à partir de la ligne de commande ...

Extraire des fichiers d'un module de fusion

orca prend en charge trois méthodes différentes pour extraire des fichiers contenus dans un Module de fusion. Orca peut extraire le fichier de cabine individuel, extraire les fichiers dans un arbre de module et extraire le fichiers dans une image source une fois qu'il a été fusionné dans une base de données cible ...

Extraction de fichiers

Pour extraire les fichiers individuels d'un Module de fusion, utilisez le

... -x ... option sur le ligne de commande, où est le Chemin souhaité sur le nouveau répertoire Arbre.

Le chemin spécifié est utilisé comme racine chemin pour les fichiers extraits. Tous Les fichiers sont extraits du fichier de taxi intégré dans le module et placé dans le chemin spécifié. Le répertoire Layout pour les fichiers extraits est Basé sur l'arborescence de la répertoire de la Module de fusion.

Cela ressemble à ce dont j'ai besoin. Mais quand je l'essaie, ORCA ouvre simplement un éditeur (avec des informations sur le MSM que j'ai spécifié) et ne fait rien . J'ai essayé une variété de lignes de commande, en commençant généralement par:

orca -x thedirectory themodule.msm

J'utilise "TheDirectory" comme quel que soit le dossier vide que je veux. Comme je l'ai dit - ça n'a rien fait.

Puis j'ai essayé MSIDEB, où quelques tentatives que j'ai faites ressemblent à ceci:

msidb -d themodudule.msm -w {stockage}

msidb -d themodudule.msm -x mergemodule.cabinet

Dans le premier cas, je ne sais pas quoi mettre pour {stockage}. Dans le second cas, il s'avère que la chaîne littérale "mergemodule.cabinet" est nécessaire (il s'agit d'un nom réservé). Cependant, l'armoire extraite ne préserve pas la hiérarchie de fichiers ou les noms de fichiers «normaux»; Donc, je ne peux pas l'utiliser à mes fins.

Quelqu'un peut-il expliquer ce que je fais mal avec les options de ligne de commande? Y a-t-il un autre outil qui peut faire cela?


1 commentaires

Heath Stewart a écrit un outil qui extrait des fichiers de correctifs (MSPS). Cela fonctionnera-t-il sur des MSMS? Je n'ai aucune idée, mais ça vaut la peine d'être coupé: blogs.msdn .Com / Heaths / Archive / 2006/04/07 / 571138.aspx


5 Réponses :


0
votes

1 commentaires

Sur votre suggestion, je l'ai utilisé: "MSI2XML -B -B Streams -C Files -C Installation.msi" ... et il y avait fondamentalement le même résultat que faire: "msidb -d themodule.msm -x mergemodule.cabinet" et "expand mergemodule .Cabinet "Alors je suis toujours coincé. Si seulement l'installation administrative de Msiexec.exe fonctionnerait sur un fichier MSM. C'est fondamentalement le comportement "extraction de fichiers" que je recherche.



1
votes

La bibliothèque de classes de déploiementToolsfoundation dans wix , a une classe d'installation avec une méthode extraitfiles () qui devrait faire juste Ce que vous voulez, mais échoue pour des modules de fusion. Ceci semble être un Bug .

Le script PowerShell suivant , qui utilise DTF pour accéder à la cabine dans la mergemodule, devrait faire ce que vous voulez. Toutes mes excuses si le script est un peu bonky, je suis nouveau à PowerShell. P>

[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()
}


0 commentaires

1
votes

J'ai eu un problème similaire, mais je suis allé à elle d'une direction différente.

J'ai installé InstallShed Express fourni avec une version antérieure de Visual Studio, créé un nouveau projet, mais je n'ai ajouté que le fichier MSM que j'ai demandé.

Après avoir compilé et exécuté ma nouvelle installation, j'ai pu extraire les fichiers que le fichier MSM contenait.


0 commentaires

5
votes

Je devais juste faire cela en créant un MSI vierge, puis utilisez Orca pour tenter de fusionner le module dans mon MSI, puis d'extraire les fichiers.

  1. créer un vide .msi. J'ai utilisé Wix 3.6 pour créer le fichier .msi et ci-dessous est la source minimale. Je l'ai nommé "blank.msi". XXX

  2. Utilisez Orca pour extraire les fichiers du module de fusion. XXX

    Les fichiers seront extraits dans le répertoire spécifié par le paramètre -x (dans ce cas . \ xdir ).

    Notez que la valeur de la valeur -f paramètre " produitFeature " correspond au nom de la fonctionnalité spécifiée dans le fichier MSI ci-dessus.


2 commentaires

Malheureusement, dans le XML n'est pas inclus, comment incluez-vous la fusion et les nœuds de Mergeref


@Gmt Le XML ci-dessus n'est utilisé que pour créer un MSI vierge. Y compris le modèle de fusion se produit dans l'appel à l'ORCA. -M fusionne le module de fusion, -f l'associe avec une fonctionnalité et -x puis extrait les fichiers.



12
votes

Vous pouvez utiliser l'outil Decompiler inclus avec WIX (appelé sombre ) pour décompiler le module de fusion et extraire les fichiers: xxx

Les fichiers seront extracés à le chemin spécifié dans le paramètre -x.

Remarque: Les fichiers seront extraits à l'aide des noms spécifiés dans le tableau de fichiers de la base de données d'installation, ce qui peut ne pas être le fichier. noms utilisés lorsque les fichiers sont réellement installés. Si vous avez besoin d'extraire les fichiers à l'aide des noms de fichiers réels, consultez mon autre réponse à cette question: Extraire des fichiers du module de fusion


1 commentaires

Cette syntaxe ne semble pas être correcte pour la version 3.5 sombre? J'ai reçu cet exemple pour travailler: dark.exe -x C: \ msm \ extrait c: \ msm \ mymergemodule.msm Le paramètre après "-x" est le chemin d'extrait pour extraire (la version 3.5 sombre).