コンテンツファイルをasp.netプロジェクトファイルに自動的に含める方法はありますか?


86

ASP.NETプロジェクトに多くのコンテンツファイル(主に画像とjs)を頻繁に追加しています。VS公開システムを使用していますが、公開時に、プロジェクトに含めるまで新しいファイルは公開されません。指定したディレクトリにあるすべてのファイルを自動的に含めたいのですが。どのディレクトリをcsprojファイルまたは他の場所に自動含めるかを指定する方法はありますか?



1
正確には私が探しているものではありません
Marko

vsソリューションブラウザ内のフォルダを変更する際の問題に関する回答を更新しました。
Filburt 2010

回答:


134

古いスレッド、私は知っていますが、私は忘れ続けているこれを行う方法を見つけました、そして最後にそれを見つけるために私の検索で、私はこの質問に出くわしました。これに対して私が見つけた最善の方法は、.csprojファイルでBeforeBuildターゲットを使用することです。

<Target Name="BeforeBuild">
    <ItemGroup>
        <Content Include="**\*.less" />
    </ItemGroup>
</Target>

VS 2010はこのセクションに触れず、プロジェクトがビルドされるたびにファイルがコンテンツとして含まれるようにします。


.lessの意味は何ですか?そして、文字列全体はどういう意味**\*.lessですか?
登録ユーザー

3
.lessファイルは、LessCSSプリプロセッサによって解析されることを目的としたcssファイルです。詳細については、Googleの「ドットレス」をご覧ください。この式**\*.lessは、すべてのディレクトリにすべての* .lessファイルを含めることを意味します。MSBUILDで話す場合、**は「すべてのディレクトリを再帰的に」を意味します
Chris

