1
我有幾個從MsiEnumProducts過濾的產品代碼,需要獲取其分配的證書。 應該可以通過使用MsiOpenDatabase獲取證書,但我不知道如何可靠地獲取.msi文件的路徑。使用產品代碼獲取已安裝的Windows Installer軟件包的證書
我寧願避免外部程序集(如wix),只能拼寫。
我有幾個從MsiEnumProducts過濾的產品代碼,需要獲取其分配的證書。 應該可以通過使用MsiOpenDatabase獲取證書,但我不知道如何可靠地獲取.msi文件的路徑。使用產品代碼獲取已安裝的Windows Installer軟件包的證書
我寧願避免外部程序集(如wix),只能拼寫。
給定一個產品代碼,調用MsiGetProductInfo傳遞屬性名稱INSTALLPROPERTY_LOCALPACKAGE返回緩存的安裝程序包在C:\ Windows \ Installer中的位置。
一旦你有了高速緩存的軟件包,對MsiGetFileSignatureInformation的調用就可以檢索到該證書。
例使用的PInvoke:
using System;
using System.Text;
using System.Runtime.InteropServices;
class Program
{
[DllImport("msi.dll", CharSet = CharSet.Ansi, SetLastError = false)]
static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf);
[DllImport("msi.dll", CharSet = CharSet.Ansi, SetLastError = false)]
static extern int MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len);
[DllImport("msi.dll", CharSet = CharSet.Ansi, SetLastError = false)]
static extern int MsiGetFileSignatureInformation(string fileName, int flags, out IntPtr certContext, IntPtr hashData, ref int hashDataLength);
[DllImport("Crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern int CertFreeCertificateContext(IntPtr certContext);
[DllImport("Crypt32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern int CertGetNameString(IntPtr certContext, UInt32 type, UInt32 flags, IntPtr typeParameter, StringBuilder stringValue, UInt32 stringLength);
static void Main(string[] args)
{
int index = 0;
StringBuilder productCode = new StringBuilder();
int result = MsiEnumProducts(index, productCode);
while (result == 0)
{
Console.WriteLine("{0}", productCode);
Int32 length = 1024;
StringBuilder fileName = new StringBuilder();
result = MsiGetProductInfo(
productCode.ToString(),
"LocalPackage",
fileName,
ref length);
if (result == 0)
{
Console.WriteLine("{0}", fileName);
IntPtr certContext = IntPtr.Zero;
IntPtr hashData = IntPtr.Zero;
int hashDataLength = 0;
result = MsiGetFileSignatureInformation(
fileName.ToString(),
0,
out certContext,
hashData,
ref hashDataLength);
if (result == 0)
{
Console.WriteLine("Got Cert");
StringBuilder simpleDisplayType = new StringBuilder();
int ok = CertGetNameString(
certContext,
4, // == CERT_NAME_SIMPLE_DISPLAY_TYPE
0,
IntPtr.Zero,
simpleDisplayType,
1024);
if (ok != 0)
{
Console.WriteLine("{0}", simpleDisplayType);
}
CertFreeCertificateContext(certContext);
}
}
++index;
result = MsiEnumProducts(index, productCode);
}
}
}
我不認爲MSI API在什麼做到這一點。據推測,你已經想出瞭如何在C:\ Windows \ Installer中獲取緩存MSI的路徑。您需要一些其他API來檢查應用於此文件的證書。請注意,在Windows 7之前,該證書將無效,因爲Windows在刪除嵌入式出租車時修改了該文件。 –
我相信如果從[** admin image **](http://stackoverflow.com/questions/1547809/extract-msi-from-exe/24987512#24987512)運行安裝,證書也將丟失從原來的微星。我不確定這是否會影響MsiDigitalSignature表及其關聯表。只需找到一個簽名的MSI文件,運行管理員映像並檢查表格。 –