使用C#生成MSI转换 [英] Generating msi transform using c#

查看:49
本文介绍了使用C#生成MSI转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a cutomization software which will do all the standardization to a mst file. Below is the code of class that will change product name and genrate transform.

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错误"来捕获它的块.在我看来,由editTransform创建的文件副本仍被它锁定,无法用于generateTrans()方法.请在这里帮助.

First editTransform() is called which will create a copy of original msi and do some changes in it, then generateTrans() is called which will get difference detween two msi files and create a transform file. Now issue is when genrateTrans() is called, then it goes to catch block of it as inst.OpenDatabase return "MSI Api Error". It seems to me that the copy of file crated by editTransform is still locked by it and is not available for use for generateTrans() menthod. Please help here.

PS:用于编辑转换的模式是事务处理.

PS: mode used for edit transform is transact.

推荐答案

而不是执行COM Interop,而是签出Windows Installer XML部署工具基金会中提供的更高级的interop库(Microsoft.Deployment.WindowsInstaller).您会发现它更易于使用.

Instead of doing the COM Interop, checkout the far superior interop library ( Microsoft.Deployment.WindowsInstaller ) found in Windows Installer XML Deployment Tools Foundation. You'll find it much easier to use.

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#生成MSI转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