Чи є спосіб автоматичного включення файлів вмісту у файл проекту asp.net?


86

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


див .: це може допомогти вам stackoverflow.com/questions/1743432/…
Саар,

1
не зовсім те, що я шукаю
Марко

Я оновив свою відповідь щодо вашої проблеми під час модифікації папки у вашому браузері проти рішення.
Філбурт

Відповіді:


134

Я знаю стару нитку, але я знайшов спосіб зробити це, про що я постійно забуваю, і, шукаючи її востаннє, я натрапив на це питання. Найкращий спосіб, який я знайшов, - це використовувати ціль BeforeBuild у файлі .csproj.

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

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


Що означає .less? А що означає ціла струна **\*.less?
Зареєстрований користувач

3
.less файли - це файли CSS, призначені для синтаксичного аналізу препроцесором Less CSS. Google "крапки менше" для отримання додаткової інформації про це. Засіб виразу **\*.lessвключає всі файли * .less у всіх каталогах. У MSBUILD говорити ** означає "всі каталоги рекурсивно"
Кріс

4
Принаймні у VS 2012, як тільки ви додаєте / видаляєте файл із проекту та зберігаєте, це, на жаль, розширюється до повного списку. :(
Кріс Філліпс,

3
Це спрацювало для моєї ситуації лише після того, як змінив BeforeBuild на AfterBuild, моя збірка запускає скрипт PowerShell, який переміщує файли, які потім не будуть підхоплені моєю спробою розгортання блакитного Інтернету, оскільки вони існували лише після успішної збірки. Побачивши "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 * *. " /> Зникає з файлу проекту.
Marko

2
@Marko правильний. Після додавання <Content Include="Images\**\*.*" />це спрацювало. Як тільки ви додасте більше зображень, .csproj змінюється і повертається до переліку всіх файлів у зображеннях / ... і <Content Include = "Images * *. " /> Зникає.
Раві Рам

Вставте цей код в окремий файл .proj і викличте його з попередньої цілі збірки у файлі .csproj.
NL - Вибачтесь перед Монікою

21

Для тих, у кого виникають проблеми з використанням відповіді Кріса , це рішення для 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 , щоб показати файли в браузері рішень. Недоліком цього є те, що будь-які маніпуляції з автоматичними каталогами змусять Visual Studio замінити запис підстановки. Слід також зазначити , що підхід нижче буде тільки оновити в Solution Explorer при відкритті Solution / Проект в VS. Навіть кнопка "Оновити" панелі інструментів "Провідник рішень" цього не зробить.

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

1
Дякуємо за експерименти та вказівку на різницю між використанням <Target> та ні. Чудове пояснення деталей узагальнюючих знаків.
Курт Хатчінсон,

@KurtHutchinson - не проблема. =)
Джессі,

Я вважаю, що це рішення потребує полірування. Коли ви вказуєте цілі запускатись після "BeforeBuild", то теоретично це також може статися ПІСЛЯ публікації. Поточне рішення, ймовірно, працює завдяки удачі.
Імре Пювель

@ ImrePühvel як ви обчислюєте публікувати відбувається до того в BeforeBuildразі? MSBuild спочатку повинен створити проект та двійкові файли, перш ніж він зможе навіть розглянути питання про публікацію.
Джессі

1
Я не стверджував, що публікація відбувалась перед збіркою, але декларація не гарантує додавання елементів до вмісту перед публікацією. З зразка коду: .. AfterTargets="BeforeBuild". Це означає, що ваша власна мета повинна виконуватися після BeforeBuild, але вона не вказує, скільки після. Хоча, моя помилка, за поточним алгоритмом впорядкування цілей це повинно бути нормальним: msdn.microsoft.com/en-us/library/ee216359.aspx
Імре Пювель

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>

Це мені дуже допомогло; У мене є кілька каталогів глибиною на кілька рівнів і безліч файлів, які я хотів автоматично включити, і це перетворило весь цей вміст в один. Дякую!
Джей Оттербейн,

2
Я експериментував із цим ще трохи, і виявляється, що це має ті самі обмеження, що і Include="**\*.ext"з підстановочними знаками.
Стівен Лієкенс,

Ого, файл проекту включає запуск PowerShell? Це взагалі в пісочниці? Це подвиг, який чекає, що станеться.
Brain2000,

Це не PowerShell. MSBuild має власний синтаксис для виклику статичних методів. Згідно з документами, це обмежується системними класами. docs.microsoft.com/en-us/visualstudio/msbuild/... Хоча я впевнений, що ви можете просто <Exec> PowerShell з будь-якими аргументами ...
Стівен

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


2

Ви можете додавати файли з такими посиланнями, їх можна шукати, переглядати, але вони не перевіряють, якщо ви намагаєтесь їх змінити, також Visual Studio залишає символи підстановки на місці:

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

Це всередині файлу .proj.


1
Я спробував це, і VS замінює підстановочний знак окремими файлами, коли я додаю або видаляю файл за допомогою VS.
carlin.scott

Це дуже елегантно, але вам слід видалити підстановний знак із цілі посилання
SimSimY

1

Не наскільки мені відомо; однак моя пропозиція полягає в тому, щоб вставити їх у проект, оскільки вони будуть включати їх за замовчуванням. Отже, замість того, щоб вставляти їх у каталог за допомогою Провідника, використовуйте Visual Studio, щоб вставити файли в папки.


-1

Я зрозумів, що найкращим рішенням для цього є додавання файлів вручну, один за одним. Якщо у вас їх сотні, як у мене, це було лише питанням кількох годин. Забавно, що навіть у 2016 році з VS 2015 ця серйозна проблема все ще не вирішена. Ах, як я люблю Xcode.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.