WindowsInstaller: MSI Informationen ändern oder anzeigen
Frank Dzaebel, erstellt am: 31.01.2009, zuletzt geändert: 16.04.2011
Kategorie:Setup, .NET-Version:4.0, [Download]

Unter .NET kann man recht einfach unter Verweise COM-Biliotheken einbinden. Hier wird die "Microsoft Windows Installer Object Library" benutzt, um eine MSI-Datei nachträglich zu ändern, oder deren Werte auszulesen. Auch die Anbindung nativer "MSI.dll"-APIs ist möglich. Beachten Sie, dass es auch umfangreiche Scripte im Windows Installer SDK gibt, dies ist nur ein Beispiel, dass man diese Thema .NET C# sehr einfach und typsicher behandeln kann.



   // [Installer.OpenDatabase Method (Windows)]
  // http://msdn.microsoft.com/en-us/library/aa369434.aspx
  // [Summary Information Stream Property Set (Windows)]
  // http://msdn.microsoft.com/en-us/library/aa372045.aspx
  // [SummaryInfo.Property Property (Windows)]
  // http://msdn.microsoft.com/en-us/library/aa372043.aspx  
  // [Re-inventing The Wheel : Careful what you wish for...]
  // http://blogs.msdn.com/mwade/archive/2007/04/26/careful-what-you-wish-for.aspx  
// using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; // using WindowsInstaller; // using WI = WindowsInstaller; WI.Database db; WI.Installer installer; private void Form1_Load(object sender, EventArgs e) { //IntPtr msiHandle = IntPtr.Zero; //NativeMethods.MsiError error = NativeMethods. // MsiOpenPackage(Path.Combine(Application.StartupPath, "Setup.msi"), out msiHandle); //if (error != NativeMethods.MsiError.Success) //{ // MessageBox.Show(error.ToString()); // return; //} cboAbfrage.SelectedIndex = 0; Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer"); installer = Activator.CreateInstance(installerType) as Installer; db = installer.OpenDatabase("../../AspNetMVCPreview3-setup.msi", MsiOpenDatabaseMode.msiOpenDatabaseModeTransact); StringList cps = installer.Components; MsiEvaluateCondition cond = db.get_TablePersistent("Shortcut"); if (cond != MsiEvaluateCondition.msiEvaluateConditionTrue) { MessageBox.Show("Test: Kein Shortcut-Table in MSI-Datei"); } SummaryInfo si = db.get_SummaryInformation(0); StringBuilder sb = new StringBuilder(); for (int p = 1; p < si.PropertyCount; p++) { object prop = si.get_Property(p); if (prop != null) sb.AppendLine(Enum.GetName(typeof(PID), p) + ": " + prop.ToString()); } MessageBox.Show(sb.ToString()); } /// <summary>Summary properties for installation packages, /// transforms, and patches are described in the /// following tables. </summary> /// <remarks> /// [Summary Property Descriptions (Windows)] /// http://msdn.microsoft.com/en-us/library/aa372049(VS.85).aspx /// </remarks> enum PID { DICTIONARY = 0, CODEPAGE, TITLE, SUBJECT, AUTHOR, KEYWORDS, COMMENTS, TEMPLATE, LASTAUTHOR, REVNUMBER, EDITTIME, LASTPRINTED, CREATE_DTM, LASTSAVE_DTM, PAGECOUNT, WORDCOUNT, CHARCOUNT, THUMBNAIL, APPNAME, SECURITY } // [SQL Syntax (Windows)] // http://msdn.microsoft.com/en-us/library/aa372021.aspx // [Examples of Database Queries Using SQL and Script] // http://msdn.microsoft.com/en-us/library/aa368562.aspx // [Database Tables] // http://msdn.microsoft.com/en-us/library/aa368259.aspx // siehe auch: // [SourceForge.net: izfree Tools for Windows Installer: Files] // http://sourceforge.net/project/showfiles.php?group_id=40188&package_id=110212 // [CodeProject: Microsoft Installer Database Reader.] // http://www.codeproject.com/KB/vb/MsiDbReader.aspx
private void btnAusführen_Click(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; try { WI.View view = null; try { view = db.OpenView(txtQuery.Text); } catch (Exception exp) { MessageBox.Show("[" + exp.Source + "] Beschreibung: " + exp.Message); return; } view.Execute(null); WI.Record cols = view.get_ColumnInfo(MsiColumnInfo.msiColumnInfoNames); dgv.Rows.Clear(); dgv.Columns.Clear(); for (int f = 1; f <= cols.FieldCount; f++) { string colName = cols.get_StringData(f); dgv.Columns.Add(colName, colName); } Record fetch = null; do { fetch = view.Fetch(); if (fetch == null) break; dgv.Rows.Add(1); for (int f = 1; f <= fetch.FieldCount; f++) { dgv[f - 1, dgv.Rows.Count - 1].Value = fetch.get_StringData(f); } Marshal.ReleaseComObject(fetch); } while (true); Marshal.ReleaseComObject(view); } finally { Cursor = Cursors.Default; } } private void cboAbfrage_SelectedIndexChanged(object sender, EventArgs e) { txtQuery.Text = cboAbfrage.SelectedItem as string; }