Menggunakan msbuild untuk menjalankan Profil Penerbitan Sistem File

87

Saya memiliki proyek ac # .Net 4.0 yang dibuat dengan VS2010 dan sekarang sedang diakses dengan VS2012.

Saya mencoba menerbitkan hanya file yang diperlukan dari situs web ini ke lokasi tujuan (C: \ builds \ MyProject [Files])

Struktur file saya: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

Saya menjalankan berikut ini melalui MSBuild:

C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ MSBuild.exe ./ProjectRoot/MyProject.csproj / p: DeployOnBuild = true /p:PublishProfile=./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

Ini xml di FileSystemDebug.pubxml

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>C:\builds\MyProject\</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>

Perilaku yang dihasilkan adalah:

  • file zip dibuat di sini: ./ProjectRoot/obj/Debug/Package/MyProject.zip
  • Tidak ada yang diterapkan ke <publishUrl>C:\builds\MyProject\</publishUrl>WTF
  • file zip yang dibuat adalah sarapan babi dan penuh dengan file yang tidak diperlukan untuk aplikasi.

Ketika saya menjalankan profil publikasi ini melalui studio visual, folder dibuat di * C: \ builds \ MyProject * dan berisi artefak persis yang saya inginkan.

Bagaimana cara mendapatkan hasil sederhana ini dari msbuild?

P. Roe
sumber

Jawaban:

52

FYI: Saya memiliki masalah yang sama dengan Visual Studio 2015. Setelah berjam-jam mencoba, sekarang saya bisa melakukannya msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofile.

Saya harus mengedit file .csproj saya agar berfungsi. Itu berisi baris seperti ini:

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

Saya mengubah baris ini sebagai berikut:

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

(Saya mengubah 10.0 menjadi 14.0, tidak yakin apakah ini perlu. Tapi saya pasti harus menghapus bagian kondisi.)

johanv.dll
sumber
1
Impor bersyarat dengan Condition="false"ada untuk kompatibilitas mundur. VS2010 mensyaratkan bahwa impor ini ada, meskipun itu dilewati karena kondisi salah. Jika Anda melihat lagi maka Anda akan melihat bahwa csproj berisi impor lain $(VSToolsPath)\WebApplications\Microsoft.WebApplication.targetsyang menyelesaikan file target untuk versi Visual Studio.
Steven Liekens
3
Perhatikan penggunaan strategis $(MSBuildToolsVersion)di jalan ke akun untuk versi VS yang tepat: <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(MSBuildToolsVersion)\WebApplications\Microsoft.WebApplication.targets" Condition="false" />. Ini bekerja untuk saya pada Pembaruan VS2015 1.
Al Dass
43

Temukan jawabannya di sini: http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

Visual Studio 2010 memiliki fitur penerbitan Proyek Aplikasi Web baru yang hebat yang memungkinkan Anda untuk dengan mudah menerbitkan proyek aplikasi web Anda dengan satu klik tombol. Di balik layar, transformasi Web.config dan pembuatan paket dilakukan oleh skrip MSBuild besar yang diimpor ke file proyek Anda (ditemukan di: C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft .Web.Publishing.t target). Sayangnya, skrip ini sangat rumit, berantakan dan tidak berdokumen (selain beberapa komentar yang sering dieja dengan buruk dan kebanyakan tidak berguna dalam file). Diagram alir besar dari file itu dan beberapa dokumentasi tentang cara menghubungkannya akan menyenangkan, tetapi sayangnya kurang (atau setidaknya saya tidak dapat menemukannya).

Sayangnya, ini berarti melakukan penerbitan melalui baris perintah jauh lebih buram daripada yang seharusnya. Saya terkejut dengan kurangnya dokumentasi di area ini, karena saat ini banyak toko menggunakan server integrasi berkelanjutan dan beberapa bahkan melakukan penyebaran otomatis (yang mana fitur penerbitan VS2010 dapat banyak membantu), jadi saya akan berpikir bahwa mengaktifkan ini ( mudah!) akan menjadi persyaratan yang cukup utama untuk fitur tersebut.

Bagaimanapun, setelah menggali melalui file Microsoft.Web.Publishing.t target selama berjam-jam dan membenturkan kepala saya ke dinding trial and error, saya telah berhasil mengetahui bagaimana Visual Studio tampaknya melakukan keajaibannya dengan satu klik "Publikasikan ke Sistem File" dan fitur "Build Deployment Package". Saya akan membahas sedikit tentang skrip MSBuild, jadi jika Anda tidak terbiasa dengan MSBuild, saya sarankan Anda melihat halaman kursus kilat MSDN ini.

Publikasikan ke Sistem File

