Есть ли способ автоматически включать файлы содержимого в файл проекта asp.net? - PullRequest
76 голосов
/ 31 марта 2010

Я часто добавляю много файлов содержимого (в основном изображения и js) в мой проект ASP.NET. Я использую систему публикации VS, и при публикации новые файлы не публикуются, пока я не включу их в проект. Я хотел бы автоматически включить все файлы в указанной директории. Есть ли способ указать, какие каталоги должны автоматически включаться в файл csproj или где-либо еще?

Ответы [ 8 ]

125 голосов
/ 25 февраля 2012

Старая ветка, я знаю, но я нашел способ сделать это, о котором постоянно забываю, и, пытаясь найти его в последний раз, я наткнулся на этот вопрос. Лучший способ, который я нашел для этого, это использовать цель BeforeBuild в файле .csproj.

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

VS 2010 не будет касаться этого раздела, и он гарантирует, что ваши файлы будут включены в качестве контента при каждой сборке проекта.

49 голосов
/ 06 апреля 2010

Вы можете просто расширить файл .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 Task. Это привело к тому, что содержимое папки было опубликовано в \ bin \ app.publish \ ... , и его нельзя было убедить опубликовать вместе с элементами содержимого внутри .csproj, поэтому я не представил его в мой ответ.

14 голосов
/ 01 марта 2018

Для тех, у кого возникли проблемы с использованием Ответ Криса , это решение для Visual Studio 2012 и новее:

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

Как отметил Крис в своем ответе - Visual Studio не будет касаться этого раздела <Target>, даже если вы вручную возитесь (добавляя / удаляя файлы) с целевым каталогом.

Обратите внимание, что должен включать подкаталог, в котором находятся файлы (в приведенном выше случае это images). Visual Studio / MSBuild поместит эти файлы в один и тот же каталог в структуре проекта. Если вы не используете подкаталог, файлы будут помещены в корень структуры проекта.

Для быстрого объяснения подстановочных знаков:

  • ** означает все рекурсивно (файлы, подкаталоги и файлы в них)
  • *.ext будет включать все файлы с расширением ext в каталоге верхнего уровня, но не в подкаталогах
    • Например, *.ext может быть *.png, *.js и т. Д. Любое расширение будет работать
  • **\*.ext будет включать все файлы с расширением ext из каталога верхнего уровня и всех подкаталогов.
  • См. Ответ от Как использовать шаблоны именования Nant / Ant? для более полного объяснения с примерами.

Для завершения, пожалуйста, обратите внимание, что существует разница между использованием <Target> и неиспользованием его.

При использовании подхода <Target> Visual Studio не будет показывать файлы в обозревателе решений.

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

Не <Target> подход будет инструктировать Visual Studio показывать файлы в обозревателе решений. Недостаток этого заключается в том, что любая манипуляция с автоматическими каталогами 1062 * приведет к тому, что Visual Studio переопределит шаблонную запись. Также следует отметить, что следующий подход позволит только обновить обозреватель решений при открытии решения / проекта в VS. Даже кнопка «Обновить» на панели инструментов обозревателя решений не сделает этого.

<ItemGroup>
  <Content Include="images\**" />
</ItemGroup>
7 голосов
/ 21 сентября 2015

Вы можете использовать метод 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>
3 голосов
/ 18 декабря 2015

Я написал, как мне удалось получить содержимое, созданное с помощью небольшого сценария 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

2 голосов
/ 11 апреля 2014

Вы можете добавлять файлы с такими ссылками, они доступны для поиска, просмотра, но они не извлекаются, если вы пытаетесь их изменить, также Visual Studio оставляет подстановочные знаки на месте:

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

Это входит в файл .proj.

1 голос
/ 06 апреля 2010

Не в моих знаниях; однако я предлагаю вставить их в проект, поскольку они будут включены по умолчанию. Поэтому вместо вставки их в каталог через проводник используйте Visual Studio, чтобы вставить файлы в папки.

0 голосов
/ 11 декабря 2016

Я понял, что лучшим решением для этого является добавление файлов вручную, один за другим. Если у вас их сотни, как у меня, это было всего за несколько часов. Забавно, что даже в 2016 году с VS 2015 эта серьезная проблема до сих пор не решена. Ааа, как я люблю Xcode.

...