Installation 从合并模块提取文件

Installation 从合并模块提取文件,installation,windows-installer,extract,merge-module,orca,Installation,Windows Installer,Extract,Merge Module,Orca,我想要的只是一个命令行工具,它可以将文件从合并模块(.msm)提取到磁盘上。换言之,我希望MSI具有相同的“管理安装”功能: msiexec/a myProduct.msi TARGETDIR=“C:\myInstallation”/qn 以上仅适用于msi(我可以说是接近的)。因此,为了获得与合并模块相同的效果,我尝试使用msidb.exe和orca.exe。orca的文档说明: 可以使用许多合并模块选项 从命令行指定 从合并模块提取文件 Orca支持三种不同的方法 用于提取文件中包含的文件

我想要的只是一个命令行工具,它可以将文件从合并模块(.msm)提取到磁盘上。换言之,我希望MSI具有相同的“管理安装”功能:

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

以上仅适用于msi(我可以说是接近的)。因此,为了获得与合并模块相同的效果,我尝试使用msidb.exe和orca.exe。orca的文档说明:

可以使用许多合并模块选项 从命令行指定

从合并模块提取文件 Orca支持三种不同的方法 用于提取文件中包含的文件 合并模块。逆戟鲸可以提取 单个CAB文件,解压缩文件 进入模块树并提取 在源映像中创建文件后,将其保存到源映像中 已合并到目标数据库中

提取文件 从文件中提取单个文件的步骤 合并模块,使用

-x。。。选择权 命令行,其中是 新目录的所需路径 树

指定的路径用作根目录 提取文件的路径。全部的 文件从CAB文件中提取 嵌入模块并放置在 指定的路径。目录 提取的文件的布局如下所示 基于 合并模块

orca -m "myModule.msm" -f ProductFeature -x .\xdir blank.msi
听起来像是我需要的。但当我尝试时,orca只需打开一个编辑器(包含我指定的msm信息)然后什么也不做。我尝试过多种命令行,通常从以下命令行开始:

orca-x目录模块.msm

我使用“theDirectory”作为我想要的任何空文件夹。就像我说的-它什么都没做

然后我尝试了msidb,其中我做了两次尝试,如下所示:

msidb-d theModule.msm-w{storage}

msidb-d theModule.msm-x MergeModule.CABinet

在第一种情况下,我不知道要为{storage}放什么。在第二种情况下,事实证明文字字符串“MergeModule.CABinet”是必需的(它是一个保留名称)。但是,提取的文件柜不保留文件层次结构或“正常”文件名;所以我不能把它用于我的目的


有人能解释一下我对命令行选项的错误吗?是否有其他工具可以执行此操作?

中的DeploymentToolsFundation类库有一个InstallPackage类,该类具有ExtractFiles()方法,该方法应该可以执行您想要的操作,但对于合并模块失败。这似乎是一个错误

下面的PowerShell脚本使用DTF访问mergemodule中的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()
}

我有一个类似的问题,但我从不同的方向去做

我安装了VisualStudio早期版本附带的InstallSheild Express,创建了一个新项目,但我只添加了所需的MSM文件


编译并运行新安装后,我能够检索MSM文件包含的文件。

我只需创建一个空白msi,然后使用Orca尝试将模块合并到msi中,然后提取文件即可

  • 创建一个空白的.msi。我曾经创建过.msi,下面是最小的源代码。我把它命名为“blank.msi”

  • 文件将被提取到-x参数指定的目录中(在本例中为。\xdir)


    请注意,-f参数“ProductFeature”的值与上面msi文件中指定的功能名称相匹配。

    您可以使用(调用)附带的反编译器工具反编译合并模块并提取文件:

    dark.exe myMergeModule.msm -x "path_to_extracted_files"
    
    文件将被提取到-x参数中指定的路径


    注意:将使用安装数据库的文件表中指定的名称提取文件,该名称可能不是实际安装文件时使用的文件名。如果您需要使用实际文件名提取文件,请参阅我对这个问题的其他回答:

    Heath Stewart编写了一个从修补程序(MSP)中提取文件的工具。它对男男性接触者有效吗?我不知道,但值得一试:根据你的建议,我使用了它:“msi2xml-b streams-c files installation.msi”…它的结果基本上与“msidb-d theModule.msm-x MergeModule.CABinet”和“expand MergeModule.CABinet”的结果相同,所以我仍然被卡住了。如果只有msiexec.exe的“管理安装”可以在msm文件上运行。这基本上就是我要寻找的“文件提取”行为。这种语法对于黑暗版本3.5似乎不正确?我使用了这个示例:dark.exe-x c:\msm\extracted c:\msm\myMergeModule.msm“-x”之后的参数是要提取到的路径(深色版本3.5)。不幸的是,在xml中没有包含Merge和MergeRef。如何包含Merge和MergeRefnodes@Gmt上面的xml仅用于创建空白msi。包括合并模型发生在对orca的调用中
    -m
    合并合并模块,
    -f
    将其与功能关联,然后
    -x
    提取文件。
    dark.exe myMergeModule.msm -x "path_to_extracted_files"