我创建了一个构建后事件,以便在使用以下构建后脚本成功构建后对应用程序进行代码签名。
copy $(TargetPath) $(TargetDir)SignedApp.exe
signtool sign /t http://timestamp.verisign.com/scripts/timestamp.dll /a $(TargetDir)SignedApp.exe
我收到错误 'signtool' 未被识别为内部或外部命令。
因此,用于构建事件的路径似乎并未指向 signtool 实用程序。当我运行 VS2013 x86 native 工具命令提示符 我可以运行 signtool,因为它包含一个指向的路径:
C:\Program Files (x86)\Windows Kits\8.1\bin\x86
我可以将此路径硬编码到我的构建事件中
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool" sign /t http://timestamp.verisign.com/scripts/timestamp.dll /a $(TargetDir)SignedApp.exe
然而,这似乎是不可移植的。如何获得为 定义的相同路径 native 命令提示符 在没有硬编码的情况下被我的后期构建事件使用?我查看了宏列表,但没有找到任何有用的。
最佳答案
我首先发现了这个问题,所以我会发布我最终选择的答案。
在此过程中,我查看了另一个答案和一些文档:
Path to SignTool.exe or "Windows Kits" directory when using Visual Studio 2012
https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=vs-2017
我的解决方案最终将这个大 PropertyGroup 添加到 csproj 文件中:
<PropertyGroup>
<!-- Find Windows Kit path and then SignTool path for the post-build event -->
<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' and Exists('$(WindowsKitsRoot)bin\x64\signtool.exe')">$(WindowsKitsRoot)bin\x64\</SignToolPath>
<SignToolPath Condition="'$(SignToolPath)' == '' And Exists('$(WindowsKitsRoot)bin\$(Platform)\signtool.exe')">$(WindowsKitsRoot)bin\$(Platform)\</SignToolPath>
<SignToolPathBin Condition="'$(SignToolPath)' == ''">$([System.IO.Directory]::GetDirectories('$(WindowsKitsRoot)bin',"10.0.*"))</SignToolPathBin>
<SignToolPathLen Condition="'$(SignToolPathBin)' != ''">$(SignToolPathBin.Split(';').Length)</SignToolPathLen>
<SignToolPathIndex Condition="'$(SignToolPathLen)' != ''">$([MSBuild]::Add(-1, $(SignToolPathLen)))</SignToolPathIndex>
<SignToolPathBase Condition="'$(SignToolPathIndex)' != ''">$(SignToolPathBin.Split(';').GetValue($(SignToolPathIndex)))\</SignToolPathBase>
<SignToolPath Condition="'$(SignToolPath)' == '' And '$(SignToolPathBase)' != '' And '$(Platform)' == 'AnyCPU'">$(SignToolPathBase)x64\</SignToolPath>
<SignToolPath Condition="'$(SignToolPath)' == '' And '$(SignToolPathBase)' != ''">$(SignToolPathBase)$(Platform)\</SignToolPath>
</PropertyGroup>
我需要很多额外的中间属性,因为我机器上的 Windows SDK 没有安装
signtool.exe
在 <root>\bin\x64\signtool.exe
而是在另一个目录级别下,即我绝对不想硬编码的 SDK 版本。然后在后期构建中我可以使用这个
"$(SignToolPath)signtool.exe"
关于visual-studio-2013 - 如何在没有硬编码路径的 Visual Studio 2013 后构建事件中使用 signtool?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44556393/