Có cách nào để tự động đưa các tệp nội dung vào tệp dự án asp.net không?


86

Tôi thường xuyên thêm nhiều tệp nội dung (chủ yếu là hình ảnh và js) vào dự án ASP.NET của mình. Tôi đang sử dụng hệ thống xuất bản VS và khi xuất bản, các tệp mới sẽ không được xuất bản cho đến khi tôi đưa chúng vào dự án. Tôi muốn tự động bao gồm tất cả các tệp trong thư mục được chỉ định. Có cách nào để chỉ định thư mục nào sẽ được tự động đưa vào tệp csproj hoặc bất kỳ nơi nào khác không?


xem: điều này có thể giúp bạn stackoverflow.com/questions/1743432/…
Saar,

1
không chính xác những gì tôi đang tìm kiếm
Marko

Tôi đã cập nhật câu trả lời của mình liên quan đến vấn đề của bạn khi sửa đổi thư mục bên trong trình duyệt so với giải pháp của bạn.
Filburt

Câu trả lời:


134

Chủ đề cũ, tôi biết, nhưng tôi đã tìm ra một cách để làm điều này mà tôi vẫn tiếp tục quên, và khi tìm kiếm để tìm lại nó lần cuối, tôi tình cờ gặp câu hỏi này. Cách tốt nhất mà tôi đã tìm thấy là sử dụng mục tiêu BeforeBuild trong tệp .csproj.

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

VS 2010 sẽ không động đến phần này và nó đảm bảo rằng các tệp của bạn được bao gồm dưới dạng nội dung mỗi khi dự án được xây dựng.


Ý nghĩa của .less là gì? Và toàn bộ chuỗi có nghĩa là **\*.lessgì?
Người dùng đã đăng ký

3
Tệp .less là tệp css được phân tích cú pháp bởi bộ tiền xử lý Ít CSS. Google "chấm bớt" để biết thêm thông tin về điều đó. Biểu thức **\*.lesscó nghĩa là bao gồm tất cả các tệp * .less trong tất cả các thư mục. Trong MSBUILD speak, phương tiện ** 'tất cả các thư mục đệ quy'
Chris