4
少なくともVS2012では、プロジェクトからファイルを追加/削除して保存するとすぐに、残念ながらこれは完全なリストに展開されます。:(
クリスフィリップス

3
これは、BeforeBuildをAfterBuildに変更した後でのみ私の状況で機能しました。ビルドは、ファイルを移動するPowerShellスクリプトを開始します。これは、ビルドが成功した後にのみ存在するため、AzureWebデプロイの試行では検出されません。「BeforeBuild」を見ると、おそらく「AterBuild」もあったことがわかりました。これが他の誰かに役立つことを願っています。
ルークライス

1
@John VS2015 +の修正については、以下の私の回答を参照しください。
ジェシー

54

あなたは単にあなたのウェブサイトの.csprojファイルを拡張することができます。再帰的なワイルドカードを使用してコンテンツルートフォルダを追加するだけです。

...
<ItemGroup>
    <!-- your normal project content -->
    <Content Include="Default.aspx" />

    <!-- your static content you like to publish -->
    <Content Include="Images\**\*.*" />
</ItemGroup>
...

そうすることで、このフォルダーとその下のすべてのコンテンツがソリューションブラウザー内に表示されます。

指定してソリューションブラウザ内のフォルダを非表示にしようとした場合

<Content Include="Images\**.*.*">
    <Visible>false</Visible>
</Content>

公開されません。


更新

すでに発見したように、VSプロジェクトは任意のコンテンツを含むように設計されていないため、ソリューション内のフォルダーに触れるとすぐにワイルドカードが置き換えられます。

したがって、フォルダとその内容がVS内から変更されないようにする必要があります。ファイルの追加または削除はファイルシステムでのみ実行できます...これは、私があなたの質問を理解したときに望んでいたことです。

フォルダをVSで非表示にできると簡単ですが、非表示にして公開する方法が見つかりませんでした。

別の失敗したアプローチは、CreateItemタスクによってフォルダーを含めることでした。その結果、フォルダのコンテンツが\ bin \ app.publish \ ...に公開され、.csproj内のコンテンツアイテムと一緒に公開することを納得させることができなかったため、回答に表示しませんでした。


3
ファイルを手動で追加または削除するまで機能します。その行の後、<Content Include = "Images **。 " />がプロジェクトファイルから消えます。
マルコ

2
@Markoは正しいです。追加<Content Include="Images\**\*.*" />した後、それは機能しました。さらに画像を追加すると、.csprojが変更され、images / ...内のすべてのファイルの一覧表示に戻り、<Content Include = "Images **。 " />はなくなります。
Ravi Ram

このコードを別の.projファイルに貼り付け、ビルド前のターゲットから.csprojファイルで呼び出します。
NL – 2016年

21

クリスの回答の使用に問題がある場合、これはVisual Studio2012以降のソリューションです。

<Target Name="ContentsBeforeBuild" AfterTargets="BeforeBuild">
  <ItemGroup>
    <Content Include="images\**" />
  </ItemGroup>
</Target>

クリスが答えで述べたように、ターゲットディレクトリを手動でいじる(ファイルの追加/削除)場合でも、VisualStudioはこのセクションに触れません<Target>

ファイルが配置されているサブディレクトリ含める必要があることに注意してください(上記の場合はimages)。Visual Studio / MSBuildは、これらのファイルをプロジェクト構造内の同じディレクトリに配置します。サブディレクトリを使用しない場合、ファイルはプロジェクト構造のルートに配置されます。

ワイルドカードの簡単な説明:

  • **すべてを再帰的に意味します(ファイル、サブディレクトリ、およびそれら内のファイル)
  • *.extextトップレベルディレクトリ内の拡張子を持つすべてのファイルが含まれますが、サブディレクトリは含まれません
    • たとえば、*.ext可能性があり*.png*.jsなど、任意のファイル拡張子が動作します
  • **\*.extextトップレベルディレクトリとすべてのサブディレクトリの拡張子を持つすべてのファイルが含まれます。
  • Nant / Antの命名パターンを使用するにどうすればよいですか?の回答を参照してください例を使用したより完全な説明については。

完成させるために、使用する場合と使用<Target>しない場合で違いがありますのでご注意ください。

この<Target>アプローチでは、VisualStudioはソリューションエクスプローラー内にファイルを表示しません

<Target Name="ContentsBeforeBuild" AfterTargets="BeforeBuild">
  <ItemGroup>
    <Content Include="images\**" />
  </ItemGroup>
</Target>

<Target>アプローチで、ソリューションエクスプローラー内にファイルを表示するようにVisualStudio指示します。これの欠点は、自動ディレクトリを操作すると、VisualStudioがワイルドカードエントリを上書きすることです。以下のアプローチでは、VSでソリューション/プロジェクトを開いたときにのみソリューションエクスプローラーが更新されることにも注意してください。ソリューションエクスプローラーの「更新」ツールバーボタンでさえ、それを行いません。

<ItemGroup>
  <Content Include="images\**" />
</ItemGroup>

1
<Target>を使用する場合と使用しない場合の違いを実験して指摘していただき、ありがとうございます。ワイルドカードの詳細についても説明します。
Kurt Hutchinson

@ KurtHutchinson-問題ありません。=)
ジェシー

このソリューションには磨きが必要だと思います。「BeforeBuild」の後に実行するようにターゲットに指示すると、理論的には、これは公開後にも発生する可能性があります。現在の解決策はおそらく運が原因で機能します。
イムレPühvel

@ImrePühvelどのように公開把握んが起こる前のBeforeBuildイベント?MSBuildは、公開を検討する前に、まずプロジェクトとバイナリをビルドする必要があります。
ジェシー

1
ビルド前に公開が行​​われるとは主張しませんでしたが、宣言は、公開前にアイテムがコンテンツに追加されることを保証するものではありません。コードサンプルから:.. AfterTargets="BeforeBuild"。つまり、カスタムターゲットはBeforeBuildの後に実行する必要がありますが、その後の量は指定されていません。しかし、私のミスは、現在のターゲットの順序アルゴリズムによって、それは大丈夫でなければなりません:msdn.microsoft.com/en-us/library/ee216359.aspx
イムレPühvel

10

フレームワークのSystem.IO.Directory.GetFile(string)メソッドとそのオーバーロードを使用して、すべてのファイルを再帰的に含めることができます。

  <ItemGroup>
    <Content Include="$([System.IO.Directory]::GetFiles('$(ProjectDir)Scripts\', '*.js', SearchOption.AllDirectories))" />
    <Content Include="$([System.IO.Directory]::GetFiles('$(ProjectDir)Images\', '*.png', SearchOption.AllDirectories))" />
  </ItemGroup>

