如何在安装 Visual Studio 2017 的情况下获取 signtool.exe 的路径

How to get path to signtool.exe with Visual Studio 2017 installed

我接手了基于 Visual Studio 2012 年的项目。 通过以下方式找到 signtool.exe 的路径:

<SignToolPath Condition=" Exists('$(WindowsSDK80Path)bin\x86\signtool.exe') and '$(SignToolPath)'=='' and '$(PROCESSOR_ARCHITECTURE)'=='x86' ">$(WindowsSDK80Path)bin\x86\signtool.exe</SignToolPath>
<SignToolPath Condition=" Exists('$(WindowsSDK80Path)bin\x64\signtool.exe') and '$(SignToolPath)'=='' and '$(PROCESSOR_ARCHITECTURE)'=='AMD64' ">$(WindowsSDK80Path)bin\x64\signtool.exe</SignToolPath>

现在我想将项目移植到 Visual Studio 2017。 以这种方式安装后,获取路径不再有效 因为缺少 Windows SDK 8.

我已经安装了 Click Once 组件和 Windows 10 SDK。 因此 signtool.exe 可用。

谁能告诉我如何找到 Visual Studio 2017 的路径?

Can someone tell me how to find the path with Visual Studio 2017?

您可以根据配置从注册表中找到并设置 SignToolPath 变量:

<PropertyGroup>
  <WindowsKitsRoot>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot10', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
  <WindowsKitsRoot Condition="'$(WindowsKitsRoot)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot81', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
  <WindowsKitsRoot Condition="'$(WindowsKitsRoot)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
  <SignToolPath Condition=" '$(SignToolPath)' == '' And '$(Platform)' == 'AnyCPU' ">$(WindowsKitsRoot)bin\x86\</SignToolPath>
  <SignToolPath Condition="'$(SignToolPath)' == ''">$(WindowsKitsRoot)bin$(Platform)\</SignToolPath>
</PropertyGroup>

我们可以将此 属性 设置到我们的项目文件或 .target 文件中,然后将其导入到项目文件中。

或者,您可以将环境变量设置为SignToolPath,全局系统路径(通过控制面板->系统->高级系统设置->环境变量):

C:\Program Files (x86)\Windows Kits\bin\x86

希望对您有所帮助。

根据 Leo 的回复,这是我为 Windows 套件 10 更新的 PropertyGroup。它没有经过全面测试,但可以在我的机器上运行 ;-)

  <PropertyGroup>
    <!-- Windows Kits 10 -->
    <WindowsKitsRoot Condition="'$(WindowsKitsRoot)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot10', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
    <SignToolPath Condition="'$(WindowsKitsRoot)' != '' And '$(SignToolPath)' == '' And exists('$(WindowsKitsRoot)bin.0.18362.0\')">$(WindowsKitsRoot)bin.0.18362.0$(Platform)\</SignToolPath>
    <SignToolPath Condition="'$(WindowsKitsRoot)' != '' And '$(SignToolPath)' == '' And exists('$(WindowsKitsRoot)bin.0.18362.0\')">$(WindowsKitsRoot)bin.0.17763.0$(Platform)\</SignToolPath>
    <SignToolPath Condition="'$(WindowsKitsRoot)' != '' And '$(SignToolPath)' == '' And exists('$(WindowsKitsRoot)bin.0.18362.0\')">$(WindowsKitsRoot)bin.0.17134.0$(Platform)\</SignToolPath>
    <SignToolPath Condition="'$(WindowsKitsRoot)' != '' And '$(SignToolPath)' == '' And exists('$(WindowsKitsRoot)bin.0.18362.0\')">$(WindowsKitsRoot)bin.0.16299.0$(Platform)\</SignToolPath>

    <!-- Windows Kits 8 and older -->
    <WindowsKitsRoot Condition="'$(WindowsKitsRoot)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot81', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
    <WindowsKitsRoot Condition="'$(WindowsKitsRoot)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
    <SignToolPath Condition=" '$(SignToolPath)' == '' And '$(Platform)' == 'AnyCPU' ">$(WindowsKitsRoot)bin\x86\</SignToolPath>
    <SignToolPath Condition="'$(SignToolPath)' == ''">$(WindowsKitsRoot)bin$(Platform)\</SignToolPath>
  </PropertyGroup>

我最近发现了一个注册表项,其中包含 signtool.exe 所需的路径。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots] "WdkBinRootVersioned" = "C:\Program Files (x86)\Windows Kits\bin.0.18362.0\"

所以这对我有用:

<PropertyGroup>
    <WindowsKitsRoot>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'WdkBinRootVersioned', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
    <SignToolPath Condition="'$(SignToolPath)' == '' And '$(Platform)' == 'AnyCPU'">$(WindowsKitsRoot)x86\</SignToolPath>
    <SignToolPath Condition="'$(SignToolPath)' == ''">$(WindowsKitsRoot)$(Platform)\</SignToolPath>
</PropertyGroup>

根据 Leo 的回复,该版本独立于 Windows Kits 版本,但它使用 Target。 $(SignToolPath) 将包含 signtool.exe.

的路径

主要思想在 MSBuild 中使用标准排序顺序并设置为 属性 SignToolPath 项组 SignToolPaths 的最后一项

<Target Name="ResolveSignToolPath" BeforeTargets="SignFile">
    <ItemGroup>
        <KitsRegKeys Include="KitsRoot" />
        <KitsRegKeys Include="KitsRoot81" />
        <KitsRegKeys Include="KitsRoot10" />
        <KitsRegKeyValues Include="@(KitsRegKeys)">
            <Value>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', '%(KitsRegKeys.Identity)', null, RegistryView.Registry32, RegistryView.Default))</Value>
        </KitsRegKeyValues>
    </ItemGroup>
    <PropertyGroup>
        <WindowsKitsRoot>%(KitsRegKeyValues.Value)</WindowsKitsRoot>
        <SignToolPlatform Condition="'$(SignToolPlatform)'=='' And '$(Platform)'!='AnyCPU'">$(Platform)</SignToolPlatform>
        <SignToolPlatform Condition="'$(SignToolPlatform)'==''">x86</SignToolPlatform>
    </PropertyGroup>
    <ItemGroup>         
        <SignToolPaths Include="$(WindowsKitsRoot)bin\**$(SignToolPlatform)\signtool.exe"/>
    </ItemGroup>
    <PropertyGroup>
        <SignToolPath>%(SignToolPaths.Identity)</SignToolPath>
    </PropertyGroup>        
    <Error Condition="'$(SignToolPath)'=='' Or !Exists('$(SignToolPath)')"
       Text="In order to sign file, this package requires access to the signtool.exe tool from the Windows Kits, which was not found. Please either: 1) Supply a correct path to your Windows Kits bin directory containing signtool.exe by setting %24(SignToolPath) OR 2) Install Windows Kits" />
    <!-- <Message Text="Signing $(SignToolPath)" Importance="high" />        -->
</Target>