Làm thế nào để bạn bao gồm các tệp bổ sung bằng cách sử dụng các gói triển khai web VS2010?


125

Tôi đang thử nghiệm bằng cách sử dụng chức năng đóng gói web mới trong visual studio 2010 và đã gặp tình huống tôi sử dụng một sự kiện dựng sẵn để sao chép yêu cầu. Chúng không thể được đưa vào như một tài liệu tham khảo vì chúng không phải là dll COM có thể được sử dụng với interop.

Khi tôi xây dựng gói triển khai, các tệp đó sẽ bị loại trừ khi tôi chọn tùy chọn chỉ bao gồm các tệp cần thiết để chạy ứng dụng. Có cách nào để định cấu hình cài đặt triển khai để bao gồm các tệp này không? Tôi đã không có may mắn tìm thấy bất kỳ tài liệu tốt về điều này.

Câu trả lời:


176

Câu hỏi tuyệt vời. Tôi vừa đăng một mục blog rất chi tiết về điều này tại Công cụ triển khai Web (MSDeploy): Gói xây dựng bao gồm các tệp bổ sung hoặc loại trừ các tệp cụ thể .

Đây là tóm tắt. Sau khi bao gồm các tệp, tôi cũng chỉ ra cách loại trừ các tệp.

Bao gồm các tập tin bổ sung

Bao gồm các tệp bổ sung vào gói khó hơn một chút nhưng vẫn không có vấn đề gì nếu bạn cảm thấy thoải mái với MSBuild và nếu bạn không đọc thì hãy đọc nó. Để làm điều này, chúng ta cần nối vào một phần của quy trình thu thập các tệp để đóng gói. Mục tiêu chúng ta cần mở rộng được gọi là CopyAllFilesToSingleFolder. Mục tiêu này có thuộc tính phụ thuộc, PipelinePreDeployCopy ALLFilesToOneFolderDependsOn, mà chúng ta có thể khai thác và tiêm vào mục tiêu của chính mình. Vì vậy, chúng tôi sẽ tạo một mục tiêu có tên CustomCollectFiles và đưa mục tiêu đó vào quy trình. Chúng tôi đạt được điều này với những điều sau đây (hãy nhớ sau câu lệnh nhập khẩu).

<PropertyGroup>
  <CopyAllFilesToSingleFolderForPackageDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForPackageDependsOn>

  <CopyAllFilesToSingleFolderForMsdeployDependsOn>
    CustomCollectFiles;
    $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
  </CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>

Điều này sẽ thêm mục tiêu của chúng tôi vào quy trình, bây giờ chúng tôi cần xác định chính mục tiêu. Giả sử rằng bạn có một thư mục có tên Extra Files cao hơn 1 cấp so với dự án web của bạn. Bạn muốn bao gồm tất cả các tập tin. Đây là mục tiêu CustomCollectFiles và chúng tôi sẽ thảo luận sau đó.

<Target Name="CustomCollectFiles">
  <ItemGroup>
    <_CustomFiles Include="..\Extra Files\**\*" />

    <FilesForPackagingFromProject  Include="%(_CustomFiles.Identity)">
      <DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>

Ở đây, những gì tôi đã làm là tạo mục _CustomFiles và trong thuộc tính Bao gồm đã bảo nó lấy tất cả các tệp trong thư mục đó và bất kỳ thư mục nào bên dưới nó. Nếu có bất kỳ cơ hội nào bạn cần loại trừ một cái gì đó khỏi danh sách đó, hãy thêm một Excludethuộc tính vào _CustomFiles.

Sau đó, tôi sử dụng mục này để điền vào mục FilesForPackagingFromProject. Đây là mục mà MSDeploy thực sự sử dụng để thêm các tệp bổ sung. Cũng lưu ý rằng tôi đã khai báo giá trị DestinationRelativePath siêu dữ liệu. Điều này sẽ xác định đường dẫn tương đối mà nó sẽ được đặt trong gói. Tôi đã sử dụng câu lệnh Extra Files% (RecursiveDir)% (Tên tệp)% (Tiện ích mở rộng) tại đây. Điều đang nói là đặt nó ở cùng một vị trí tương đối trong gói vì nó nằm trong thư mục Extra Files.

Không bao gồm các tập tin

Nếu bạn mở tệp dự án của một ứng dụng web được tạo bằng VS 2010 về phía dưới cùng của nó, bạn sẽ tìm thấy một dòng với.

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

BTW bạn có thể mở tệp dự án bên trong VS. Nhấp chuột phải vào dự án chọn Unload Project. Sau đó nhấp chuột phải vào dự án không tải và chọn Chỉnh sửa dự án.