これは私にとって大きな助けになりました。数レベルの深さの複数のディレクトリがあり、自動インクルードしたいファイルがたくさんあります。これにより、これらすべてのコンテンツが1つになりました。ありがとう!
Jay Otterbein 2015年

2
これをもう少し試してみたところInclude="**\*.ext"、ワイルドカードの場合と同じ制限があることがわかりました。
Steven Liekens 2015年

うわー、プロジェクトファイルには実行PowerShellが含まれていますか?それはまったくサンドボックス化されていますか?それは起こるのを待っているエクスプロイトです。
Brain20 0019

PowerShellではありません。MSBuildには、静的メソッドを呼び出すための独自の構文があります。ドキュメントによると、これはシステムクラスに限定されています。docs.microsoft.com/en-us/visualstudio/msbuild/... 私は必ずできるだけの<Execの> PowerShellの任意の引数を持つ...だが
スティーブンLiekens

3

小さなPowerShellスクリプトで作成されたコンテンツインクルードを取得する方法を記述しました。

$folders = Get-ChildItem .\ -r -Directory
$filtered = $folders |Select-Object @{Name='FullName';Expression={$_.fullname.replace($pwd,'')}}, @{Name='FolderDepth';Expression={($_.fullname.Split('\').Count) - ($Pwd.Path.split('\').count)}} | Sort-Object -Descending FullName,folderDepth 
$basefolders = $filtered | Where-Object{$_.folderdepth -eq 1}
$basefoldersobj = @()
foreach($basefolder in $basefolders)
{
  $basefoldername =$baseFolder.fullname
  $filteredbase = $filtered -match "\$basefoldername\\" | Sort-Object -Descending FolderDepth | Select-Object -first 1
  if($filteredbase -eq $null)
  {
    $filteredbase = $filtered -match "\$basefoldername" | Sort-Object -Descending FolderDepth | Select-Object -first 1
  }
  $obj = New-Object psobject
  Add-Member -InputObject $obj -MemberType NoteProperty -Name 'Folder' -Value $basefolder.fullname.trim('\')
  Add-member -InputObject $obj -MemberType NoteProperty -Name 'DeepestPath' -Value $filteredbase.folderDepth
  $basefoldersobj += $obj
}
$include = '*.*'
foreach($bfolderObj in $basefoldersobj)
{
  $includecount = ''
  $includecount = "\$include" * ($bfolderObj.Deepestpath)
  Write-Output "<content Include=`"$($bfolderObj.folder)$includecount`" /> "
}

これにより、PowerShellプロンプトで必要なincludeステートメントが生成されます。


2

このようなリンクを含むファイルを追加できます。ファイルは検索可能で表示可能ですが、変更しようとしてもチェックアウトされません。また、VisualStudioではワイルドカードがそのまま残ります。

  <ItemGroup>
    <Content Include="..\Database Schema\Views\*.sql">
      <Link>Views\*.sql</Link>
    </Content>
  </ItemGroup>

これは.projファイル内に入ります。


1
これを試しましたが、VSを使用してファイルを追加または削除すると、VSはワイルドカードを個々のファイルに置き換えます。
carlin.scott 2015年

これは非常にエレガントですが、リンクターゲットからワイルドカードを削除する必要があります
SimSimY 2015

1

私の知る限りではありません。ただし、デフォルトで含まれるため、プロジェクトに貼り付けることをお勧めします。そのため、エクスプローラーを使用してディレクトリに貼り付ける代わりに、VisualStudioを使用してファイルをフォルダーに貼り付けます。


-1

これに対する最善の解決策は、ファイルを1つずつ手動で追加することであることに気付きました。私がしたようにあなたがそれらを何百も持っているならば、それはほんの数時間の問題でした。2016年にVS2015を使用しても、この深刻な問題がまだ解決されていないのはおかしいです。ああ、Xcodeが大好きです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.