Bagaimana Anda memasukkan file tambahan menggunakan paket penyebaran web VS2010?

125

Saya menguji menggunakan fungsionalitas pengemasan web baru di visual studio 2010 dan menemukan situasi di mana saya menggunakan acara pra-bangun untuk menyalin .dll yang diperlukan ke dalam folder bin saya yang diandalkan oleh aplikasi saya untuk panggilan API. Mereka tidak dapat dimasukkan sebagai referensi karena mereka bukan COM dll yang dapat digunakan dengan interop.

Ketika saya membangun paket penerapan saya, file-file itu dikecualikan ketika saya memilih opsi untuk hanya menyertakan file yang diperlukan untuk menjalankan aplikasi. Apakah ada cara untuk mengonfigurasi pengaturan penyebaran untuk menyertakan file-file ini? Saya tidak beruntung menemukan dokumentasi yang bagus tentang ini.

Jason
sumber

Jawaban:

176

Pertanyaan yang bagus Saya baru saja memposting entri blog yang sangat rinci tentang hal ini di Web Deployment Tool (MSDeploy): Buat Paket termasuk file tambahan atau tidak termasuk file tertentu .

Inilah sinopsisnya. Setelah memasukkan file, saya juga menunjukkan cara mengecualikan file.

Termasuk File Ekstra

Memasukkan file tambahan ke dalam paket sedikit lebih sulit tetapi masih tidak ada masalah jika Anda nyaman dengan MSBuild, dan jika Anda tidak maka baca ini. Untuk melakukan ini, kita perlu menghubungkan ke bagian dari proses yang mengumpulkan file untuk kemasan. Target yang perlu kita perluas disebut CopyAllFilesToSingleFolder. Target ini memiliki properti dependensi, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, yang dapat kita manfaatkan dan suntikkan target kita sendiri. Jadi kami akan membuat target bernama CustomCollectFiles dan menyuntikkannya ke dalam proses. Kami mencapai ini dengan yang berikut (ingat setelah pernyataan impor).

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

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

Ini akan menambah target kita ke proses, sekarang kita perlu mendefinisikan target itu sendiri. Mari kita asumsikan bahwa Anda memiliki folder bernama File Ekstra yang terletak 1 tingkat di atas proyek web Anda. Anda ingin memasukkan semua file itu. Ini adalah target CustomCollectFiles dan kami diskusikan setelah itu.

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

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

Di sini yang saya lakukan adalah membuat item _CustomFiles dan pada atribut Include menyuruhnya untuk mengambil semua file di folder itu dan folder apa pun di bawahnya. Jika kebetulan Anda perlu mengecualikan sesuatu dari daftar itu, tambahkan Excludeatribut ke _CustomFiles.

Kemudian saya menggunakan item ini untuk mengisi item FilesForPackagingFromProject. Ini adalah item yang benar-benar digunakan MSDeploy untuk menambahkan file tambahan. Juga perhatikan bahwa saya mendeklarasikan nilai DestinationRelativePath metadata. Ini akan menentukan jalur relatif yang akan ditempatkan dalam paket. Saya menggunakan pernyataan Extra Files% (RecursiveDir)% (Filename)% (Extension) di sini. Apa yang dikatakannya adalah menempatkannya di lokasi relatif yang sama dalam paket seperti di bawah folder File Ekstra.

Tidak termasuk file

Jika Anda membuka file proyek aplikasi web yang dibuat dengan VS 2010 di bagian bawahnya, Anda akan menemukan sebuah baris.

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

BTW Anda dapat membuka file proyek di dalam VS. Klik kanan pada proyek pilih Unload Project. Kemudian klik kanan pada proyek yang dibongkar dan pilih Edit Proyek.

Pernyataan ini akan mencakup semua target dan tugas yang kita butuhkan. Sebagian besar penyesuaian kami harus setelah impor itu, jika Anda tidak yakin memasukkannya setelah itu! Jadi, jika Anda memiliki file untuk dikecualikan ada nama item, ExcludeFromPackageFiles, yang dapat digunakan untuk melakukannya. Sebagai contoh, katakanlah Anda memiliki file bernama Sample.Debug.xml yang termasuk dalam aplikasi web Anda tetapi Anda ingin file tersebut dikecualikan dari paket yang dibuat. Anda dapat menempatkan cuplikan di bawah setelah pernyataan impor itu.

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

Dengan mendeklarasikan mengisi item ini, file akan secara otomatis dikecualikan. Perhatikan penggunaan FromTargetmetadata di sini. Saya tidak akan membahasnya di sini, tetapi Anda harus tahu untuk selalu menentukannya.

