20

Visual Studio では、ドロップダウン ボタンからAdd->Existing Itemを実行できます。Add as LinkAdd

これは素晴らしい。これにより、別のプロジェクトからファイルを追加できます。ファイルを編集すると、元のプロジェクトでも編集されます。

この機能を使用して、構成ファイル (Shared.config という名前) を 1 つのソリューション内のすべてのプロジェクトに存在させたいと考えています。そして、そのファイルを常に同じにしてください。

ソリューション
|
|- プロジェクト 1
| - Shared.config [物理]
|- プロジェクト 2
| - Shared.config [リンク済み]

パブリッシュ後、ファイルは実際にパブリッシュされたすべてのプロジェクトで終了するため、問題はありません。

しかし、公開前 (ビルドの開発中) には、リンクされたファイルは実際には存在しません。Windows エクスプローラーでファイルを表示しようとすると、ファイルがプロジェクト ディレクトリにないことがわかります。Visual Studio は、ソリューション エクスプローラーに存在するかのように見せるだけです。(ビルド時に、リンクされたアイテムはおそらくディレクトリにコピーされbinますが、ディレクトリからファイルを使用/アクセスしたくありませんbin。)

今、これはもちろん問題を引き起こします。System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("Shared.config"))Shared.config がプロジェクトのルート ディレクトリにまだ存在しないため、プロジェクトが発行される前に印刷しようとすると失敗します。

私がやりたいことと、あなたの助けが必要なところは次のとおりです。

  • リンクされたすべてのファイルを元の場所からターゲットの場所にコピーしたいと思います。

これにより、ビジュアルスタジオにリンクされたファイルと元のコピーが作成され、同じ名前の同じディレクトリに両方が存在します。

通常、ディレクトリに同じ名前のファイルが既に含まれている場合、VS はそのディレクトリにリンクされたアイテムを作成することを許可しません。

ただし、最初にリンクされたアイテムを作成してテストしました。次に、Windows エクスプローラーを使用して元のファイルを宛先ディレクトリにコピーし、Visual Studio が正常に動作することを確認します。ソリューション エクスプローラーは単に物理ファイルを非表示にし、代わりにリンクされたアイテムを表示します。Show all files(ソリューション エクスプローラーをクリックした場合でも。)

ソリューション
|
|- プロジェクト 1
| - Shared.config [物理]
|- プロジェクト 2
| - Shared.config [リンク]
| - Shared.config [物理、ビルド中にここにコピーされ、ソリューション エクスプローラーには表示されない]

これはまさに私が欲しいものです!ファイルを編集しようとすると、Visual Studio は「リンクされた項目」を開きます。また、ビルド時に、物理ファイルがターゲット ディレクトリにコピーされるため、アクセスしようとするコード用に存在します。

どうすればいいですか?これは Build イベントで行う必要がありますか? その場合、「リンクされたすべてのファイルのオリジナルを宛先ディレクトリにコピーする」と言うにはどうすればよいですか?

4

4 に答える 4

27

dss539 の回答に問題がありました (vs2010 でテスト済み)。まず、一致するすべてのファイルのソリューション エクスプローラーに重複が表示されました。2 つ目'%link'は、プロパティ アクセサーではなく、文字列そのものであり、常に空の文字列と等しくない''ため、ビルド アクションを含むすべてのファイルNoneが一致し、複製され、ビルド時にコピーされます。第三に、リンクされたファイルはプロジェクトのルート ディレクトリにコピーされますが、リンクが配置されている場所にファイルをコピーする必要がありました。だから私はいくつかの変更を加えました:

<Target Name="CopyLinkedFiles" BeforeTargets="Build">
  <ItemGroup>
    <LinkedItem Include="@(Content)" Condition="%(Content.Link) != ''" />
  </ItemGroup>
  <Copy SourceFiles="@(LinkedItem)" DestinationFiles="%(LinkedItem.Link)"/> 
</Target>

LinkedItemソリューション エクスプローラーで項目が重複しなくなりました。リンクをコピーするには、Contentビルド アクションを設定する必要があります。

于 2013-07-02T14:59:07.743 に答える
17

これを実装するには、おそらく MSBuild 機能を使用する必要があります。

csproj ファイルを編集します (Visual Studio で、プロジェクトを右クリックしてアンロードし、右クリックして編集します)。

一番下までスクロールすると、この行が見つかるはずです。

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

その行の直後に、これらの行を追加します。

  <ItemGroup>
    <LinkedItem Include="@(None)" Condition="'%Link' != ''" />
  </ItemGroup>
  <Target Name="CopyLinkedFiles" BeforeTargets="Build" Inputs="@(LinkedItem)" Outputs="@(LinkedItem->'%(Filename)%(Extension)')">
    <Copy SourceFiles="@(LinkedItem)" DestinationFolder="$(MSBuildProjectDirectory)" />
  </Target>

ビルドするたびに、ビルド アクションが発生する直前に、MSBuild はすべてのリンクされたファイルをコピーします。

説明

ItemGroup「LinkedItem」という名前の「配列」が含まれています。リンク プロパティを含む "None" 項目のみを追加して、この配列を生成します。

Targetは MSBuild の概念です。これは、ビルドの特定のフェーズと考えることができます。このフェーズに「CopyLinkedFiles」という名前を付けましたが、任意の名前を付けることができます。

BeforeTargets指定されたフェーズの前にアクションを実行するように MSBuild に指示するディレクティブです。ここでは、「ビルド」フェーズの前に「CopyLinkedFiles」を実行することを選択しました。

Inputs最適化パラメータです。必要でない場合はコピーをスキップしてビルドを高速化するために使用されます。気にしない場合は、このパラメーターを無視できます。MSBuild はInputs、期待されるOutputsタイムスタンプと比較して、実行する必要があるかどうかを確認します。

Copyコピーするファイルを受け取り、指定したフォルダーに出力する MSBuild タスクです。

冗長性の削減

これをすべての .csproj ファイルに貼り付けるか、中央の .proj に入れて csproj ファイルに埋め込むことができます。悲しいことに、何をするにしても、すべての .csproj を少なくとも 1 回は編集する必要があります。:(

共通プロジェクト呼び出しでファイルを作成するWhateverNameYouLike.proj これらのコンテンツをファイルに入れます。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- paste the previously shown code here -->

  <!-- you can save yourself some hassle by linking the config file here, but if you really enjoy adding the file as a link to every project, you can skip this line -->
  <None Include="..\Common\Shared.config">
    <Link>Shared.config</Link>
  </None>
</Project>

今厄介な部分: すべての .csproj で、 おそらく終了タグ<Import Project="..\Common\WhateverNameYouLike.proj" /> の直前に行を追加する必要があります。</Project>

于 2013-03-19T17:25:02.853 に答える
1

リンクされた構成ファイルを右クリックし、プロパティを選択して、Copy to Output Directoryからに変更NeverCopy alwaysます。

于 2013-03-19T17:12:57.123 に答える
0

Visual Studio でビルド前およびビルド後のイベントを作成できます。

プロジェクトを選択し、右クリックして、プロパティ、ビルド イベントを選択します。

プレビルドの場合 -

copy /y "$(LocationOfShared.Config)Shared.config\" "$(TargetDir)"

ポストビルドの場合

cd $(TargetDir)
del shared.config

明らかに、返される実際の場所をいじる必要がありますが、アイデアは得られます。

編集 - 上記の回答はより簡単で簡単ですが、これはラウンドアラウンドの方法として機能するはずです。

于 2013-03-19T17:13:05.287 に答える