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