Search code examples
cakebuild

Pickig the right SignTool with Cake build script


I have a problem with Cakes Sign method. On my own PC it works like a charm, but on the build server, it apparently finds an older version of SignTool.exe, that does not support the /as switch (AppendSignature = true in SignToolSettings). Searching the buildserver there are 15 instances in "Program Files (x86)" alone. With dates ranging from 2010 to 2019. What can I do to help Cake pick the right SignTool?

I'm using Cake 0.34.1

Edit:

devlead's solution is definitely a viable one, but having to instruct every developer to set environment variables for location of tools, might not always be desirable.

To add to the complexity, my build script uses three tools from the WinSDK, and they don't even necessarily live in the same directory on one machine.

I have come up with a solution that builds on empirical knowledge of possible locations of the tools in a prioritized list:

FilePath LocateTool(FilePath tool, IEnumerable<DirectoryPath> possiblePaths)
{
   return possiblePaths.FirstOrDefault(p => FileExists(p.CombineWithFilePath(tool).FullPath))?.CombineWithFilePath(tool) ?? throw new CakeException($"Tool {tool} not found");
}
///////////////////////////////////////////////////////////////////////////////
// SETUP / TEARDOWN
///////////////////////////////////////////////////////////////////////////////

Setup(ctx =>
{
   var WinKitPaths = new List<DirectoryPath>()
      .Append("C:/Program Files (x86)/Windows Kits/10/bin/x86")
      .Append("C:/Program Files (x86)/Windows Kits/8.1/bin/x86")
      .Append("C:/Program Files (x86)/Windows Kits/8.0/bin/x86");
   ctx.Tools.RegisterFile(LocateTool("stampinf.exe", WinKitPaths));
   ctx.Tools.RegisterFile(LocateTool("inf2cat.exe", WinKitPaths));
   ctx.Tools.RegisterFile(LocateTool("signtool.exe", WinKitPaths));
});

This solution needs no messing with environment vars, but additional paths might need to be added along the way.


Solution

  • By default Cake will use Windows SDK Paths found in registry for resolving SignTool.exe, if no SDK path found in registry it'll try known paths is program files.

    It starts with Windows 10 SDK, then Windows 8 and last Windows 7, so normally it should at least try to pick latest, you can see logic in SignToolResolver.cs.

    So might be that installing Windows 10 SDK on your build server will solve the issue.

    All Cake tool paths can be overridden though, so if you already have latest installed and Cake can't resolve it automatically, then you can specify it on SignToolSignSettings.

    One way to do this could be through using an environment variable on the build server

    var signToolSettings = new SignToolSignSettings {
        ToolPath = EnvironmentVariable("SignToolPath")
    };
    

    If variable not specified it'll use the default tool resolution, if environment variable set before launching i.e.

    Setting SignToolPath environment variable to 'C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe', then that path will be used regardless.