首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该如何在msbuild脚本中引用sn.exe?

我应该如何在msbuild脚本中引用sn.exe?
EN

Stack Overflow用户
提问于 2012-10-08 20:35:07
回答 6查看 4.2K关注 0票数 4

我需要在构建完成后对我的程序集重新签名(我已经对它做了一些其他的事情),所以我首先添加了一个名为C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\sn.exe<Exec>任务。这必须适用于其他开发人员/环境,所以我希望我可以从该文件夹复制sn.exesn.exe.config,并将其存储在我们的代码存储库中,这样我就可以从已知位置调用它的通用版本。

sn.exe在sdk目录之外孤立地崩溃,所以我想知道如何在不知道它在什么路径下的情况下引用它。不同的人有不同的环境(x86与x64,不同的安装目录,不同的版本),所以我希望能够轻松地引用该工具的最新版本(或者任何版本)。看起来是一个足够简单的工具,也许有另一种方法可以用另一个工具/命令/msbuild任务对程序集进行签名?任何帮助都将不胜感激。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-07-13 01:49:28

要在msbuild脚本中以适合大多数人的方式正确引用像snsqlmetal这样的工具,您必须考虑操作环境和框架实现的不同方面。主要有两种情况: Microsoft Windows和Microsoft的框架实现,然后是其他一切(我指的是Mono/unix)。

微软

然而,正如问题所暗示的那样,sn或其他工具所在的FrameworkSdkPath中的确切位置无法直接确定。参考答案表明,FrameworkSdkPath下用于存放工具的唯一可能文件夹是binbin/NETFX 4.0 Tools。但是,其他值也是可能的(Visual Studio2013预览版使用bin/NETFX 4.5.1 Tools)。因此,搜索sn的唯一正确方法是使用glob表达式或递归搜索它。我很难弄清楚如何使用MSBuild进行全局扩展,而且内置的MSBuild任务似乎不支持在FrameworkSdkPath下搜索特定的实用程序。但是,cmd的WHERE具有此功能,可用于执行搜索。结果类似于下面的msbuild代码:

代码语言:javascript
复制
<Target Name="GetSNPath" BeforeTargets="AfterBuild">
  <GetFrameworkSdkPath>
    <Output TaskParameter="Path" PropertyName="WindowsSdkPath" />
  </GetFrameworkSdkPath>
  <Exec Command="WHERE /r &quot;$(WindowsSdkPath.TrimEnd('\\'))&quot; sn &gt; sn-path.txt"  />
  <ReadLinesFromFile File="sn-path.txt">
    <Output TaskParameter="Lines" PropertyName="SNPath"/>
  </ReadLinesFromFile>
  <Delete Files="sn-path.txt" />
  <PropertyGroup>
    <SNPath>$([System.Text.RegularExpressions.Regex]::Replace('$(SNPath)', ';.*', ''))</SNPath>
  </PropertyGroup>
</Target>

(请参阅Property Functions以了解为什么我可以在此处使用String.TrimEndWHERE不喜欢尾随的斜杠。此更改可确保只找到一个结果,并确保<Exec/>实际成功。)

现在,您可以使用<Exec Command="&quot;$(SNPath)&quot;" />调用sn

便携

不出所料,在除sn之外的任何操作系统上,解析到Window的路径都要简单得多。在Mac和任何Linux发行版上,我在PATH中找到了sn。在这种情况下,使用GetFrameworkSdkPath无济于事;事实上,这似乎返回了一个无法找到sn的路径,至少对于我在使用xbuild时测试的mono-2.10的旧版本是如此:

Mac FrameworkSdkPath上的

  • /Library/Frameworks/Mono.framework/Versions/2.10.5/lib/mono/2.0/usr/bin/sn是指向某个Linux安装的符号链接,FrameworkSdkPath/usr/lib64/mono/2.0sn/usr/bin/sn (这是一个使用mono).

调用<代码>d38的外壳脚本

