Creating msi conversion using C #

I am creating cutting software that will perform standardization in the mst file. Below is the class code that will change the product name and genrate conversion.

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; } } } 

The first editTransform () is called, which will create a copy of the original msi and make some changes to it, then generateTrans () is called, which will get the difference between the two msi files and create the conversion file. Now the problem is when genrateTrans () is called, then it goes to the catch block, since inst.OpenDatabase returns "MSI Api Error". It seems to me that the copy of the file processed by editTransform is still locked by it and is not available for use with the generateTrans () menthod. Please help here.

PS: the mode used to convert the edit is transactional.

+4
source share
1 answer

Instead of doing COM interactions, check out the more advanced interop library (Microsoft.Deployment.WindowsInstaller) found in the Windows Installer XML Deployment Tools Foundation. You will 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); } } } } } 
+6
source

Source: https://habr.com/ru/post/1402089/


All Articles