VS2010 Publikasikan Ke Sistem File Dialog Publikasikan ke Sistem File membutuhkan waktu beberapa lama untuk saya karena saya mengharapkan beberapa penggunaan MSBuild yang masuk akal akan terjadi. Sebaliknya, VS2010 melakukan sesuatu yang cukup aneh: ia memanggil MSBuild untuk melakukan semacam penerapan setengah yang menyiapkan file aplikasi web di folder objek proyek Anda, kemudian tampaknya melakukan salinan manual dari file-file itu (yaitu di luar MSBuild) ke dalam folder publikasi target Anda. Ini benar-benar perilaku yang mendera karena MSBuild dirancang untuk menyalin file di sekitar (dan hal-hal lain yang terkait dengan build), jadi masuk akal jika keseluruhan proses hanya satu target MSBuild yang dipanggil oleh VS2010, bukan target, lalu salinan manual.

Ini berarti bahwa melakukan ini melalui MSBuild pada baris perintah tidak sesederhana menjalankan file proyek Anda dengan target tertentu dan menyetel beberapa properti. Anda harus melakukan apa yang seharusnya dilakukan VS2010: buat sendiri target yang melakukan penerapan setengah lalu salin hasilnya ke folder target. Untuk mengedit file proyek Anda, klik kanan pada proyek di VS2010 dan klik Unload Project, kemudian klik kanan lagi dan klik Edit. Gulir ke bawah hingga Anda menemukan elemen Impor yang mengimpor target aplikasi web (Microsoft.WebApplication.t target; file ini sendiri mengimpor file Microsoft.Web.Publishing.t target yang disebutkan sebelumnya). Di bawah baris ini kami akan menambahkan target baru kami, yang disebut PublishToFileSystem:

<Target Name="PublishToFileSystem"
        DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
    <Error Condition="'$(PublishDestination)'==''"
           Text="The PublishDestination property must be set to the intended publishing destination." />
    <MakeDir Condition="!Exists($(PublishDestination))"
             Directories="$(PublishDestination)" />

    <ItemGroup>
        <PublishFiles Include="$(_PackageTempDir)\**\*.*" />
    </ItemGroup>

    <Copy SourceFiles="@(PublishFiles)"
          DestinationFiles="@(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')"
          SkipUnchangedFiles="True" />
</Target>

Target ini bergantung pada target PipelinePreDeployCopyAllFilesToOneFolder, yang dipanggil VS2010 sebelum melakukan penyalinan manual. Beberapa penggalian di Microsoft.Web.Publishing.t target menunjukkan bahwa memanggil target ini menyebabkan file proyek ditempatkan ke direktori yang ditentukan oleh properti _PackageTempDir.

Tugas pertama yang kami panggil dalam target kami adalah tugas Error, di mana kami telah menempatkan kondisi yang memastikan bahwa tugas hanya terjadi jika properti PublishDestination belum disetel. Ini akan menangkap Anda dan membuat kesalahan jika Anda lupa menentukan properti PublishDestination. Kami kemudian memanggil tugas MakeDir untuk membuat direktori PublishDestination itu jika belum ada.

Kami kemudian mendefinisikan Item yang disebut PublishFiles yang mewakili semua file yang ditemukan di bawah folder _PackageTempDir. Tugas Salin kemudian dipanggil yang menyalin semua file tersebut ke folder Tujuan Publikasi. Atribut DestinationFiles pada elemen Salin agak rumit; itu melakukan transformasi item dan mengubah jalur mereka ke jalur baru yang di-rooting di folder PublishDestination (lihat Metadata Item Terkenal untuk melihat apa artinya% () s).

Untuk memanggil target ini dari baris perintah, kita sekarang dapat melakukan perintah ini (dengan jelas mengubah nama dan properti file proyek agar sesuai dengan Anda):

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
P. Roe
sumber
3
Saya tidak dapat memahami potongan kode untuk target baru (ini menunjukkan 01 02 03 ...). Bisakah Anda mengedit?
fan711
2
Saya setuju dengan fan711. Padahal, solusi dijelaskan pada tautan - untuk apa kemudian menyalinnya?
Антон Курьян
4
@ АнтонКурьян: Tautan cenderung mati setelah beberapa waktu, itulah mengapa pertanyaan dan jawaban di stackoverflow.com harus selalu berdiri sendiri tanpa bergantung pada sumber daya eksternal.
Oliver
Hasilnya terlihat seperti profil terbitkan sama sekali tidak digunakan oleh MSBuild, dan malah melakukan paket (mungkin default?). Apa solusi Anda di bawah ini untuk mereplikasi apa yang diatur untuk dilakukan profil, yang ditangani oleh Microsoft.Web.Publishing.t target dengan memilih jenis yang benar dari folder penerapannya (untuk FileSystem). Jadi sepertinya Anda menemukan kembali roda di sini, alih-alih memecahkan masalah itu. Tetapi tidak bisa mengatakan dengan pasti tanpa log MSBuild Anda. Saya mendapatkan milik saya untuk bekerja, detail dalam jawaban saya
GregS
1
Solusi GregS tidak berhasil untuk saya. Build baik-baik saja, tetapi tidak ada file yang disalin ke direktori publish
bergegas
19

Masih kesulitan setelah mencoba semua jawaban di atas (saya menggunakan Visual Studio 2013). Tidak ada yang disalin ke folder terbitkan.

