ASP.NETプロジェクトに多くのコンテンツファイル(主に画像とjs)を頻繁に追加しています。VS公開システムを使用していますが、公開時に、プロジェクトに含めるまで新しいファイルは公開されません。指定したディレクトリにあるすべてのファイルを自動的に含めたいのですが。どのディレクトリをcsprojファイルまたは他の場所に自動含めるかを指定する方法はありますか?
ASP.NETプロジェクトに多くのコンテンツファイル(主に画像とjs)を頻繁に追加しています。VS公開システムを使用していますが、公開時に、プロジェクトに含めるまで新しいファイルは公開されません。指定したディレクトリにあるすべてのファイルを自動的に含めたいのですが。どのディレクトリをcsprojファイルまたは他の場所に自動含めるかを指定する方法はありますか?
回答:
古いスレッド、私は知っていますが、私は忘れ続けているこれを行う方法を見つけました、そして最後にそれを見つけるために私の検索で、私はこの質問に出くわしました。これに対して私が見つけた最善の方法は、.csprojファイルでBeforeBuildターゲットを使用することです。
<Target Name="BeforeBuild">
<ItemGroup>
<Content Include="**\*.less" />
</ItemGroup>
</Target>
VS 2010はこのセクションに触れず、プロジェクトがビルドされるたびにファイルがコンテンツとして含まれるようにします。
**\*.less
ですか?
**\*.less
は、すべてのディレクトリにすべての* .lessファイルを含めることを意味します。MSBUILDで話す場合、**は「すべてのディレクトリを再帰的に」を意味します
あなたは単にあなたのウェブサイトの.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内のコンテンツアイテムと一緒に公開することを納得させることができなかったため、回答に表示しませんでした。
<Content Include="Images\**\*.*" />
した後、それは機能しました。さらに画像を追加すると、.csprojが変更され、images / ...内のすべてのファイルの一覧表示に戻り、<Content Include = "Images **。 " />はなくなります。
クリスの回答の使用に問題がある場合、これはVisual Studio2012以降のソリューションです。
<Target Name="ContentsBeforeBuild" AfterTargets="BeforeBuild">
<ItemGroup>
<Content Include="images\**" />
</ItemGroup>
</Target>
クリスが答えで述べたように、ターゲットディレクトリを手動でいじる(ファイルの追加/削除)場合でも、VisualStudioはこのセクションに触れません<Target>
。
ファイルが配置されているサブディレクトリを含める必要があることに注意してください(上記の場合はimages
)。Visual Studio / MSBuildは、これらのファイルをプロジェクト構造内の同じディレクトリに配置します。サブディレクトリを使用しない場合、ファイルはプロジェクト構造のルートに配置されます。
ワイルドカードの簡単な説明:
**
すべてを再帰的に意味します(ファイル、サブディレクトリ、およびそれら内のファイル)*.ext
ext
トップレベルディレクトリ内の拡張子を持つすべてのファイルが含まれますが、サブディレクトリは含まれません
*.ext
可能性があり*.png
、*.js
など、任意のファイル拡張子が動作します**\*.ext
ext
トップレベルディレクトリとすべてのサブディレクトリの拡張子を持つすべてのファイルが含まれます。完成させるために、使用する場合と使用<Target>
しない場合で違いがありますのでご注意ください。
この<Target>
アプローチでは、VisualStudioはソリューションエクスプローラー内にファイルを表示しません。
<Target Name="ContentsBeforeBuild" AfterTargets="BeforeBuild">
<ItemGroup>
<Content Include="images\**" />
</ItemGroup>
</Target>
非<Target>
アプローチでは、ソリューションエクスプローラー内にファイルを表示するようにVisualStudioに指示します。これの欠点は、自動ディレクトリを操作すると、VisualStudioがワイルドカードエントリを上書きすることです。以下のアプローチでは、VSでソリューション/プロジェクトを開いたときにのみソリューションエクスプローラーが更新されることにも注意してください。ソリューションエクスプローラーの「更新」ツールバーボタンでさえ、それを行いません。
<ItemGroup>
<Content Include="images\**" />
</ItemGroup>
BeforeBuild
イベント?MSBuildは、公開を検討する前に、まずプロジェクトとバイナリをビルドする必要があります。
.. AfterTargets="BeforeBuild"
。つまり、カスタムターゲットはBeforeBuildの後に実行する必要がありますが、その後の量は指定されていません。しかし、私のミスは、現在のターゲットの順序アルゴリズムによって、それは大丈夫でなければなりません:msdn.microsoft.com/en-us/library/ee216359.aspx
フレームワークの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>
Include="**\*.ext"
、ワイルドカードの場合と同じ制限があることがわかりました。
小さな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ステートメントが生成されます。
このようなリンクを含むファイルを追加できます。ファイルは検索可能で表示可能ですが、変更しようとしてもチェックアウトされません。また、VisualStudioではワイルドカードがそのまま残ります。
<ItemGroup>
<Content Include="..\Database Schema\Views\*.sql">
<Link>Views\*.sql</Link>
</Content>
</ItemGroup>
これは.projファイル内に入ります。
私の知る限りではありません。ただし、デフォルトで含まれるため、プロジェクトに貼り付けることをお勧めします。そのため、エクスプローラーを使用してディレクトリに貼り付ける代わりに、VisualStudioを使用してファイルをフォルダーに貼り付けます。
これに対する最善の解決策は、ファイルを1つずつ手動で追加することであることに気付きました。私がしたようにあなたがそれらを何百も持っているならば、それはほんの数時間の問題でした。2016年にVS2015を使用しても、この深刻な問題がまだ解決されていないのはおかしいです。ああ、Xcodeが大好きです。