我尝试在我的程序安装程序中集成根证书安装。我必须从证书创建一个对象,然后将其添加到商店。
const std::string cert = R"cert(
-----BEGIN CERTIFICATE-----
/***/
-----END CERTIFICATE-----
)cert";
PCCERT_CONTEXT pCertCtx = NULL;
CRYPT_INTEGER_BLOB blob;
blob.pbData = (BYTE*)cert.c_str();
bool result = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
CERT_QUERY_CONTENT_FLAG_CERT,
CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED,
0, NULL, NULL, NULL, NULL, NULL, (const void**)&pCertCtx);
if (!result) {
DWORD errorMessageID = ::GetLastError();
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&messageBuffer, 0, NULL);
std::string message(messageBuffer, size);
//Free the buffer.
LocalFree(messageBuffer);
return ERROR_INSTALL_FAILURE;
}
我用这个自定义操作制作了自己的 dll 并将其添加到 WiX。
<Binary Id="pathFixer" SourceFile="$(var.product.inputFilesDir)\path-fixer.dll" />
<Binary Id="additionalActions" SourceFile="$(var.product.inputFilesDir)\additional-actions.dll" />
<CustomAction Id="SetNativeMessageHostPath" BinaryKey="pathFixer" DllEntry="SetNativeMessageHostPath" Execute="deferred" Impersonate="no"/>
<CustomAction Id="SetInstallDir" Property="SetNativeMessageHostPath" Value="[INSTALLDIR]" Execute="immediate" />
<CustomAction Id="installRootCert" BinaryKey="additionalActions" DllEntry="installRootCert" Execute="deferred" Impersonate="no"/>
<CustomAction Id="ResetOldVersionFound" Property="OTHER_VERSION_FOUND" Value="" Execute="immediate" />
<CustomAction Id="GetPerUserOldVersionFound" Property="USER_OTHER_VERSION_FOUND" Value="[OTHER_VERSION_FOUND]" Execute="immediate" />
<CustomAction Id="GetPerMachineOldVersionFound" Property="MACHINE_OTHER_VERSION_FOUND" Value="[OTHER_VERSION_FOUND]" Execute="immediate" />
<CustomAction Id="SetPerUserOldVersionToRemove" Property="OTHER_VERSION_FOUND" Value="[USER_OTHER_VERSION_FOUND]" Execute="immediate" />
<CustomAction Id="SetPerMachineOldVersionToRemove" Property="OTHER_VERSION_FOUND" Value="[MACHINE_OTHER_VERSION_FOUND]" Execute="immediate" />
<InstallExecuteSequence>
<Custom Action="SetPerUserOldVersionToRemove" Before="RemoveExistingProducts">MSIINSTALLPERUSER=1</Custom>
<Custom Action="SetPerMachineOldVersionToRemove" Before="RemoveExistingProducts">MSIINSTALLPERUSER=""</Custom>
<Custom Action="SetInstallDir" After="InstallInitialize"/>
<RemoveExistingProducts After="InstallInitialize" />
<InstallExecute After="RemoveExistingProducts" />
</InstallExecuteSequence>
<Media Id="1" Cabinet="$(var.project.name).cab" EmbedCab="yes" CompressionLevel="high" />
<CustomAction Id="SetPerUserFolder" Directory="APPLICATIONFOLDER" Value="[AppDataFolder]" Execute="immediate" />
<CustomAction Id="SetPerMachineFolder" Directory="APPLICATIONFOLDER" Value="[ProgramFilesFolder]" Execute="immediate" />
<InstallExecuteSequence>
<Custom Action="SetPerUserFolder" After="CostFinalize">NOT Installed AND MSIINSTALLPERUSER=1</Custom>
<Custom Action="SetPerMachineFolder" After="SetPerUserFolder">NOT Installed AND MSIINSTALLPERUSER=""</Custom>
<Custom Action="SetNativeMessageHostPath" After="PublishProduct">NOT REMOVE</Custom>
<Custom Action="installRootCert" After="PublishProduct">NOT REMOVE</Custom>
</InstallExecuteSequence>
调试直接说执行了安装功能。但是通过一些神奇的操作,比如加入 MessageBox、调试,我从周期CryptQueryObject
true
中false
获取,但不是系统地。GetLastError
说Parameter is incorrect
。为什么会发生这种情况?