因此,我们需要做的就是尝试执行sn。任何将其sn实现放在非标准位置的unix用户都已经知道适当地更新路径,因此构建脚本不需要搜索它。此外,WHERE在unix中也不存在。因此,在unix的情况下,我们希望用在unix上只输出sn的东西来替换第一个<Exec/>调用,并且在Windows上运行时仍然执行完整的搜索。为了区分类unix和Windows环境,我们使用了一个技巧,该技巧利用了unix shell的true命令和cmd标签语法的快捷方式。

代码语言:javascript
复制
:; echo 'I’m unix!'; exit $?
echo I’m Windows :-/

利用这一点,我们得到的GetSNPath任务如下所示:

代码语言:javascript
复制
<Target Name="GetSNPath" BeforeTargets="AfterBuild">
  <GetFrameworkSdkPath>
    <Output TaskParameter="Path" PropertyName="WindowsSdkPath" />
  </GetFrameworkSdkPath>
  <Exec Command=":; echo sn &gt; sn-path.txt; exit $?
WHERE /r &quot;$(WindowsSdkPath.TrimEnd('\\'))&quot; sn &gt; sn-path.txt"  />
  <ReadLinesFromFile File="sn-path.txt">
    <Output TaskParameter="Lines" PropertyName="SNPath"/>
  </ReadLinesFromFile>
  <Delete Files="sn-path.txt" />
  <PropertyGroup>
    <SNPath>$([System.Text.RegularExpressions.Regex]::Replace('$(SNPath)', ';.*', ''))</SNPath>
  </PropertyGroup>
</Target>

结果是一个可移植的方法,用于查找调用sn所需的字符串。最后一个解决方案允许您同时支持Microsoft及其msbuild以及使用xbuild的所有其他平台。它还克服了将bin\NETFX 4.0 Tools硬编码到.csproj文件中的问题,以同时支持微软工具的未来和当前版本。

票数 7
EN

Stack Overflow用户

发布于 2012-10-10 22:59:03

原来有一个名为"GetFrameworkSdkPath“的任务可以获取Windows SDK的位置。从那里,我必须测试sn.exe是否直接存在于bin文件夹中,或者是否存在于bin\NETFX 4.0 Tools\中。到目前为止似乎是可靠的。

代码语言:javascript
复制
<PropertyGroup>
  <SNExePath>NotSet</SNExePath>
</PropertyGroup>

<!-- Sometimes theres nothing in the WindowsSdkPath dir and there's stuff in a deeper folder called 'NETFX 4.0 Tools'. -->
<Target Name="GetSNPath" BeforeTargets="AfterBuild">
  <GetFrameworkSdkPath>
    <Output TaskParameter="Path" PropertyName="WindowsSdkPath" />
  </GetFrameworkSdkPath>
  <PropertyGroup>
    <SNExePath>$(WindowsSdkPath)bin\sn.exe</SNExePath>
  </PropertyGroup>
  <PropertyGroup>
    <SNExePath Condition="!Exists($(SNExePath))">$(WindowsSdkPath)bin\NETFX 4.0 Tools\sn.exe</SNExePath>
  </PropertyGroup>
</Target>  

<Target Name="AfterBuild">
  <Exec Command="$(SNExePath) -R $(TargetPath) $(SignatureFile)" />
</Target>
票数 7
EN

Stack Overflow用户

发布于 2013-10-04 01:02:07

我现在使用的方法涉及到使用一个属性函数在framework SDK path -ala下搜索SN.exe:

代码语言:javascript
复制
<GetFrameworkSDKPath>
  <Output TaskParameter="Path" PropertyName="DotNetFrameworkDir"/>
</GetFrameworkSDKPath>

<PropertyGroup>
  <SNPath>$([System.IO.Directory]::GetFiles("$(DotNetFrameworkDir)", "sn.exe", SearchOption.AllDirectories)[0])</SNPath>
</PropertyGroup>

到目前为止,我只在Visual Studio2013上亲自测试过,但文档暗示它应该回到Visual Studio2010。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12781870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档