Hasil tangkapannya adalah jika saya menjalankan MSBuild dengan proyek individu dan bukan solusi, saya harus meletakkan parameter tambahan yang menentukan versi Visual Studio:

/p:VisualStudioVersion=12.0

12.0adalah untuk VS2013, ganti dengan versi yang Anda gunakan. Setelah saya menambahkan parameter ini, itu hanya berfungsi.

Baris perintah lengkapnya terlihat seperti ini:

MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0

Saya telah menemukannya di sini:

http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/command-line-deployment

Mereka menyatakan:

Jika Anda menentukan proyek individu dan bukan solusi, Anda harus menambahkan parameter yang menentukan versi Visual Studio.

felix-b
sumber
12

Menurut saya, profil terbitkan Anda tidak sedang digunakan, dan melakukan beberapa pengemasan default. Target Microsoft Web Publish melakukan semua yang Anda lakukan di atas, itu memilih target yang benar berdasarkan konfigurasi.

Saya mendapatkan milik saya untuk bekerja tidak ada masalah dari langkah TeamCity MSBuild, tetapi saya menentukan jalur eksplisit ke profil, Anda hanya perlu memanggilnya dengan nama tanpa .pubxml (misalnya FileSystemDebug). Ini akan ditemukan selama di folder standar, yang mana milik Anda.

Contoh:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=FileSystemDebug

Catatan ini dilakukan dengan menggunakan target Microsoft Web Publish versi Visual Studio 2012, biasanya terletak di "C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v11.0 \ Web". Lihat folder penerapan untuk target jenis penerapan tertentu yang digunakan

GregS
sumber
MS telah membuat banyak perbaikan sejak ini diposting beberapa tahun yang lalu, terima kasih atas program yang diperbarui?
P. Roe
3

FYI: Masalah yang sama dengan menjalankan di server build (Jenkins dengan msbuild 15 diinstal, didorong dari VS 2017 di proyek web .NET Core 2.1).

Dalam kasus saya, penggunaan target "terbitkan" dengan msbuild yang mengabaikan profil.

Jadi perintah msbuild saya dimulai dengan:

msbuild /t:restore;build;publish

Ini dengan benar memicu proses publikasi, tetapi tidak ada kombinasi atau variasi dari "/ p: PublishProfile = FolderProfile" yang pernah bekerja untuk memilih profil yang ingin saya gunakan ("FolderProfile").

Ketika saya berhenti menggunakan target publikasi:

msbuild /t:restore;build /p:DeployOnBuild=true /p:PublishProfile=FolderProfile

Saya (dengan bodohnya) berpikir bahwa itu tidak akan membuat perbedaan, tetapi segera setelah saya menggunakan tombol DeployOnBuild, profil itu diambil dengan benar.

Dari Orbonia
sumber
3

Sebenarnya saya menggabungkan semua jawaban Anda ke solusi saya sendiri bagaimana menyelesaikan masalah di atas:

  1. Saya membuat file pubxml sesuai kebutuhan saya
  2. Kemudian saya menyalin semua parameter dari file pubxml ke daftar parameter saya sendiri "/ p: foo = bar" untuk msbuild.exe
  3. Saya membuang file pubxml

Hasilnya seperti itu:

msbuild /t:restore /t:build /p:WebPublishMethod=FileSystem /p:publishUrl=C:\builds\MyProject\ /p:DeleteExistingFiles=True /p:LastUsedPlatform="Any CPU" /p:Configuration=Release

Rainer
sumber
1

Pertama, periksa versi Visual studio dari PC pengembang yang dapat menerbitkan solusi (proyek). seperti yang ditunjukkan untuk VS 2013

 /p:VisualStudioVersion=12.0

tambahkan baris perintah di atas untuk menentukan versi visual studio apa yang harus membangun proyek tersebut. Seperti jawaban sebelumnya, ini mungkin terjadi ketika kami mencoba untuk menerbitkan hanya satu proyek, bukan seluruh solusi.

Jadi kode lengkapnya akan seperti ini

"C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ msbuild.exe" "C: \ Program Files (x86) \ Jenkins \ workspace \ Jenkinssecondsample \ MVCSampleJenkins \ MVCSampleJenkins.csproj" / T: Build; Package / p : Konfigurasi = DEBUG / p: OutputPath = "obj \ DEBUG" / p: DeployIisAppPath = "Situs Web Default / jenkinsdemoapp" /p:VisualStudioVersion=12.0

Shammie
sumber
1
Maaf shammakalubo Anda sering salah mengartikan pertanyaan itu.
P. Roe
1
@shammakalubo Jawabannya benar, hanya saja tidak disebutkan secara lengkap. Parameter ini perlu ditambahkan ke perintah yang disebutkan oleh OP, yang kemudian akan menjadi: MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0Parameter ini adalah apa yang saya lewatkan dan memperbaiki masalah saya. Anda hanya perlu menyebutkan jawabannya secara lengkap!
Syed Waqas
@WaqasShah Terima kasih, Seperti yang Anda sebutkan, saya telah mengedit jawaban saya dan menerbitkan kode lengkap seperti apa.
Shammie