2015-05-23 68 views
1

我有幾個從MsiEnumProducts過濾的產品代碼,需要獲取其分配的證書。 應該可以通過使用MsiOpenDatabase獲取證書,但我不知道如何可靠地獲取.msi文件的路徑。使用產品代碼獲取已安裝的Windows Installer軟件包的證書

我寧願避免外部程序集(如wix),只能拼寫。

+2

我不認爲MSI API在什麼做到這一點。據推測,你已經想出瞭如何在C:\ Windows \ Installer中獲取緩存MSI的路徑。您需要一些其他API來檢查應用於此文件的證書。請注意,在Windows 7之前,該證書將無效,因爲Windows在刪除嵌入式出租車時修改了該文件。 –

+0

我相信如果從[** admin image **](http://stackoverflow.com/questions/1547809/extract-msi-from-exe/24987512#24987512)運行安裝,證書也將丟失從原來的微星。我不確定這是否會影響MsiDigitalSignature表及其關聯表。只需找到一個簽名的MSI文件,運行管理員映像並檢查表格。 –

回答

2

給定一個產品代碼,調用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); 
     } 
    } 
} 
相關問題