4

ビルドが完了した後にアセンブリに再署名する必要があるため (そして、アセンブリに他の<Exec>作業を行った後) C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\sn.exe、. sn.exeこれは他の開発者/環境でも機能する必要があるため、そのフォルダーからコピーしsn.exe.configてコードリポジトリに保存し、既知の場所から常に共通バージョンを呼び出すことができることを望んでいました.

sn.exesdk ディレクトリの外で単独でクラッシュするので、どのパスの下にあるのかわからないまま参照する方法を考えています。人によって環境が異なる (x86 と x64、異なるインストール ディレクトリ、異なるバージョン) ため、ツールの最新バージョン (またはおそらく任意のバージョン) を簡単に参照できるようにしたいと考えています。単純なツールのように思えますが、別のツール/コマンド/msbuild タスクでアセンブリに署名する別の方法があるのではないでしょうか? どんな助けでも大歓迎です。

4

6 に答える 6

7

snほとんどの人にとって機能する方法で msbuild スクリプトでor (私が求めているもの)のようなツールを適切に参照するsqlmetalには、動作環境とフレームワークの実装のさまざまな側面を考慮する必要があります。主なケースは 2 つあります。Microsoft Windows と、Microsoft によるフレームワークの実装と、その後に続くその他すべて (Mono/unix を意味します) です。私が考えることができる状況をサポートする正しいアプローチの例は、最後にリストされています.

マイクロソフト

snWindows のどこに、または他の同様のツールが存在するかを見つける適切な方法は、既に述べたように、 GetFrameworkSdkPath タスクから開始することです。

ただし、質問が示唆するように、FrameworkSdkPath 内snまたは別のツールが存在する正確な場所を直接特定することはできません。bin参照された回答は、ツールが存在する FrameworkSdkPath の下にある唯一の可能なフォルダーはとであることを示唆していますbin/NETFX 4.0 Tools。ただし、他の値も使用できます (Visual Studio 2013 プレビューでは を使用しますbin/NETFX 4.5.1 Tools)。したがって、検索する唯一の適切な方法snは、グロブ式を使用するか、再帰的に検索することです。MSBuild でグロブ展開を行う方法がわかりません。組み込みの MSBuild タスクは、特定のユーティリティの FrameworkSdkPath での検索をサポートしていないようです。ただし、cmdWHEREにはこの機能があり、検索に使用できます。結果は、次の msbuild コードのようになります。

<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>

(ここで使用できる理由については、プロパティ関数を参照してください。末尾のスラッシュが好きではありません。編集:プロパティ関数の使用を追加して、プロパティ内の最初に見つかったパス以外のすべてを削除するアクセスを追加しました。友人のマシンの呼び出しの 1 つで、複数の特定のコマンドの結果を取得し、fond ツールへの試行を中断しました. この変更により、結果が 1 つだけ見つかり、実際に成功することが保証されます.)String.TrimEndWHERERegex.Replace()SNPathWHERE<Exec/><Exec/>

で呼び出すことができるようsnになりまし<Exec Command="&quot;$(SNPath)&quot;" />た。

ポータブル

当然のことながら、パスの解決は、snWindows 以外のオペレーティング システムでははるかに簡単です。Mac OSX および Linux の任意のディストリビューションでsnは、PATH に含まれています。このような状況では、を使用GetFrameworkSdkPathしても役に立ちません。実際、sn少なくとも xbuild を使用してテストした古いバージョンの mono-2.10 では、これは見つからないパスを返すようです。

  • Mac OSXFrameworkSdkPathでは/Library/Frameworks/Mono.framework/Versions/2.10.5/lib/mono/2.0、 および/usr/bin/snは へのシンボリック リンク/Library/Frameworks/Mono.framework/Commands/snです。
  • 特定の Linux インストールでは、FrameworkSdkPathis/usr/lib64/mono/2.0およびsnis (で/usr/bin/sn呼び出すシェル スクリプト)。/usr/lib64/mono/4.0/sn.exemono

したがって、必要なことは を実行することだけsnです。非標準の場所に実装を配置する UNIX ユーザーsnは、PATH を適切に更新することを既に知っているため、ビルド スクリプトでそれを検索する必要はありません。また、WHEREunix には存在しません。したがって、UNIX の場合、最初の<Exec/>呼び出しをsn、UNIX でのみ出力し、Windows で実行したときに完全な検索を行うものに置き換えたいと考えています。trueUNIX ライクな環境と Windows 環境を区別するために、UNIX シェルのコマンドとコマンドのラベル構文のショートカットを利用するトリックを使用します。簡単な例として、次のスクリプトはI’m unix!UNIX シェルアウトとI’m Windows :-/Windows シェルアウトで出力します。

:; echo 'I’m unix!'; exit $?
echo I’m Windows :-/

これを利用して、結果のGetSNPathTask は次のようになります。

<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 ファイルへのハードコーディングを克服して、Microsoft ツールの将来および現在のバージョンを同時にサポートします。

于 2013-07-12T17:49:28.080 に答える
2

私が現在使用している方法では、プロパティ関数を使用して、フレームワーク SDK パスの下で SN.exe を検索します - ala:

<GetFrameworkSDKPath>
  <Output TaskParameter="Path" PropertyName="DotNetFrameworkDir"/>
</GetFrameworkSDKPath>

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

これまでのところ、私はこれを Visual Studio 2013 で個人的にテストしただけですが、ドキュメントによると、Visual Studio 2010 でも動作するはずです。

于 2013-10-03T17:02:07.430 に答える
1

実行可能ファイルを参照する各開発マシンで環境変数を作成できます。これは、MSBuild でプロパティとして参照できます。

そのため、システム プロパティの詳細タブから環境変数を作成します。私は通常、現在のユーザーをスコープとするシステム環境変数ではなく、システム環境変数を作成するだけです。それを取得するには、Visual Studio を再起動する必要があります。

次に、MSBuild で参照します。

<Exec Command="$(SnExe)">

SnExe定義した環境変数はどこにありますか。

于 2012-10-09T02:23:07.363 に答える
1

$(SDK40ToolsPath) 変数の価値は、同様の状況で私にとって役に立ちました。これにより、どのバージョンのツールがインストールされているかを知る必要がなくなります。

  <PropertyGroup>
    <XsdExePath>$(SDK40ToolsPath)xsd.exe</XsdExePath>
  </PropertyGroup>
  <Target Name="BeforeBuild">
    <ItemGroup>
      <xsd Include="Objects.xsd" />
    </ItemGroup>
    <Exec Command="&quot;$(XsdExePath)&quot; @(xsd) /c /namespace:Blah.Objects" />
  </Target>
于 2016-01-20T02:11:55.037 に答える