Tuyên bố này sẽ bao gồm tất cả các mục tiêu và nhiệm vụ mà chúng ta cần. Hầu hết các tùy chỉnh của chúng tôi sẽ là sau lần nhập đó, nếu bạn không chắc chắn đặt sau! Vì vậy, nếu bạn có các tệp để loại trừ, có một tên mục, ExcludeFromPackageFiles, có thể được sử dụng để làm như vậy. Ví dụ: giả sử bạn có tệp có tên Sample.Debug.xml có trong ứng dụng web của bạn nhưng bạn muốn loại trừ tệp đó khỏi các gói đã tạo. Bạn có thể đặt đoạn mã bên dưới sau câu lệnh nhập đó.

<ItemGroup>
  <ExcludeFromPackageFiles Include="Sample.Debug.xml">
    <FromTarget>Project</FromTarget>
  </ExcludeFromPackageFiles>
</ItemGroup>

Bằng cách khai báo mục này, các tệp sẽ tự động bị loại trừ. Lưu ý việc sử dụng FromTargetsiêu dữ liệu ở đây. Tôi sẽ không nhận được ở đây, nhưng bạn nên biết để luôn luôn xác định điều đó.


3
Bạn có thể mở rộng ví dụ của mình để đưa đầu ra dự án bổ sung vào xuất bản không?
Anthony Serdyukov

7
Tôi đã cài đặt VS2012 (RC) và đối với tôi có một DependencyProperty khác. Để hỗ trợ các nhóm hỗn hợp (và máy chủ xây dựng của chúng tôi), tôi đã có cấu hình CopyAllFilesToSingleFolderForPackageDependsOn ban đầu một bản sao bằng cách sử dụng DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn
Emil Lerch

2
Đây là điều tuyệt vời. Sử dụng điều này để triển khai một số thông tin phiên bản được lưu trữ trong một tệp txt.
lamarant

