c# - 使用 C# 生成 msi 转换

标签 c# windows-installer transform

我正在创建一个自定义软件,它将对 mst 文件进行所有标准化。 下面是将更改产品名称和生成转换的类的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WindowsInstaller;
using System.Data;

namespace Automation
{
    class CustomInstaller
    {
        public CustomInstaller()
        {
        }
        public Record getInstaller(string msiFile,MsiOpenDatabaseMode mode,string query)
        {
            Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            Installer inst = (Installer)Activator.CreateInstance(type);
            Database db = inst.OpenDatabase(msiFile, mode);
            WindowsInstaller.View view = db.OpenView(query);
            view.Execute(null); 
            Record record = view.Fetch();
            db.Commit();
            return record;

        }
        public bool generateTrans(string file1, string file2,string transName)
        {
            Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            Installer inst = (Installer)Activator.CreateInstance(type);
            Database db1 = inst.OpenDatabase(file1, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);

            try
            {
                Database db2 = inst.OpenDatabase(file2, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
                return db2.GenerateTransform(db1, transName);

            }
            catch (Exception e) { }
            return false;
        }
        public int editTransform(string msiFile, MsiOpenDatabaseMode mode, string query)
        {
            Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            Installer inst = (Installer)Activator.CreateInstance(type);
            Database db = inst.OpenDatabase(msiFile, mode);
            WindowsInstaller.View view = db.OpenView(query);
            view.Execute(null);
            db.Commit();
            int o=(int)db.DatabaseState;
            db = null;
            inst = null;
            type = null;
            return 1;
        }
    }
}

首先调用 editTransform() 以创建原始 msi 的副本并对其进行一些更改,然后调用 generateTrans() 以获取两个 msi 文件之间的差异并创建一个转换文件。 现在的问题是当 genrateTrans() 被调用时,它会在 inst.OpenDatabase 返回“MSI Api 错误”时捕获它的 block 。 在我看来,由 editTransform 创建的文件副本仍然被它锁定,并且不可用于 generateTrans() menthod。 请在这里帮忙。

PS:edit transform使用的模式是transact。

最佳答案

不要执行 COM 互操作,而是检查 Windows Installer XML 部署工具基础中的高级互操作库 (Microsoft.Deployment.WindowsInstaller)。您会发现它更易于使用。

using System;
using System.IO;
using Microsoft.Deployment.WindowsInstaller;

namespace ConsoleApplication1
{

    class Program
    {
        const string REFERENCEDATABASE = @"C:\orig.msi";
        const string TEMPDATABASE = @"C:\temp.msi";
        const string TRANSFORM = @"c:\foo.mst";

        static void Main(string[] args)
        {
            File.Copy(REFERENCEDATABASE, TEMPDATABASE, true);
            using (var origDatabase = new Database(REFERENCEDATABASE, DatabaseOpenMode.ReadOnly))
            {
                using (var database = new Database(TEMPDATABASE, DatabaseOpenMode.Direct))
                {
                    database.Execute("Update `Property` Set `Property`.`Value` = 'Test' WHERE `Property`.`Property` = 'ProductName'");
                    database.GenerateTransform(origDatabase, TRANSFORM);
                    database.CreateTransformSummaryInfo(origDatabase, TRANSFORM, TransformErrors.None, TransformValidations.None);
                }
            }
        }
    }
}

关于c# - 使用 C# 生成 msi 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9757902/

相关文章:

actionscript-3 - 从长方形变成梯形

html - 对齐 270 度定向 div(转换 : rotate)

c# - NServicebus 6、Azure 存储持久性、Sagas 和复杂类型(集合)

windows - 如何使用 Squirrel.Windows 注册应用程序以在 Windows 启动时运行?

.net - 如何使用完全独立的 .NET 3.5 sp1 安装程序制作 WiX 安装程序?

OpenGL glMatrixMode(GL_PROJECTION) 与 glMatrixMode(GL_MODELVIEW)

c# - 将数据分组到单列并合并另一列

c# - 如何在 Windows 7 上删除 Java 程序的标题栏和任务栏图标?

c# - 删除测试驱动开发中的重复

powershell - 如何使用 PowerShell 查找已安装的软件?