Нужен способ вытаскивать инфу из msi пакета. Нашел решение в инете, на его основе сделал класс
internal class GetMsiInfo {
#region using msi.dll
[DllImport("msi.dll", SetLastError = true)]
private static extern uint MsiOpenDatabase(string szDatabasePath, IntPtr phPersist, out IntPtr phDatabase);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
private static extern int MsiDatabaseOpenViewW(IntPtr hDatabase, [MarshalAs(UnmanagedType.LPWStr)] string szQuery, out IntPtr phView);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
private static extern int MsiViewExecute(IntPtr hView, IntPtr hRecord);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
private static extern uint MsiViewFetch(IntPtr hView, out IntPtr hRecord);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
private static extern int MsiRecordGetString(IntPtr hRecord, int iField, [Out] StringBuilder szValueBuf, ref int pcchValueBuf);
[DllImport("msi.dll", ExactSpelling = true)]
private static extern IntPtr MsiCreateRecord(uint cParams);
[DllImport("msi.dll", ExactSpelling = true)]
private static extern uint MsiCloseHandle(IntPtr hAny);
[DllImport("msi.dll", CharSet = CharSet.Auto)]
public static extern uint MsiDatabaseCommit(IntPtr phDatabas);
#endregion
public string ValueProperty { get; private set; }
//public void GetMSIInfo(string fileName, string property) {
public void GetMSIInfo(string fileName, string property)
{
try
{
using (Stream stream = new FileStream(fileName, FileMode.Open))
{
}
}
catch (Exception e)
{
//check here why it failed and ask user to retry if the file is in use.
Console.WriteLine(e.Message);
}
var sqlStatement = "SELECT * FROM Property WHERE Property = '" + property + "'";
var phDatabase = IntPtr.Zero;
var phView = IntPtr.Zero;
var hRecord = IntPtr.Zero;
var szValueBuf = new StringBuilder();
var pcchValueBuf = 255;
// Open the MSI database in the input file
var val = MsiOpenDatabase(fileName, IntPtr.Zero, out phDatabase);
hRecord = MsiCreateRecord(1);
// Open a view on the Property table for the version property
var viewVal = MsiDatabaseOpenViewW(phDatabase, sqlStatement, out phView);
// Execute the view query
var exeVal = MsiViewExecute(phView, hRecord);
// Get the record from the view
var fetchVal = MsiViewFetch(phView, out hRecord);
// Get the version from the data
var retVal = MsiRecordGetString(hRecord, 2, szValueBuf, ref pcchValueBuf);
uint uRetCode;
uRetCode = MsiDatabaseCommit(phDatabase);
uRetCode = MsiCloseHandle(phView);
uRetCode = MsiCloseHandle(hRecord);
uRetCode = MsiCloseHandle(phDatabase);
ValueProperty = szValueBuf.ToString();
}
}
Только он отрабатывает нормально при первом вызове метода. При втором вылетает ошибка.
System.AccessViolationException
HResult=0x80004003
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=Install-From-MSI
StackTrace:
at Install_From_MSI.GetMsiInfo.MsiRecordGetString(IntPtr hRecord, Int32 iField, StringBuilder szValueBuf, Int32& pcchValueBuf)
at Install_From_MSI.GetMsiInfo.GetMSIInfo(String fileName, String property) in C:\Users\user\source\repos\\Install-From-MSI\GetMsiInfo.cs:line 78
at Install_From_MSI.NewApp.<>c__DisplayClass39_0.<GetInfoMSI>b__0() in C:\Users\user\source\repos\\Install-From-MSI\NewApp.cs:line 102
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Просьба подсказать в какую сторону копать. Спасибо.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Все работало буквально 10 минут назадСоздал новую сцену, все так же работало, но потом что-то пошло не так
Помогите самоваруЕсть два метода, которые по отдельности возвращают координаты х и у соотвественно