5
Điều này dường như không làm việc cho tôi. Tôi đang sử dụng VStudio 2013. :( Thiết lập msbuild ở trên có hoạt động cho năm 2013 không?
irperez

8
@SayedIbrahimHashimi và đồng. đã tạo ra một phiên bản cập nhật hơn nhiều của hướng dẫn này trên trang web asp.net . Tôi thực sự khuyên bạn nên liên kết đó, vì đó là sự khác biệt giữa tôi bị kẹt khi sửa đổi tệp csproj thay vì tệp pubxml.
Adam Venezuela ngày

21

Một giải pháp đơn giản hơn là chỉnh sửa tệp csproj để đưa dll cần thiết vào thư mục bin và sau đó tạo mục tiêu trước khi sao chép mục vào thư mục bin từ thư mục thư viện chung nơi chúng tôi lưu trữ các dll của bên thứ 3. Bởi vì mục tồn tại trong tệp giải pháp, nó được triển khai bởi msbuild / msdeploy và không có gì phức tạp là cần thiết.

Thẻ được sử dụng để bao gồm tệp mà không cần thêm thông qua VS (thường sẽ muốn thêm nó vào VCS của bạn)

<Content Include="Bin\3rdPartyNative.dll" ><Visible>false</Visible></Content>

Đây là mục tiêu BeforeBuild phù hợp với tôi:

<Target Name="BeforeBuild">
    <Message Text="Copy $(SolutionDir)Library\3rdPartyNative.dll to '$(TargetDir)'3rdPartyNative.dll" Importance="high" />
    <Copy SourceFiles="$(SolutionDir)Library\3rdPartyNative.dll" DestinationFiles="$(TargetDir)3rdPartyNative.dll" />
</Target>

Đã chỉnh sửa để bao gồm đề xuất của @ tuespetre để ẩn mục nhập do đó loại bỏ nhược điểm trước đó của thư mục bin hiển thị. Chưa được tôi xác minh.


3
"Sự đơn giản là sự tinh tế tột cùng"
BornToCode

1
Điều này hoạt động trong nhiều trường hợp, nhưng không hoạt động nếu bạn có các tệp cần được đưa vào bên ngoài thư mục bin.
Nathan

5
@toxaq, tôi có thể thiếu một cái gì đó, nhưng vấn đề tôi gặp phải là tôi thực sự cần các tệp ở một vị trí trong gói triển khai không có trong thư mục bin. Vì vậy, có, bạn có thể sao chép các tệp từ bất kỳ đâu vào thư mục bin, nhưng chúng sẽ không được bao gồm ở đúng vị trí trong gói triển khai trong kịch bản đó. Để biết giá trị của nó, tình huống mà tôi gặp phải là với dự án ClearScript.V8 - các tệp gốc không được xuất hiện trong thư mục bin, nhưng phải xuất hiện trong phần tử mẹ của nó - xem Clearscript.codeplex.com/discussions/438696 để thảo luận .
Nathan

3
Tôi sẽ tăng thêm mười lần nữa nếu tôi có thể. Đây phải là câu trả lời được chấp nhận. Tôi cũng muốn thêm rằng bạn có thể thiết lập <Visible>false</Visible>để ẩn nó khỏi Solution Explorer.
tuespetre

1
@Tohid cảm ơn, đã thực hiện chỉnh sửa đó. Không có bất kỳ nội dung MS nào để kiểm tra vì vậy tôi chưa xác minh.
toxaq

7

Giống như @toxaq, nhưng một giải pháp thậm chí đơn giản hơn là:

Trong trình khám phá giải pháp, thêm tệp dưới dạng một liên kết đến thư mục thư viện / tài liệu tham khảo, và sau đó trong các thuộc tính được đặt để sao chép vào đầu ra của bản dựng.


3
-1 điều này giả định rằng dự án muốn có mối quan hệ thời gian liên kết rõ ràng. Không phù hợp với các hệ thống loại trình cắm
MickyD

6

Vì vậy, việc thực hiện của Sayed không hiệu quả với tôi. Tôi đang sử dụng VS2013 và sử dụng gói Triển khai Web và cần thêm một số DLL plugin từ thư mục khác vào thùng của gói triển khai. Đây là cách tôi quản lý để làm cho nó hoạt động (dễ dàng hơn nhiều):

Ở dưới cùng của tệp csproj của bạn thêm:

<Target Name="AdditionalFilesForPackage" AfterTargets="CopyAllFilesToSingleFolderForMsdeploy">
    <ItemGroup> 
        <Files Include="..\SomeOtherProject\bin\$(Configuration)\*.*"/>
    </ItemGroup>
    <Copy SourceFiles="@(Files)" DestinationFolder="$(_PackageTempDir)\bin\" />  
</Target>

Các đề cập khác trong tệp csproj:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <DeployOnBuild>true</DeployOnBuild>
    <DeployTarget>Package</DeployTarget>
    <DeployIisAppPath>Default Web Site/MyWebsite</DeployIisAppPath>
    <DesktopBuildPackageLocation>..\output\Service\Service\Service.Release.zip</DesktopBuildPackageLocation>
    <FilesToIncludeForPublish>OnlyFilesToRunTheApp</FilesToIncludeForPublish>
    <ExcludeGeneratedDebugSymbol>true</ExcludeGeneratedDebugSymbol>
    <PublishDatabases>false</PublishDatabases>
</PropertyGroup>

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v12.0\WebApplications\Microsoft.WebApplication.targets" />

Cảm ơn bạn. Tôi đang sử dụng VS2015 và tôi cũng cần thêm DLLS từ thư mục bin dự án khác. Giải pháp của bạn là cách dễ nhất và hoạt động hoàn hảo.
Rafael

5

Muốn bình luận để nhấn mạnh bình luận của Emil Lerch ở trên. Nếu bạn đã cài đặt Azure SDK, thì hãy tìm một DependencyProperty khác.

Về cơ bản, bạn có thể cần phải sử dụng "Copy ALLFilesToSingleFolderForMsdeployDependsOn thay vì" CopyAllFilesToSingleFolderForPackageDependsOn ".

Đây là một liên kết khác nếu điều này không phù hợp với bạn và bạn đã cài đặt Azure SDK: http://forums.iis.net/t/1190714.aspx


3

Là một phụ lục cho câu trả lời của Sayed, tôi thấy rằng một tuyên bố tĩnh về các mục ExcludeFromPackageFiles trong dự án của tôi là không đủ. Tôi cần loại trừ một số DLL nhất định chỉ có sẵn sau khi biên dịch (các mô-đun Ninject cụ thể của Azure không cần thiết khi tôi triển khai lên IIS).

Vì vậy, tôi đã cố gắng tạo ra danh sách ExcludeFromPackageFiles của mình bằng cách sử dụng bản sao CopyAllFilesToSingleFolderForPackageDependsOn đã nói ở trên. Tuy nhiên, điều này là quá muộn vì quy trình đóng gói đã loại bỏ các mục ExcludeFromPackageFiles. Vì vậy, tôi đã sử dụng kỹ thuật tương tự, nhưng sớm hơn một chút:

<PropertyGroup>
    <ExcludeFilesFromPackageDependsOn>
        $(ExcludeFilesFromPackageDependsOn);
        _ExcludeAzureDlls
    </ExcludeFilesFromPackageDependsOn>
</PropertyGroup>

<Target Name="_ExcludeAzureDlls">
    <ItemGroup>
        <FilesForPackagingFromProjectWithNoAzure Include="@(FilesForPackagingFromProject)"
                               Exclude="%(RootDir)%(Directory)*Azure*.dll" />
        <AzureFiles Include="@(FilesForPackagingFromProject)"
                    Exclude="@(FilesForPackagingFromProjectWithNoAzure)" />
        <ExcludeFromPackageFiles Include="@(AzureFiles)">
            <FromTarget>_ExcludeAzureEnvironmentDlls</FromTarget>
        </ExcludeFromPackageFiles>
    </ItemGroup>
</Target>

Mong rằng sẽ giúp được ai đó ...


1

Ngoài ra, có thể đặt tệp là Nội dung | Sao chép luôn

Ngoài ra, có thể đặt tệp là Nội dung |  Sao chép luôn


1
Có vẻ đây phải là câu trả lời hàng đầu vì nó dễ nhất và rõ ràng nhất
J Miglietta
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.