4
Ít nhất là trong VS 2012, ngay sau khi bạn thêm / xóa tệp khỏi dự án và lưu, điều này không may được mở rộng thành danh sách đầy đủ. :(
Chris Phillips

3
Điều này chỉ phù hợp với tình huống của tôi sau khi thay đổi BeforeBuild thành AfterBuild, bản dựng của tôi khởi động một tập lệnh powershell để di chuyển các tệp, sau đó sẽ không được chọn bởi nỗ lực triển khai web azure của tôi vì chúng chỉ tồn tại sau khi xây dựng thành công. Nhìn thấy "BeforeBuild", tôi biết rằng có lẽ cũng có một "AterBuild". Hy vọng điều này sẽ giúp người khác.
Luke Rice

1
@John xem câu trả lời của tôi bên dưới để biết cách sửa lỗi cho VS2015 +.
Jesse

54

Bạn chỉ cần mở rộng tệp .csproj trang web của mình. Chỉ cần thêm thư mục gốc nội dung của bạn bằng ký tự đại diện đệ quy:

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

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

Làm như vậy làm cho thư mục này và tất cả nội dung bên dưới hiển thị bên trong trình duyệt giải pháp của bạn.

Nếu bạn cố gắng ẩn thư mục bên trong trình duyệt giải pháp bằng cách chỉ định

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

nó sẽ không được xuất bản.


Cập nhật

Như bạn đã phát hiện ra, ký tự đại diện sẽ được thay thế ngay khi bạn chạm vào thư mục bên trong giải pháp của mình vì các dự án VS không được thiết kế để chứa nội dung tùy ý.

Vì vậy, bạn sẽ phải đảm bảo rằng thư mục và nội dung của nó không bao giờ được sửa đổi từ bên trong VS - việc thêm hoặc xóa tệp chỉ có thể được thực hiện trên hệ thống tệp ... đó là những gì bạn muốn khi tôi hiểu câu hỏi của bạn.

Sẽ dễ dàng hơn nếu thư mục có thể được ẩn trong VS nhưng tôi không thể tìm cách ẩn nó VÀ xuất bản.

Một cách tiếp cận không thành công khác là bao gồm thư mục theo CreateItemTác vụ. Điều này dẫn đến nội dung của thư mục được xuất bản lên \ bin \ app.publish \ ... và không thể thuyết phục được xuất bản nó cùng với các mục nội dung bên trong .csproj nên tôi đã không trình bày nó trong câu trả lời của mình.


3
Nó hoạt động cho đến khi tôi thêm hoặc xóa tệp theo cách thủ công. Sau khi dòng <Nội dung bao gồm = "Hình ảnh * *. " /> Biến mất khỏi tệp dự án.
Marko

2
@Marko là chính xác. Sau khi thêm <Content Include="Images\**\*.*" />nó đã hoạt động. Sau khi bạn thêm nhiều hình ảnh, .csproj sẽ được thay đổi và quay trở lại để liệt kê tất cả các tệp trong hình ảnh / ... và <Nội dung bao gồm = "Hình ảnh * *. " /> Biến mất.
Ravi Ram

Dán mã này vào một tệp .proj riêng biệt và gọi mã đó từ mục tiêu xây dựng trước trong tệp .csproj.
NL - Xin lỗi Monica,

21

Đối với những người gặp sự cố khi sử dụng câu trả lời của Chris , đây là giải pháp cho Visual Studio 2012 và mới hơn:

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

Như Chris đã đề cập trong câu trả lời của mình - Visual Studio sẽ không chạm vào <Target>phần này, ngay cả khi bạn tự thao tác (thêm / xóa tệp) với thư mục đích.

Xin lưu ý rằng bạn nên bao gồm một thư mục con nơi chứa các tệp (trong trường hợp trên là nó images). Visual Studio / MSBuild sẽ đặt các tệp đó trong cùng một thư mục trong cấu trúc dự án. Nếu bạn không sử dụng thư mục con, các tệp sẽ được đặt ở gốc của cấu trúc dự án.

Để có giải thích nhanh về các ký tự đại diện:

  • **có nghĩa là mọi thứ đệ quy (tệp, thư mục con và tệp trong đó)
  • *.extsẽ bao gồm tất cả các tệp có phần mở rộng exttrong thư mục cấp cao nhất, nhưng không bao gồm các thư mục con
    • Ví dụ, *.extcó thể là *.png, *.jsvv Bất kỳ phần mở rộng tập tin sẽ làm việc
  • **\*.extsẽ bao gồm tất cả các tệp có phần mở rộng exttừ thư mục cấp cao nhất và tất cả các thư mục con.
  • Xem câu trả lời từ Làm cách nào để sử dụng các mẫu đặt tên Nant / Ant? để được giải thích đầy đủ hơn với các ví dụ.

Để hoàn thành, xin lưu ý rằng có sự khác biệt giữa việc sử dụng <Target>và không sử dụng nó.

Với <Target>phương pháp này, Visual Studio sẽ không hiển thị các tệp trong Trình khám phá giải pháp.

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

Phương <Target>pháp không tiếp cận sẽ hướng dẫn Visual Studio hiển thị các tệp trong Trình khám phá giải pháp. Hạn chế của điều này là bất kỳ thao tác nào đối với các thư mục tự động sẽ khiến Visual Studio ghi đè mục nhập ký tự đại diện. Cũng cần lưu ý rằng cách tiếp cận dưới đây sẽ chỉ cập nhật Trình khám phá Giải pháp khi mở Giải pháp / Dự án trong VS. Ngay cả nút thanh công cụ "refresh" của Solution Explorer cũng không làm được.

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

1
Cảm ơn bạn đã thử nghiệm và chỉ ra sự khác biệt giữa việc sử dụng <Mục tiêu> và không. Giải thích tuyệt vời về các chi tiết của các ký tự đại diện.
Kurt Hutchinson

@KurtHutchinson - không vấn đề gì. =)
Jesse

