Могу ли я извлечь содержимое пакета 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: