使用 Visual Studio 2012 时 SignTool.exe 或“Windows Kits”目录的路径
Posted
技术标签:
【中文标题】使用 Visual Studio 2012 时 SignTool.exe 或“Windows Kits”目录的路径【英文标题】:Path to SignTool.exe or "Windows Kits" directory when using Visual Studio 2012 【发布时间】:2012-12-29 13:13:06 【问题描述】:使用 Visual Studio 2012 时如何获取 SignTool.exe 的路径?
在 Visual Studio 2010 中,您可以使用
<Exec Command=""$(FrameworkSDKDir)bin\signtool.exe" sign /p ... />
$(FrameworkSDKDir)
在哪里
"c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\"
但在 Visual Studio 2012 中,$(FrameworkSDKDir)
是
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\"
SignTool 在
"c:\Program Files (x86)\Windows Kits\8.0\bin\x64\"
除了硬编码之外,有没有办法获得这个目录的路径(我试过FrameworkSDKDir
和WindowsSDKDir
,但都指向v8.0A目录)。
(我知道 SignFile MSBuild 任务,但我不能使用它,因为它不接受证书密码。)
【问题讨论】:
$(FrameworkSdkDir) 指向我机器上的 Windows 工具包。不要与 $(FrameworkSDKRoot) 混淆,您的问题中大小写错误。 MSBuild 属性在我的测试中不区分大小写。 FrameworkSDKRoot / FrameworkSdkDir 指向我项目中的同一个地方 - C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\ @Ryan 他们可能指向同一个地方,但这不是区分大小写的问题。 @EdwardThomson - 确定吗?在 MSBUILD 中获取您关心的任何属性,并使用 CraZY cAse 通过消息输出 - 它会起作用。试试看! @Ryan - 我是说FrameworkSdkDir
和FrameworkSdkRoot
大小写不同,但内容不同。
【参考方案1】:
我刚刚遇到了同样的问题。从 Visual Studio 2012 命令提示符运行构建工作,但它在 IDE 中失败。在寻找详细或诊断日志时,我找到了What is the default location for MSBuild logs?,它告诉我 Visual Studio 无法提供我真正需要的诊断信息。
这是我最终修复它的方法。
打开一个普通的命令提示符(不是 Visual Studio 命令提示符),并通过完全限定 MSBuild 的路径 (%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe) 来运行 msbuild。这最终给了我在 Visual Studio 2012 中收到的相同错误消息(错误代码 9009)。
然后,通过附加 /v:diag 开关,使用“诊断”日志记录(显示所有属性和项目值)运行相同的构建。
从这个输出中,我了解到它确实有一些新属性,我可以使用这些属性来获取 signtool.exe 的位置(摘录如下):
windir = C:\Windows
windows_tracing_flags = 3
windows_tracing_logfile = C:\BVTBin\Tests\installpackage\csilogfile.log
WindowsSDK80Path = C:\Program Files (x86)\Windows Kits\8.0\
WIX = C:\Program Files (x86)\WiX Toolset v3.7\
因此,我对这个问题的解决方案是将以下内容添加到我的 *.targets 文件中:
<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>
希望这对您也有帮助。我在前言中包含了我是如何做到这一点的,因为还有其他可用的属性可能更适合您的目的。
【讨论】:
这是两年前的,但您能解释一下您是如何将它添加到您的目标中的吗?我的解决方法是添加到构建后事件: IF EXIST "C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe" "C:\Program Files (x86)\Windows Kits\8.0 \bin\x86\signtool.exe" 签名 /a /d "QA" $(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)\QA.exe【参考方案2】:好的,因为这是 google 上第一次点击“SignTool.exe not found on buildserver”,我将添加 VisualStudio 2015 和 Windows 10 Enterprise 64bit 的附加信息。
我必须在 VisualStudio 设置中添加 ClickOnce 发布工具:
在此之后你会在
中找到signtool.exe c:\Program Files (x86)\Windows Kits\8.1\bin\x64\ c:\Program Files (x86)\Windows Kits\8.1\bin\x86\ c:\Program Files (x86)\Windows Kits\8.1\bin\arm\安装了 Visual Studio 2017 后,它位于
C:\Program Files (x86)\Windows Kits\10\bin\arm\signtool.exe C:\Program Files (x86)\Windows Kits\10\bin\arm64\signtool.exe C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe C:\Program Files (x86)\Windows Kits\10\bin\x86\signtool.exe在 Visual Studio 2017 15.7.4 中,路径会根据您安装的所选 Windows 10 工具包再次更改。
您将通过启动 Visual Studio 2017 开发人员命令提示符 获得通用路径
然后输入
where signtool.exe
【讨论】:
如果你已经安装了VS2015,你可以去控制面板->添加/删除程序->右键单击MS Visual Studio并选择更改重新运行这个安装向导并添加上面的选项【参考方案3】:下面是一个更通用的方法,可以根据构建机器的具体配置来查找和设置SignToolPath
变量;通过读取注册表:
<PropertyGroup>
<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)' == ''">$(WindowsKitsRoot)bin\$(Platform)\</SignToolPath>
</PropertyGroup>
这假定$(Platform)
解析为arm
、x86
或x64
之一。否则将$(Platform)
宏替换为相应的目录。
编辑(2017.07.05):
这是一个更新的<PropertyGroup>
,它遵循新的 Windows 10 工具包并将($Platform)=='AnyCPU'
强制转换为x86
:
<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>
【讨论】:
如果您使用AnyCPU
和特定平台进行编译,那么您将需要以下两个条件语句:
<SignToolPath Condition=" '$(SignToolPath)' == '' And '$(Platform)' == 'AnyCPU' ">$(WindowsKitsRoot)bin\x64\</SignToolPath>
<SignToolPath Condition="'$(SignToolPath)' == ''">$(WindowsKitsRoot)bin\$(Platform)\</SignToolPath>
@Randy Walker,Condition="'$(SignToolPath)'==''"
会阻止设置该属性。因此,操作系统中的环境变量将防止它在构建过程中被覆盖。<WindowsKitsRoot>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot10', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
。
@RandyWalker,此外,还要检查构建环境中的其他.targets
文件是否调用GetRegistryValueFromView()
,以防参数(例如RegistryView.Registry32
)与上述相同。 【参考方案4】:
Resolve-Path "C:\Program Files*\Windows Kits\*\bin\*\signtool.exe"
输出:
Path
----
C:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe
C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe
C:\Program Files (x86)\Windows Kits\8.1\bin\arm\signtool.exe
C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe
C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe
【讨论】:
【参考方案5】:因为对我来说,今天(20/07/2020)之前的所有建议都失败了,尽管其中大多数在过去都有效,但我决定发布一个更全面的方法,该方法也解决了后来的 Windows 10 SDK 位置,同时仍然使用旧的作为后备。
<PropertyGroup Label="UserDefinedVariables">
<!-- Get Windows SDK root folder-->
<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>
<!-- Evaluates the most recent Windows SDK folder containing SignTool.exe -->
<!-- add new versions here, duplicating following line -->
<SignToolFolder Condition="'$(SignToolFolder)' == '' And exists('$(WindowsKitsRoot)bin\10.0.18362.0\x64\Signtool.exe')">$(WindowsKitsRoot)bin\10.0.18362.0\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == '' And exists('$(WindowsKitsRoot)bin\10.0.17763.0\x64\Signtool.exe')">$(WindowsKitsRoot)bin\10.0.17763.0\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == '' And exists('$(WindowsKitsRoot)bin\10.0.17134.0\x64\Signtool.exe')">$(WindowsKitsRoot)bin\10.0.17134.0\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == '' And exists('$(WindowsKitsRoot)bin\10.0.16299.0\x64\Signtool.exe')">$(WindowsKitsRoot)bin\10.0.16299.0\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == '' And exists('$(WindowsKitsRoot)bin\10.0.15063.0\x64\Signtool.exe')">$(WindowsKitsRoot)bin\10.0.15063.0\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == '' And exists('$(WindowsKitsRoot)bin\10.0.14393.0\x64\Signtool.exe')">$(WindowsKitsRoot)bin\10.0.14393.0\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == '' And '$(Platform)' == 'AnyCPU' ">$(WindowsKitsRoot)bin\x64\</SignToolFolder>
<SignToolFolder Condition="'$(SignToolFolder)' == ''">$(WindowsKitsRoot)bin\$(Platform)\</SignToolFolder>
<!-- Now we should be able to calculate SignTool.exe fullpath -->
<SignToolExe Condition=" '$(SignToolFolder)' != '' ">$(SignToolFolder)SignTool.exe</SignToolExe>
</PropertyGroup>
<!-- Finally, I would suggest you add the following lines to your project file because they will be quite usefull when things go wrong (and they will) -->
<!-- Send indivual compile bessages to MSBuild output so you check the value of each variable -->
<Target Name="ShowUserDefinedVariables" BeforeTargets="BeforeBuild">
<Message Importance="High" Text="WindowsKitsRoot = $(WindowsKitsRoot)" />
<Message Importance="High" Text="SignToolFolder = $(SignToolFolder)" />
<Message Importance="High" Text="SignToolExe = $(SignToolExe)" />
</Target>
【讨论】:
【参考方案6】:我使用的这种方法仅依赖于标准构建事件:
powershell -Command "(Resolve-Path \"C:\Program Files (x86)\\Windows Kits\\10\\bin\\*\\x64\" | Select-Object -Last 1).Path" > stpath
set /p STPATH=<stpath
del stpath
"%STPATH%\signtool.exe" sign ..........
随着新的 Windows SDK 安装并选择最新的,它将应对新的路径。
【讨论】:
【参考方案7】:我假设正在使用 signtool 对可执行文件或 dll 进行签名。在 Visual Studio 2019 中,有一个 Developer 命令行,它提供了 Developer Cmd 和 Developer Powershell。这两个选项都可以自动解析signtool,无需担心当前的Windows SDK。
如果我们想从原生 powershell 使用 Developer Powershell,那么我们只需要为 Developer Powershell 导入模块。要导入模块,我们需要在原生 powershell 中运行以下行:
&Import-Module "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"; Enter-VsDevShell 5ee267ff
5ee267ff
的位置因每台机器而异。您可以在 Developer Powershell 快捷方式的属性中找到它。
导入模块后,我们甚至可以从本机 powershell 解析 signtool。最后,我们可以在项目的构建后事件中添加一个脚本,以便该脚本导入 Developer powershell,然后我们可以简单地使用 signtool 进行签名。
【讨论】:
以上是关于使用 Visual Studio 2012 时 SignTool.exe 或“Windows Kits”目录的路径的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 2010 的 Visual C++ 2012 运行时库先决条件
使用 Visual Studio 2012 时 SignTool.exe 或“Windows Kits”目录的路径
在 Visual Studio 2012 Ultimate 中的 Windows 中使用 OpenSSL 时出错
Visual Studio 2010 项目到 Visual Studio 2012