Tôi tin rằng giải pháp này cần đánh bóng. Khi bạn hướng dẫn mục tiêu chạy sau "BeforeBuild" thì về lý thuyết, điều này cũng có thể xảy ra SAU KHI xuất bản. Giải pháp hiện tại có lẽ hoạt động do may mắn.
Imre Pühvel

@ ImrePühvel làm thế nào để bạn tìm bố xảy ra trước khi các BeforeBuildsự kiện? MSBuild trước tiên phải xây dựng dự án và mã nhị phân trước khi nó có thể xem xét xuất bản.
Jesse

1
Tôi không khẳng định việc xuất bản sẽ xảy ra trước khi xây dựng, nhưng tuyên bố đó không đảm bảo rằng các mục được thêm vào nội dung trước khi xuất bản. Từ mẫu mã: .. AfterTargets="BeforeBuild". Có nghĩa là, mục tiêu tùy chỉnh của bạn phải thực thi sau BeforeBuild, nhưng nó không chỉ định bao nhiêu sau đó. Tuy nhiên, sai lầm của tôi, bởi các thuật toán mục tiêu đặt hàng hiện tại nó phải được ok: msdn.microsoft.com/en-us/library/ee216359.aspx
Imre Pühvel

10

Bạn có thể sử dụng System.IO.Directory.GetFile(string)phương thức của khung công tác và các quá tải của nó để đưa vào tất cả các tệp một cách đệ quy.

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

Đây là một sự giúp đỡ lớn đối với tôi; Tôi có nhiều thư mục sâu ở một vài cấp độ và rất nhiều tệp tôi muốn tự động đưa vào và điều này đã biến tất cả những nội dung đó thành một. Cảm ơn!
Jay Otterbein

2
Tôi đã thử nghiệm với điều này nhiều hơn và hóa ra rằng điều này có tất cả các hạn chế giống như Include="**\*.ext"với các ký tự đại diện.
Steven Liekens

Chà, tệp dự án có chạy powershell không? Đó có phải là hộp cát không? Đó là một khai thác đang chờ đợi xảy ra.
Brain2000, 23/09/19

Nó không phải là PowerShell. MSBuild có cú pháp riêng để gọi các phương thức tĩnh. Theo tài liệu, điều này được giới hạn cho một lớp hệ thống. docs.microsoft.com/en-us/visualstudio/msbuild/... Mặc dù tôi chắc chắn rằng bạn có thể chỉ <Exec> PowerShell với bất kỳ đối số ...
Steven Liekens

3

Tôi đã viết ra cách tôi có thể nhận được nội dung bao gồm được tạo bằng một tập lệnh powershell nhỏ:

$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`" /> "
}

Điều này sẽ tạo ra câu lệnh bao gồm cần thiết tại dấu nhắc powershell


2

Bạn có thể thêm các tệp có liên kết như thế này, chúng có thể tìm kiếm, có thể xem, nhưng chúng sẽ không được kiểm tra nếu bạn cố gắng thay đổi chúng, cũng như visual studio để lại các ký tự đại diện tại chỗ:

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

Điều này nằm trong tệp .proj.


1
Tôi đã thử điều này và VS thay thế ký tự đại diện bằng các tệp riêng lẻ khi tôi thêm hoặc xóa tệp bằng VS.
carlin.scott

Đây là rất thanh lịch, nhưng bạn nên loại bỏ các ký tự đại diện từ mục tiêu liên kết
SimSimY

1

Không phải kiến ​​thức của tôi; tuy nhiên đề xuất của tôi là dán chúng vào dự án vì điều này sẽ bao gồm chúng theo mặc định. Vì vậy, thay vì dán chúng vào thư mục thông qua Explorer, hãy sử dụng Visual Studio để dán tệp vào thư mục.


-1

Tôi nhận ra rằng giải pháp tốt nhất cho việc này là thêm từng tệp theo cách thủ công. Nếu bạn có hàng trăm người trong số họ như tôi đã làm, đó chỉ là vấn đề trong vài giờ. Buồn cười là ngay cả trong năm 2016 với VS 2015 vấn đề nghiêm trọng này vẫn không được giải quyết. Ahh, tôi yêu Xcode như thế nào.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.