Jon*_*onN 4 path post-build-event signtool visual-studio-2013
我创建了一个构建后事件,以便在使用以下构建后脚本成功构建后对应用程序进行代码签名。
copy $(TargetPath) $(TargetDir)SignedApp.exe
signtool sign /t http://timestamp.verisign.com/scripts/timestamp.dll /a $(TargetDir)SignedApp.exe
Run Code Online (Sandbox Code Playgroud)
我收到错误 “signtool”未被识别为内部或外部命令。 因此,用于构建事件的路径似乎并未指向 signtool 实用程序。当我运行VS2013 x86 Native Tools Command Prompt 时,我可以运行 signtool,因为它包含一个指向:
C:\Program Files (x86)\Windows Kits\8.1\bin\x86
Run Code Online (Sandbox Code Playgroud)
我可以将此路径硬编码到我的构建事件中
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool" sign /t http://timestamp.verisign.com/scripts/timestamp.dll /a $(TargetDir)SignedApp.exe
Run Code Online (Sandbox Code Playgroud)
然而,这似乎是不可移植的。如何在没有硬编码的情况下获得为本地命令提示符定义的相同路径以供我的后期构建事件使用?我查看了宏列表,但没有找到任何有用的。
web*_*rgm 11
我首先发现了这个问题,所以我会发布我最终选择的答案。
在此过程中,我查看了另一个答案和一些文档:
使用 Visual Studio 2012 时 SignTool.exe 或“Windows Kits”目录的路径
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>
Run Code Online (Sandbox Code Playgroud)
我需要很多额外的中间属性,因为我机器上的 Windows SDK 没有安装signtool.exe在<root>\bin\x64\signtool.exe另一个目录级别下,这是我绝对不想硬编码的 SDK 版本。
然后在后期构建中我可以使用它 "$(SignToolPath)signtool.exe"
我决定的解决方案是:
REM If SIGNTOOL environment variable is not set then try setting it to a known location
if "%SIGNTOOL%"=="" set SIGNTOOL=%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86\signtool.exe
REM Check to see if the signtool utility is missing
if exist "%SIGNTOOL%" goto OK1
REM Give error that SIGNTOOL environment variable needs to be set
echo "Must set environment variable SIGNTOOL to full path for signtool.exe code signing utility"
echo Location is of the form "C:\Program Files (x86)\Windows Kits\8.1\x86\bin\signtool.exe"
exit -1
:OK1
echo Copying $(TargetFileName) to $(TargetDir)SignedApp.exe
copy $(TargetPath) $(TargetDir)SignedApp.exe
"%SIGNTOOL%" sign /t http://timestamp.verisign.com/scripts/timestamp.dll /a $(TargetDir)SignedApp.exe
Run Code Online (Sandbox Code Playgroud)
这是@Dennis Kuypers 建议 #4 的变体。开发人员必须将环境变量 SIGNTOOL 设置到正确的位置。如果他们无法做到这一点,那么就会尝试一个已知的可能位置。如果失败,则会报告错误,指示他们适当地设置 SIGNTOOL env var。
我确实发现有一个环境变量WindowsSdkDir
WindowsSdkDir=C:\Program Files (x86)\Windows Kits\8.1\
Run Code Online (Sandbox Code Playgroud)
但同样,这仅在运行本机命令提示符时设置,因此在运行构建后事件脚本时未定义。
| 归档时间: |
|
| 查看次数: |
5587 次 |
| 最近记录: |