Я часто добавляю много файлов содержимого (в основном изображений и js) в свой проект ASP.NET. Я использую систему публикации VS, и при публикации новые файлы не публикуются, пока я не включу их в проект. Я хотел бы автоматически включать все файлы в указанный каталог. Есть ли способ указать, какие каталоги должны быть автоматически включены в файл csproj или где-либо еще?
86
Ответы:
Старая ветка, я знаю, но я нашел способ сделать это, о чем постоянно забываю, и, пытаясь найти его в последний раз, я наткнулся на этот вопрос. Лучший способ, который я нашел для этого, - использовать цель BeforeBuild в файле .csproj.
<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 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
из каталога верхнего уровня и всех подкаталогов.В заключение обратите внимание, что есть разница между использованием
<Target>
и неиспользованием.При таком
<Target>
подходе Visual Studio не будет отображать файлы в обозревателе решений.<Target Name="ContentsBeforeBuild" AfterTargets="BeforeBuild"> <ItemGroup> <Content Include="images\**" /> </ItemGroup> </Target>
Непостоянство
<Target>
подход будет инструктировать Visual Studio , чтобы показать файлы в обозревателе решений. Недостатком этого является то, что любые манипуляции с автоматическими каталогами заставят Visual Studio переопределить запись с подстановочными знаками. Следует также отметить , что подход ниже будет только обновить в Solution Explorer при открытии Solution / Проект в 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`" /> " }
Это должно создать необходимый оператор include в командной строке PowerShell.
источник
Вы можете добавлять файлы с такими ссылками, они доступны для поиска и просмотра, но они не извлекаются, если вы пытаетесь их изменить, также Visual Studio оставляет подстановочные знаки на месте:
<ItemGroup> <Content Include="..\Database Schema\Views\*.sql"> <Link>Views\*.sql</Link> </Content> </ItemGroup>
Это находится внутри файла .proj.
источник
Насколько мне известно, нет; однако я предлагаю вставить их в проект, так как они будут включены по умолчанию. Поэтому вместо того, чтобы вставлять их в каталог через проводник, используйте Visual Studio для вставки файлов в папки.
источник
Я понял, что лучшее решение для этого - вручную добавлять файлы по одному. Если у вас их сотни, как у меня, это всего лишь вопрос нескольких часов. Забавно, что даже в 2016 году с VS 2015 эта серьезная проблема все еще не решена. Ах, как я люблю Xcode.
источник