在WiX中静默安装根证书

时间:2012-11-20 17:04:17

标签: wix

如何从WiX静默安装根证书?我正在安装一些根证书和中间证书,对于根证书,系统会显示确认对话框,显示基本证书属性和指纹。这是我的相关代码,使用WixIIsExtension映射到名称空间iis

<Binary Id="RootCa" SourceFile="Certificates\RootCa.cer" />

<DirectoryRef Id="TARGETDIR">
  <Component Id="RootCa" Guid="...">
    <iis:Certificate
      Id="RootCa"
      BinaryKey="RootCa"
      Name="RootCa"
      StoreLocation="currentUser"
      StoreName="root"/>
  </Component>
</DirectoryRef>

<Feature ...>
    <ComponentRef Id="RootCa" />
</Feature>

4 个答案:

答案 0 :(得分:5)

我正在使用相同的自定义操作

<CustomAction Id="InstallCertificates" Directory="TARGETDIR" ExeCommand="[SystemFolder]Certutil –addstore –f &quot;root&quot; &quot;[INSTALLLOCATION]Certificates\CertificateName.cer&quot;" Execute="immediate" Return="ignore" />

答案 1 :(得分:3)

我很久以前一直在寻找答案。那就是我拥有的东西:

WiX代码:

<CustomAction Id="ImportCer.Props" Property="ImportCer" Value="[INSTALLDIR]ca\root.cer" />
<CustomAction Id="ImportCer" Execute="deferred"  FileKey="hsminst.dll" DllEntry="ImportCer" />

<CustomAction Id="ImportPfx.Props" Property="ImportPfx" Value="[INSTALLDIR]ca\super.pfx" />
<CustomAction Id="ImportPfx" Execute="deferred" FileKey="hsminst.dll" DllEntry="ImportPfx" />

C ++代码:

 extern "C" __declspec(dllexport) UINT __stdcall ImportCer(MSIHANDLE hInstall)
 {
      char szPath[MAX_PATH];

      GetModuleFileNameA(NULL, szPath, MAX_PATH);

      char certFilePath[MAX_PATH] = {0};
  DWORD certFilePathLen = MAX_PATH;
      MsiGetProperty (
           hInstall, 
           "CustomActionData", 
           certFilePath, 
           &certFilePathLen);

      wchar_t certFilePathW[MAX_PATH];
      MultiByteToWideChar(
           CP_ACP, 
           0, 
           certFilePath, 
           -1, 
           certFilePathW, 
           MAX_PATH);

      PCCERT_CONTEXT pCertCtx = NULL;

      if (CryptQueryObject (
         CERT_QUERY_OBJECT_FILE,
         certFilePathW,
         CERT_QUERY_CONTENT_FLAG_ALL,
         CERT_QUERY_FORMAT_FLAG_ALL,
         0,
         NULL,
         NULL,
         NULL,
         NULL,
         NULL,
         (const void **)&pCertCtx) != 0)
      {
          HCERTSTORE hCertStore = CertOpenStore (
              CERT_STORE_PROV_SYSTEM,
              0,
              0,
              CERT_STORE_OPEN_EXISTING_FLAG |
              CERT_SYSTEM_STORE_LOCAL_MACHINE,
              L"root");
          if (hCertStore != NULL)
          {
               if (!CertAddCertificateContextToStore (
                  hCertStore,
                  pCertCtx,
                  CERT_STORE_ADD_ALWAYS,
                  NULL))
               {
                  return -2;
               }

               if (!CertCloseStore (hCertStore, 0))
               {
                   return -3;
               }
          }
          else
          { 
                return -1; 
          }

          if (pCertCtx)
          {
               CertFreeCertificateContext (pCertCtx);
          }
      }
      return 0;
  }

  extern "C" __declspec(dllexport) UINT __stdcall ImportPfx(MSIHANDLE hInstall)
  {
       char certFilePath[MAX_PATH] = {0};
   DWORD certFilePathLen = MAX_PATH;
       MsiGetProperty (
            hInstall, 
            "CustomActionData", 
            certFilePath, 
            &certFilePathLen);

       wchar_t certFilePathW[MAX_PATH];
       MultiByteToWideChar(
            CP_ACP, 
            0, 
            certFilePath, 
            -1, 
            certFilePathW, 
            MAX_PATH);

       CRYPTUI_WIZ_IMPORT_SRC_INFO importSrc;
       memset(
           &importSrc, 
           0, 
           sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO));

       importSrc.dwSize = sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO);
       importSrc.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_FILE;
       importSrc.pwszFileName = certFilePathW;
       importSrc.pwszPassword = L"111111";
       importSrc.dwFlags = CRYPT_EXPORTABLE;

       HCERTSTORE serviceStore = CertOpenStore(
            CERT_STORE_PROV_SYSTEM,
            0,
            0,
            CERT_STORE_OPEN_EXISTING_FLAG |
            CERT_SYSTEM_STORE_CURRENT_USER,
            L"my");

       if (CryptUIWizImport(
            CRYPTUI_WIZ_NO_UI ,
            NULL,
            NULL,
            &importSrc,
            serviceStore
            ) == 0)
       {
           return -1;
       }
       return 0;
  }
