Skip to content

Commit

Permalink
WiX4: #1473: Build error with WixToolset.UI.wixext
Browse files Browse the repository at this point in the history
  • Loading branch information
oleg-shilo committed Apr 4, 2024
1 parent 1b8fd49 commit 85e5ff4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 12 deletions.
16 changes: 14 additions & 2 deletions Source/src/WixSharp/CommonTasks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2517,10 +2517,22 @@ internal static string SfxCAFor(string platformDir)
return PackageDir("wixtoolset.dtf.customaction").PathCombine($@"tools\{platformDir}\SfxCA.dll");
}

internal static string FindWixExtensionDll(string name, string version)
=> WixExtensionsDir.PathCombine(name, version, "wixext4", name + ".dll");

internal static void EnsureWixExtension(string name)
{
if (!Directory.Exists(WixExtensionsDir.PathCombine(name)))
Compiler.Run("wix.exe", $"extension add -g {name}");
var version = WixExtension.GetPreferredVersion(name);
if (version.IsEmpty())
{
if (!Directory.Exists(WixExtensionsDir.PathCombine(name)))
Compiler.Run("wix.exe", $"extension add -g {name}");
}
else
{
if (!Directory.Exists(WixExtensionsDir.PathCombine(name, version)))
Compiler.Run("wix.exe", $"extension add -g {name}/{version}");
}
}

internal static void EnsureDtfTool(string package = null)
Expand Down
55 changes: 45 additions & 10 deletions Source/src/WixSharp/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -650,14 +650,22 @@ This code was generated by WixSharp.
static string GenerateWixCommand(WixProject project, string wxsFile)
{
// Debug.Assert(false);
// objFile = IO.Path.ChangeExtension(wxsFile, ".wixobj");

project.WixExtensions.ForEach(x => WixTools.EnsureWixExtension(x));

string extensionDlls = project.WixExtensions
.Select(x => x.ExpandEnvVars())
.Distinct()
.JoinBy(" ", dll => $"-ext \"{dll}\"");
.JoinBy(" ", dll =>
{
var dllPath = dll;

var preferredVersion = WixExtension.GetPreferredVersion(dll);
if (preferredVersion.IsNotEmpty())
dllPath = WixTools.FindWixExtensionDll(dll, preferredVersion);

return $"-ext \"{dllPath}\"";
});

string libFiles = project.LibFiles
.Select(x => x.ExpandEnvVars())
Expand Down Expand Up @@ -749,7 +757,10 @@ static string Build(Project project, string path, OutputType type)
Compiler.OutputWriteLine("->");
}

Run(compiler, compileCmd);

var output = Run(compiler, compileCmd);

ProcessOutput(output);

if (IO.File.Exists(outFile))
{
Expand Down Expand Up @@ -797,6 +808,23 @@ static string Build(Project project, string path, OutputType type)
return path;
}

static void ProcessOutput(string output)
{
// wix.exe : error WIX0144: The extension 'WixToolset.UI.wixext' could not be found. Checked paths: WixToolset.UI.wixext,
// C:\Users\user\.wix\extensions\WixToolset.UI.wixext\5.0.0-rc.2\wixext4\WixToolset.UI.wixext.dll

if (output.Contains("error WIX0144") &&
output.Contains("WixToolset.UI.wixext") &&
output.Contains("5.0.0-rc.2"))
{
Compiler.OutputWriteLine("\nWARNING: It looks like your msi requires WixToolset.UI.wixext and the latest version found on this PC " +
"is v5.0.0-rc.2.\nThis extension version is known as being broken so you have to use any other version released by the WiX team.\n" +
"You can do this by installing a newer version of this extension or by specifying the desired (even older) working version " +
"explicitly in your msi build script (e.g. setup.cs) before calling `project.BuiuldMsi(...)`:\n\n" +
" WixExtension.UI.PreferredVersion = \"4.0.4\";\n");
}
}

/// <summary>
/// Builds the WiX source file (*.wxs) from the specified <see cref="Project"/> instance for further compiling into MSI file.
/// </summary>
Expand Down Expand Up @@ -3514,10 +3542,11 @@ static XElement AddDir(XElement parent, Dir wDir)

internal static object WiX_Tools = new object();

internal static void Run(string exe, string args, string workingDir = null)
internal static string Run(string exe, string args, string workingDir = null)
{
lock (WiX_Tools)
{
var runOutput = new StringBuilder();
string file = exe.IsAbsolutePath() ? exe : ExternalTool.Locate(exe);

Process p = new Process();
Expand All @@ -3543,16 +3572,23 @@ internal static void Run(string exe, string args, string workingDir = null)
p.StartInfo.CreateNoWindow = true;
p.Start();

void OnOutputLine(string line)
{

Compiler.OutputWriteLine(line);
Trace.WriteLine(line);
ToolsOutputReceived?.Invoke(line + Environment.NewLine);
runOutput.AppendLine(line);
}

ThreadPool.QueueUserWorkItem(x =>
{
string line = "";
while (null != (line = p.StandardError.ReadLine()))
{
lock (p)
{
Compiler.OutputWriteLine(line);
Trace.WriteLine(line);
ToolsOutputReceived?.Invoke(line + Environment.NewLine);
OnOutputLine(line);
}
}
});
Expand All @@ -3563,14 +3599,13 @@ internal static void Run(string exe, string args, string workingDir = null)
{
lock (p)
{
OutputWriteLine(line);
Trace.WriteLine(line);
ToolsOutputReceived?.Invoke(line + Environment.NewLine);
OnOutputLine(line);
}
}
}

p.WaitForExit();
return runOutput.ToString();
}
}

Expand Down
22 changes: 22 additions & 0 deletions Source/src/WixSharp/WixExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;

namespace WixSharp
Expand Down Expand Up @@ -85,6 +86,27 @@ public override string ToString()
return XmlNamespace;
}

/// <summary>
/// The preferred version of the Wix Extension package.
/// <para>Despite being an instance property the property value is shared by the all instances of the extension of a specific
/// stored WiX extension type.</para>
/// IE `WixExtension.UI.PreferredVersion = "4.0.4"`.
/// </summary>
public string PreferredVersion
{
get => preferredVersion.ContainsKey(this.Assembly) ? preferredVersion[this.Assembly] : null;
set => preferredVersion[this.Assembly] = value;
}

internal static string GetPreferredVersion(string assembly)
{
if (assembly.IsEmpty())
return null;
return preferredVersion.ContainsKey(assembly) ? preferredVersion[assembly] : null;
}

static Dictionary<string, string> preferredVersion = new Dictionary<string, string>();

/// <summary>
/// Creates XElement based on XName (XNamespace and specified name) and specified attributes.
/// <param name="name">Name of the element.</param>
Expand Down

0 comments on commit 85e5ff4

Please sign in to comment.