WIX 安装程序中的自定义操作不会 运行
Custom Action Won't Run in WIX Installer
我正在尝试创建一个 MSI,其唯一目的是在 运行 将 .NET Framework 安装程序作为一个 WIX 助推器。由于在安装 .NET 4.8 之前我还没有找到从引导程序安装此证书的另一种方法,因此我决定创建一个包含自定义操作的 MSI 来安装证书,然后将其添加到 MSIPackage 调用的链中。我现在正在单独测试安装程序。所以,基本上我已经构建了自定义操作,并将其添加到 WIX 安装项目中。但是,在构建之后,当我 运行 msi 时,未安装证书。作为自定义操作的一部分,我添加了一个要创建的文件,只是为了查看它是否 运行ning,但该文件也从未创建过。
我的自定义操作如下:
[CustomAction]
public static ActionResult CheckForExistingCertificate(Session session)
{
session.Log("Starting CheckForExistingCertificate");
var logFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
@"\CertificateInstallInfo";
if (!File.Exists(logFile))
File.Create(logFile);
try
{
session.Log("***** Beginning LocalMachine Certificate Store Search...");
X509Store lmStore = new X509Store(StoreName.CertificateAuthority,
StoreLocation.LocalMachine);
lmStore.Open(OpenFlags.ReadOnly);
session.Log("***** lmStore.Certificates.Count = " + lmStore.Certificates.Count);
foreach (X509Certificate2 cert in lmStore.Certificates)
{
session.Log("lmCertificate Listing : " + cert.FriendlyName);
if (cert.FriendlyName == "Microsoft Root Certificate Authority 2011")
{
session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] = "TRUE";
}
}
session.Log("***** Beginning CurrentUser Certificate Store Search...");
X509Store cuStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser);
cuStore.Open(OpenFlags.ReadOnly);
session.Log("***** cuStore.Certificates.Count = " + cuStore.Certificates.Count);
foreach (X509Certificate2 cert in cuStore.Certificates)
{
session.Log("cuCertificate Listing : " + cert.FriendlyName);
if (cert.FriendlyName == "Microsoft Root Certificate Authority 2011")
{
session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] = "TRUE";
}
}
if (session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] == "FALSE")
{
X509Certificate2 certificate = new X509Certificate2("MicrosoftRootCertificateAuthority2011.cer");
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
}
}
catch (Exception ex)
{
File.WriteAllText(logFile, ex.ToString());
session.Log("CheckForExistingCertificate - in catch");
}
session.Log("Ending CheckForExistingCertificate - end of function");
return ActionResult.Success;
}
我的 WIX 设置 Product.wxs 文件是:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Install Certificates" Language="1033" Version="1.0.0.0" Manufacturer="Just Joe Applications" UpgradeCode="68d00e98-21a2-480f-bb3a-be3049995f3c">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<!--<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />-->
<MediaTemplate />
<Binary Id="CustomActionBinary" SourceFile="$(var.InstallCertificateAction.TargetDir)$(var.InstallCertificateAction.TargetName).CA.dll" />
<CustomAction Id="InstallCert" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="CheckForExistingCertificate" Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action="InstallCert" After="InstallInitialize"/>
</InstallExecuteSequence>
<Feature Id="ProductFeature" Title="Install Certificates" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Install Certificates" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
</ComponentGroup>
</Fragment>
</Wix>
如果您想将其作为引导程序捆绑包中的 MSI 包来执行此操作,只需使用 WiX IIS 扩展将证书安装到适当的证书存储中。
如果我要使用自己的代码来执行此操作,我会将其编写为无窗口控制台应用程序并将其作为 EXE 包连接到引导程序。您也可以编写一个注册表值以在检测条件下使用,但如果您不费心,它可能不会对 运行 程序一遍又一遍有害。
我正在尝试创建一个 MSI,其唯一目的是在 运行 将 .NET Framework 安装程序作为一个 WIX 助推器。由于在安装 .NET 4.8 之前我还没有找到从引导程序安装此证书的另一种方法,因此我决定创建一个包含自定义操作的 MSI 来安装证书,然后将其添加到 MSIPackage 调用的链中。我现在正在单独测试安装程序。所以,基本上我已经构建了自定义操作,并将其添加到 WIX 安装项目中。但是,在构建之后,当我 运行 msi 时,未安装证书。作为自定义操作的一部分,我添加了一个要创建的文件,只是为了查看它是否 运行ning,但该文件也从未创建过。
我的自定义操作如下:
[CustomAction]
public static ActionResult CheckForExistingCertificate(Session session)
{
session.Log("Starting CheckForExistingCertificate");
var logFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
@"\CertificateInstallInfo";
if (!File.Exists(logFile))
File.Create(logFile);
try
{
session.Log("***** Beginning LocalMachine Certificate Store Search...");
X509Store lmStore = new X509Store(StoreName.CertificateAuthority,
StoreLocation.LocalMachine);
lmStore.Open(OpenFlags.ReadOnly);
session.Log("***** lmStore.Certificates.Count = " + lmStore.Certificates.Count);
foreach (X509Certificate2 cert in lmStore.Certificates)
{
session.Log("lmCertificate Listing : " + cert.FriendlyName);
if (cert.FriendlyName == "Microsoft Root Certificate Authority 2011")
{
session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] = "TRUE";
}
}
session.Log("***** Beginning CurrentUser Certificate Store Search...");
X509Store cuStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser);
cuStore.Open(OpenFlags.ReadOnly);
session.Log("***** cuStore.Certificates.Count = " + cuStore.Certificates.Count);
foreach (X509Certificate2 cert in cuStore.Certificates)
{
session.Log("cuCertificate Listing : " + cert.FriendlyName);
if (cert.FriendlyName == "Microsoft Root Certificate Authority 2011")
{
session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] = "TRUE";
}
}
if (session["INTERMEDIATECERTIFICATEALREADYINSTALLED"] == "FALSE")
{
X509Certificate2 certificate = new X509Certificate2("MicrosoftRootCertificateAuthority2011.cer");
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
}
}
catch (Exception ex)
{
File.WriteAllText(logFile, ex.ToString());
session.Log("CheckForExistingCertificate - in catch");
}
session.Log("Ending CheckForExistingCertificate - end of function");
return ActionResult.Success;
}
我的 WIX 设置 Product.wxs 文件是:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Install Certificates" Language="1033" Version="1.0.0.0" Manufacturer="Just Joe Applications" UpgradeCode="68d00e98-21a2-480f-bb3a-be3049995f3c">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<!--<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />-->
<MediaTemplate />
<Binary Id="CustomActionBinary" SourceFile="$(var.InstallCertificateAction.TargetDir)$(var.InstallCertificateAction.TargetName).CA.dll" />
<CustomAction Id="InstallCert" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="CheckForExistingCertificate" Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action="InstallCert" After="InstallInitialize"/>
</InstallExecuteSequence>
<Feature Id="ProductFeature" Title="Install Certificates" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Install Certificates" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
</ComponentGroup>
</Fragment>
</Wix>
如果您想将其作为引导程序捆绑包中的 MSI 包来执行此操作,只需使用 WiX IIS 扩展将证书安装到适当的证书存储中。
如果我要使用自己的代码来执行此操作,我会将其编写为无窗口控制台应用程序并将其作为 EXE 包连接到引导程序。您也可以编写一个注册表值以在检测条件下使用,但如果您不费心,它可能不会对 运行 程序一遍又一遍有害。