检查是否使用CustomAction和Wix安装了.NETCore

时间:2019-11-19 08:57:31

标签: c# .net-core installation wix custom-action

如果未安装NetCore 3.1(预览版),我想取消安装

我创建了这个CustomAction:

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Win32;

namespace WixCustomAction
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult CheckDotNetCore31Installed(Session session)
        {
            session.Log("Begin CheckDotNetCore31Installed");

            RegistryKey lKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost");

            var version = (string)lKey.GetValue("Version");

            session["DOTNETCORE31"] = version == "3.1.0-preview3.19553.2" ? "1" : "0";

            return ActionResult.Success;
        }
    }
}

然后在WXS文件中:

<<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">

   <Product ...>

  (...)

    <Property Id="DOTNETCORE31">0</Property>

    <Condition Message="You must first install the .NET Core 3.1 Runtime">
      Installed OR DOTNETCORE31="1"
    </Condition>

    <InstallExecuteSequence>
      <Custom Action="Check.NetCore" Before="LaunchConditions">NOT Installed</Custom>
    </InstallExecuteSequence>

  </Product>

  <Fragment>
    <Binary Id="WixCA.dll" SourceFile="$(var.WixCustomAction.TargetDir)$(var.WixCustomAction.TargetName).CA.dll" />
    <CustomAction Id="Check.NetCore" BinaryKey="WixCA.dll" DllEntry="CheckDotNetCore31Installed" Execute="immediate"  />
  </Fragment>

这是我遇到的问题,因为我总是收到警告消息。 一个主意 ?谢谢

3 个答案:

答案 0 :(得分:1)

  

调试 :您是否将调试器附加到自定义操作中,以便   可以看到那里发生了什么?我敢打赌这不是正确设置您的财产。 The custom action might not be running at all?显示一个消息框以抽烟测试吗?涉及更多(附加Visual Studio调试器):

     

LaunchCondition :在MSI数据库中,启动条件由LaunchCondition table中的记录表示。该表有两列。 条件列包含一个表达式,该表达式必须计算为 True 才能继续安装

MSI

  

结论 So your condition does not evaluate to true properly 。是什么    DOTNETCORE31 的实际值?我敢打赌它是 0 。再检查一遍   请。显然,最简单的方法是直接将其设置为 1 而不是 0 -然后再次进行编译和测试。像这样暂时进行硬编码:

<Property Id="DOTNETCORE31">1</Property>

链接 :以下是有关启动条件和其他主题的先前答案:


WiX自定义操作 :您具有调用自定义操作的基本标记吗?使用debugability检查已编译的MSI,以查看OrcaBinaryCustomActionInstallExecuteSequence表中是否有条目。一些WiX标记模型(pillage gihub.com for samples?):

InstallUISequence

GUI和静默安装 :显然,您还可以通过对话框事件运行自定义操作(例如单击按钮),但是这不会使其在静默模式下运行。 GUI在静默模式下被跳过,因此您需要在<Binary Id="CustomActions" SourceFile="C:\Test.CA.dll" /> <...> <CustomAction Id="CustomAction1" BinaryKey="CustomActions" DllEntry="CustomAction1"/> <...> <InstallUISequence> <Custom Action="CustomAction1" After="CostFinalize" /> </InstallUISequence> <...> <InstallExecuteSequence> <Custom Action="CustomAction1" After="CostFinalize" /> </InstallExecuteSequence> 和GUI中运行自定义操作。

答案 1 :(得分:1)

也许最好使用cmd检查.net核心版本 dotnet --version命令,以避免Windows体系结构依赖性

这种情况下的自定义操作示例:

    [CustomAction]
    public static ActionResult CheckVersion(Session session)
    {
       var minVersion = new Version(3, 1, 1);
        var command = "/c dotnet --version";// /c is important here
        var output = string.Empty;
        using (var p = new Process())
        {
            p.StartInfo = new ProcessStartInfo()
            {
                FileName = "cmd.exe",
                Arguments = command,
                UseShellExecute = false,                    
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                CreateNoWindow = true,
            };
            p.Start();
            while (!p.StandardOutput.EndOfStream)
            {
                output += $"{p.StandardOutput.ReadLine()}{Environment.NewLine}";
            }
            p.WaitForExit();
            if (p.ExitCode != 0)
            {
                session["DOTNETCORE1"] = "0";
                return ActionResult.Success;
                //throw new Exception($"{p.ExitCode}:{ p.StandardError.ReadToEnd()}");
            }

            //you can implement here your own comparing algorithm
            //mine will not work with -perview string, but in this case you can just 
            //replace all alphabetical symbols with . using regex, for example
            var currentVersion = Version.Parse(output);
            session["DOTNETCORE1"] = (currentVersion < minVersion) ? "0" : "1";
            
            return ActionResult.Success;
         }
      

答案 2 :(得分:0)

借助Stein Asmul,我能够调试CustomAction。这是有效的代码:

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Win32;

namespace WixCustomAction
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult CheckDotNetCore31Installed(Session session)
        {
            session.Log("Begin CheckDotNetCore31Installed");

            RegistryKey localMachine64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
            RegistryKey lKey = localMachine64.OpenSubKey(@"SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost\", false);

            var version = (string)lKey.GetValue("Version");

            session["DOTNETCORE1"] = version == "3.1.0-preview3.19553.2" ? "1" : "0";

            return ActionResult.Success;
        }
    }
}