gpt4 book ai didi

c# - 以编程方式检查 MSI 的产品版本

转载 作者:搜寻专家 更新时间:2023-10-30 19:54:58 24 4
gpt4 key购买 nike

如何使用msi.dll通过pinvoke快速获取msi数据库的ProductVersion?大多数情况下,我发现涉及使用 WindowsInstaller COM 包装器,虽然这完成了工作,但我想通过使用 msi.dll 的 pinvoke 获得相同的结果。

最佳答案

这是我想出的。

C# Windows Installer COM 库:

            // Get the type of the Windows Installer object 
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");

// Create the Windows Installer object
Installer installer = (Installer)Activator.CreateInstance(installerType);

// Open the MSI database in the input file
Database database = installer.OpenDatabase(od.FileName, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);

// Open a view on the Property table for the version property
WindowsInstaller.View view = database.OpenView("SELECT * FROM Property WHERE Property = 'ProductVersion'");

// Execute the view query
view.Execute(null);

// Get the record from the view
Record record = view.Fetch();

// Get the version from the data
string version = record.get_StringData(2);

C# 调用:

    [DllImport("msi.dll", SetLastError = true)]
static extern uint MsiOpenDatabase(string szDatabasePath, IntPtr phPersist, out IntPtr phDatabase);

[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern int MsiDatabaseOpenViewW(IntPtr hDatabase, [MarshalAs(UnmanagedType.LPWStr)] string szQuery, out IntPtr phView);

[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern int MsiViewExecute(IntPtr hView, IntPtr hRecord);

[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern uint MsiViewFetch(IntPtr hView, out IntPtr hRecord);

[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern int MsiRecordGetString(IntPtr hRecord, int iField,
[Out] StringBuilder szValueBuf, ref int pcchValueBuf);

[DllImport("msi.dll", ExactSpelling = true)]
static extern IntPtr MsiCreateRecord(uint cParams);

[DllImport("msi.dll", ExactSpelling = true)]
static extern uint MsiCloseHandle(IntPtr hAny);

public string GetVersionInfo(string fileName)
{
string sqlStatement = "SELECT * FROM Property WHERE Property = 'ProductVersion'";
IntPtr phDatabase = IntPtr.Zero;
IntPtr phView = IntPtr.Zero;
IntPtr hRecord = IntPtr.Zero;

StringBuilder szValueBuf = new StringBuilder();
int pcchValueBuf = 255;

// Open the MSI database in the input file
uint val = MsiOpenDatabase(fileName, IntPtr.Zero, out phDatabase);

hRecord = MsiCreateRecord(1);

// Open a view on the Property table for the version property
int viewVal = MsiDatabaseOpenViewW(phDatabase, sqlStatement, out phView);

// Execute the view query
int exeVal = MsiViewExecute(phView, hRecord);

// Get the record from the view
uint fetchVal = MsiViewFetch(phView, out hRecord);

// Get the version from the data
int retVal = MsiRecordGetString(hRecord, 2, szValueBuf, ref pcchValueBuf);

uRetCode = MsiCloseHandle(phDatabase);
uRetCode = MsiCloseHandle(phView);
uRetCode = MsiCloseHandle(hRecord);

return szValueBuf.ToString();
}

这可以很容易地推断为通过更改 SQL 语句从 msi 数据库中获取任何属性或字段。我希望这可以帮助别人。

关于c# - 以编程方式检查 MSI 的产品版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4347325/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com