希望能帮助你

答案 2 :(得分:1)

Sunil提供的自定义操作等同于属性为Certificate的{​​{1}}组件。在我的情况下,在机器商店中安装更有意义,所以我会继续这样做。原始问题仍然存在:如何在用户存储中静默安装根证书。如果有人对该问题有答案,我会将其标记为正确答案。

答案 3 :(得分:0)

我在使用WiX安装证书时遇到了问题 - 我遇到了两个问题:

1。如果您告诉WiX安装在本地计算机上受信任的根证书中,它不起作用,而是安装在个人存储中。
2。 WiX安装的证书(当他们有私钥时)的权限没有设置Everyone用户。 [您可以使用MMC更改权限 - >证书管理器 - >本地计算机 - >(使用私钥查找证书)右键单击 - >所有任务 - >管理私钥,这将打开文件权限对话框]

使用microsoft winhttpcertcfg.exe tool可以避免这两个问题。我在批处理文件中使用它(见下文),并使用WiX静默自定义操作来调用批处理文件。我让WiX在执行批处理之前安装工具,证书和批处理文件。可以设置批处理以在安装后删除工具和证书。它还可用于启动WiX安装的服务,该服务取决于证书。批处理的使用大大减少了WiX文件中自定义操作的数量。

未正确安装证书的后果是间歇性错误(某些计算机正常工作,有些计算机没有工作,但有些计算机无效)和。#34;无法创建SSL / TLS安全通道&#34;执行http请求时出现异常。

REM Batch file to install certificates using WinHttpCertCfg.exe
"[path to installed]winhttpcertcfg.exe" -i "[path to installed]ca.pfx" -a Everyone -c LOCAL_MACHINE\Root  > c:\temp\installcc.log
"[path to installed]winhttpcertcfg.exe" -i "[path to installed]server.pfx" -a Everyone -c LOCAL_MACHINE\My  >> c:\temp\installcc.log

我在产品中安装批量安装和卸载文件。然后在WiX中 - 注意延迟和模拟的自定义操作。

<CustomAction Id="InstallCustomAction_Cmd" 
    Property="InstallCustomActionQt" 
    Value="&quot;cmd.exe&quot; /c &quot;[#InstallCustomAction.cmd]&quot;" 
    Execute="immediate" />

<CustomAction Id="InstallCustomActionQt" 
    BinaryKey="WixCA" 
    DllEntry="CAQuietExec"
    Execute="deferred" 
    Return="ignore" 
    Impersonate="yes"/>

<InstallExecuteSequence>
    <Custom Action="InstallCustomAction_Cmd" Before="InstallFinalize">NOT REMOVE</Custom>
    <Custom Action="InstallCustomActionQt" After="InstallCustomAction_Cmd" >NOT REMOVE</Custom>
...
</InstallExecuteSequence>
...
<Component Id="InstallCustomAction" Guid="{your-GUID}">
    <File Id="InstallCustomAction.cmd" KeyPath="yes"  
          Source="tools\InstallCloudConnectCustomAction.cmd" />
</Component>