Могу ли я извлечь содержимое пакета MSI из программы на C++ или C#?

Скажем, если у меня есть установочный файл MSI, могу ли я извлечь его содержимое из программы на C# или C++ без его установки?

2 ответа

Решение

Как правило, вы можете выполнить административную установку, чтобы извлечь содержимое MSI.

msiexec /a foo.msi TARGETDIR=C:\EXTRACTHERE /qn

Если вы не хотите выходить из процесса, вы можете напрямую взаимодействовать с MSI через функцию MsiInstallProduct.

szPackagePath [in] Строка с нулевым символом в конце, указывающая путь к расположению пакета установщика Windows. Строковое значение может содержать URL-адрес, сетевой путь, путь к файлу (например, file://packageLocation/package.msi) или локальный путь (например, D: \ packageLocation \ package.msi).

szCommandLine [in] Строка с нулевым символом в конце, указывающая параметры свойства командной строки. Это должен быть список в формате Property=Setting Property=Setting. Для получения дополнительной информации см. О свойствах.

Чтобы выполнить административную установку, включите ACTION=ADMIN в szCommandLine. Для получения дополнительной информации см. Свойство ACTION.

Обратите внимание, что хотя вы можете объявить P/Invoke самостоятельно, существует действительно хорошая библиотека взаимодействия.NET с Windows Instaler XML, которая называется Deployment Tools Foundation (DTF). Пространство имен Microsoft.Deployment.WindowsInstaller имеет метод класса с именем Installer, который предоставляет статический метод с именем InstallProduct. Это прямая инкапсуляция MsiInstallProduct.

Использование библиотек DTF скрывает от вас уродство Win32 API и правильно реализует IDisposable там, где это необходимо, чтобы обеспечить освобождение базовых неуправляемых дескрипторов при необходимости.

Кроме того, DTF имеет пространство имен Microsoft.DeploymentWindowwsInstaller.Package с классом InstallPackage. Этот класс предоставляет метод с именем ExtractFiles(), который извлекает файлы в рабочий каталог. Пример кода выглядит так:

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Package;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using( var package = new InstallPackage(@"C:\test.msi", DatabaseOpenMode.ReadOnly))
            {
                package.ExtractFiles();
            }
        }
    }
}

Файл MSI является структурированным хранилищем COM. Это в основном база данных. Вы можете найти подробную документацию по MSDN:

  • Вот API базы данных
  • Здесь вы можете найти информацию о формате составного двоичного файла
  • Вот документ об установщике Windows
Другие вопросы по тегам