Sayed Ibrahim Hashimi
sumber
3
Bisakah Anda memperluas contoh Anda untuk memasukkan hasil proyek tambahan ke dalam publikasi?
Anthony Serdyukov
7
Saya sudah menginstal VS2012 (RC), dan bagi saya ada DependencyProperty yang berbeda. Untuk mendukung tim campuran (dan server build kami), saya memiliki CopyAllFilesToSingleFolderForPackageDepends yang asliDalam konfigurasi dan duplikat menggunakan DependencyProperty CopyAllFilesToSingleFolderForMsdeployDependsOn
Emil Lerch
2
Ini luar biasa. Menggunakan ini untuk menyebarkan beberapa informasi versi yang disimpan dalam file txt.
Lamarant
5
Ini sepertinya tidak berhasil untuk saya. Saya menggunakan VStudio 2013. :( Apakah pengaturan msbuild di atas berfungsi untuk 2013?
irperez
8
@SayedIbrahimHashimi and co. telah membuat versi yang lebih baru dari panduan ini di situs web asp.net . Saya sangat merekomendasikan tautan itu, karena itulah perbedaan antara saya terjebak memodifikasi file csproj daripada file pubxml.
Adam Venezia
21

Solusi yang lebih sederhana adalah dengan mengedit file csproj untuk memasukkan dll yang diperlukan dalam folder bin dan kemudian membuat target beforebuild untuk menyalin item ke folder bin dari folder perpustakaan umum di mana kita menyimpan dll pihak ke-3 kita. Karena item ada dalam file solusi, item ini digunakan oleh msbuild / msdeploy dan tidak ada yang rumit yang diperlukan.

Tag digunakan untuk memasukkan file tanpa menambahkan melalui VS (yang biasanya ingin menambahkannya ke VCS Anda)

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

Ini adalah target BeforeBuild yang bekerja untuk saya:

<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>

Diedit untuk memasukkan saran @ tuespetre untuk menyembunyikan entri sehingga menghilangkan kelemahan sebelumnya dari folder nampan yang terlihat. Tidak diverifikasi oleh saya.

toxaq
sumber
3
"kesederhanaan adalah kecanggihan tertinggi"
BornToCode
1
Ini berfungsi dalam banyak kasus, tetapi tidak berfungsi jika Anda memiliki file yang perlu dimasukkan di luar folder bin.
Nathan
5
@toxaq, saya bisa melewatkan sesuatu, tetapi masalah yang saya temui adalah saya benar - benar membutuhkan file di lokasi dalam paket penyebaran yang tidak ada di folder bin. Jadi ya, Anda dapat menyalin file dari mana saja ke folder bin, tetapi mereka tidak akan dimasukkan di lokasi yang tepat dalam paket penerapan dalam skenario itu. Untuk apa nilainya, situasi yang saya temui adalah dengan proyek ClearScript.V8 - .dlls asli tidak boleh muncul di direktori bin, tetapi harus muncul di induknya - lihat clearscript.codeplex.com/discussions/438696 untuk diskusi .
Nathan
3
Saya akan membesarkan hati sepuluh kali lagi jika saya bisa. Ini harus menjadi jawaban yang diterima. Saya juga ingin menambahkan bahwa Anda dapat mengatur <Visible>false</Visible>untuk menyembunyikannya dari Solution Explorer.
tuespetre
1
@Tohid terima kasih, telah melakukan edit itu. Tidak punya barang MS untuk diuji jadi saya belum memverifikasi.
toxaq
7

Sama seperti @toxaq, tetapi solusi yang lebih sederhana adalah dengan:

Dalam solusi explorer, tambahkan file sebagai tautan ke folder pustaka / referensi, dan kemudian di properti atur agar disalin ke output build.

eglasius
sumber
3
-1 ini mengasumsikan bahwa proyek ingin memiliki hubungan waktu-linker eksplisit. Tidak cocok untuk sistem tipe plug-in
MickyD
6

Jadi implementasi Sayed tidak berhasil untuk saya. Saya menggunakan VS2013 dan menggunakan paket Web Deploy dan perlu menambahkan beberapa DLL plugin dari folder lain ke dalam bin paket deploy. Begini cara saya membuatnya bekerja (lebih mudah):

Di bagian bawah file csproj Anda, tambahkan:

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

Penyebutan lain dalam file 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" />
K0D4
sumber
Terima kasih. Saya menggunakan VS2015 dan saya juga perlu menambahkan DLL dari folder bin proyek lain. Solusi Anda adalah yang paling mudah dan bekerja dengan sempurna.
Rafael
5

Ingin berkomentar untuk menekankan komentar Emil Lerch di atas. Jika Anda telah menginstal Azure SDK, kemudian cari DependencyProperty yang berbeda.

Pada dasarnya, Anda mungkin perlu menggunakan "CopyAllFilesToSingleFolderForMsdeployDependsOn alih-alih" CopyAllFilesToSingleFolderForPackageDependsOn ". Saya tidak benar-benar seorang pria MSBuild yang maju dan saya membuang waktu untuk mencabut rambut saya mencoba menentukan mengapa target saya tidak dipanggil.

Berikut ini tautan lain jika ini tidak berhasil untuk Anda dan Anda telah menginstal Azure SDK: http://forums.iis.net/t/1190714.aspx

Paul Schroeder
sumber
3

Sebagai tambahan untuk jawaban Sayed, saya menemukan bahwa deklarasi statis item ExcludeFromPackageFiles dalam proyek saya tidak cukup. Saya perlu mengecualikan DLL tertentu yang hanya tersedia setelah dikompilasi (modul Azin spesifik Ninject yang tidak diperlukan ketika saya menyebarkan ke IIS).

Jadi saya mencoba untuk membuat daftar ExcludeFromPackageFiles menggunakan CopyAllFilesToSingleFolderForPackageDependsOn trick Sayed diposting di atas. Namun, ini sudah terlambat karena proses pengemasan telah menghapus item ExcludeFromPackageFiles. Jadi, saya menggunakan teknik yang sama, tetapi sedikit lebih awal:

<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>

Semoga itu bisa membantu seseorang ...

Peter McEvoy
sumber
1

Juga, dimungkinkan untuk mengatur file sebagai Konten | Salin selalu

Juga, dimungkinkan untuk mengatur file sebagai Konten |  Salin selalu

Fabito
sumber
1
Tampaknya ini harus menjadi jawaban teratas karena ini adalah yang termudah dan paling jelas
J Miglietta