Dosya Sistemi Yayınlama Profilini yürütmek için msbuild kullanma


88

VS2010 ile oluşturulmuş ac # .Net 4.0 projem var ve şimdi VS2012 ile erişiliyor.

Bu web sitesinden yalnızca gerekli dosyaları bir hedef konuma yayınlamaya çalışıyorum (C: \ builds \ MyProject [Files])

Dosya yapım: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

MSBuild aracılığıyla aşağıdakileri çalıştırıyorum:

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

İşte FileSystemDebug.pubxml'deki xml

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

Ortaya çıkan davranış:

  • burada bir zip dosyası oluşturulur: ./ProjectRoot/obj/Debug/Package/MyProject.zip
  • <publishUrl>C:\builds\MyProject\</publishUrl>WTF'ye hiçbir şey dağıtılmadı
  • Oluşturulan zip dosyası domuz kahvaltısıdır ve uygulama için gerekli olmayan dosyalarla doludur.

Bu yayınlama profilini visual studio aracılığıyla çalıştırdığımda, * C: \ builds \ MyProject * konumunda bir klasör oluşturulur ve tam istediğim yapıları içerir.

Bu basit sonucu msbuild'den nasıl alabilirim?

Yanıtlar:


52

Bilginize: Visual Studio 2015 ile aynı sorunu yaşadım. Birçok saat denedikten sonra artık yapabilirim msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofile.

Çalışması için .csproj dosyamı düzenlemem gerekiyordu. Şöyle bir satır içeriyordu:

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

Bu satırı şu şekilde değiştirdim:

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

(10.0'ı 14.0 olarak değiştirdim, bunun gerekli olup olmadığından emin değilim. Ama kesinlikle koşul kısmını kaldırmak zorunda kaldım.)


1
Condition="false"Geriye dönük uyumluluk için koşullu içe aktarma var. VS2010, yanlış koşul nedeniyle atlansa bile bu içe aktarmanın var olmasını gerektirir. Tekrar bakarsanız, csproj'un $(VSToolsPath)\WebApplications\Microsoft.WebApplication.targetsgeçerli Visual Studio sürümü için hedefler dosyasına çözümlenen başka bir içe aktarım içerdiğini görürsünüz .
Steven Liekens

3
Stratejik kullanımına dikkat $(MSBuildToolsVersion)düzgün VS sürümü için hesaba yolunda: <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(MSBuildToolsVersion)\WebApplications\Microsoft.WebApplication.targets" Condition="false" />. Bu benim için VS2015 Güncelleme 1'de çalıştı.
Al Dass

43

Cevabı burada buldum: http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

Visual Studio 2010, web uygulaması projenizi tek bir düğmeyle kolayca yayınlamanıza olanak tanıyan harika yeni Web Uygulaması Projesi yayınlama özelliklerine sahiptir. Web.config dönüşümü ve paket oluşturma perde arkasında proje dosyanıza aktarılan devasa bir MSBuild komut dosyası tarafından yapılır (şu konumda bulunur: C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft .Web.Publishing.targets). Ne yazık ki, komut dosyası oldukça karmaşık, dağınık ve belgelenmemiş (diğerlerinde dosyada çoğu zaman kötü yazılmış ve çoğunlukla işe yaramaz yorumlar). Bu dosyanın büyük bir akış şeması ve ona nasıl bağlanılacağına dair bazı belgeler güzel olurdu, ancak ne yazık ki eksik görünüyor (ya da en azından bulamıyorum).

Maalesef bu, komut satırı üzerinden yayın yapmanın olması gerekenden çok daha opak olduğu anlamına geliyor. Bu alandaki dokümantasyon eksikliğine şaşırdım, çünkü bugünlerde birçok mağaza sürekli bir entegrasyon sunucusu kullanıyor ve hatta bazıları otomatik dağıtım (VS2010 yayınlama özelliklerinin çok yardımcı olabileceği) yapıyor, bu yüzden bunu etkinleştirmeyi düşünürdüm ( kolayca!) özellik için oldukça temel bir gereklilik olurdu.

Her neyse, Microsoft.Web.Publishing.targets dosyasını saatlerce kazdıktan ve kafamı deneme yanılma duvarına vurduktan sonra, Visual Studio'nun sihirli bir tıklama ile "Dosya Sistemine Yayınla" yı nasıl gerçekleştirdiğini anlamayı başardım. ve "Dağıtım Paketi Oluştur" özellikleri. Biraz MSBuild komut dosyası yazacağım, bu yüzden MSBuild'e aşina değilseniz, bu hızlandırılmış kurs MSDN sayfasına göz atmanızı öneririm.

Dosya Sistemine Yayınla

VS2010 Dosyaya Yayınlama Sistemine Yayınlama İletişim Kutusunu Dosya Sistemine Yayımlama biraz zaman aldı çünkü MSBuild'in bazı mantıklı kullanımlarının gerçekleşmesini bekledim. Bunun yerine, VS2010 oldukça tuhaf bir şey yapıyor: MSBuild'i projenizin obj klasöründeki web uygulamasının dosyalarını hazırlayan bir tür yarı dağıtım gerçekleştirmeye çağırıyor, ardından bu dosyaların manuel bir kopyasını yapıyor gibi görünüyor (yani MSBuild dışında) hedef yayın klasörünüze. Bu gerçekten çılgınca bir davranıştır çünkü MSBuild dosyaları (ve diğer yapı ile ilgili şeyleri) kopyalamak için tasarlanmıştır, bu nedenle tüm sürecin VS2010'un çağırdığı bir MSBuild hedefi, bir hedef değil, manuel bir kopya olması mantıklı olacaktır.

Bu, bunu komut satırında MSBuild aracılığıyla yapmanın, proje dosyanızı belirli bir hedefle çağırmak ve bazı özellikleri ayarlamak kadar basit olmadığı anlamına gelir. VS2010'un yapması gerekeni yapmanız gerekecek: kendiniz yarı dağıtımı gerçekleştiren bir hedef oluşturun ve ardından sonuçları hedef klasöre kopyalayın. Proje dosyanızı düzenlemek için VS2010'da projeye sağ tıklayın ve Projeyi Kaldır'a tıklayın, ardından tekrar sağ tıklayıp Düzenle'ye tıklayın. Web uygulaması hedeflerini içe aktaran İçe Aktar öğesini bulana kadar aşağı kaydırın (Microsoft.WebApplication.targets; bu dosyanın kendisi daha önce bahsedilen Microsoft.Web.Publishing.targets dosyasını içe aktarır). Bu satırın altına, PublishToFileSystem adlı yeni hedefimizi ekleyeceğiz:

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

Bu hedef, VS2010'un manuel kopyasını yapmadan önce çağırdığı PipelinePreDeployCopyAllFilesToOneFolder hedefine bağlıdır. Microsoft.Web.Publishing.targets'da bazı araştırmalar, bu hedefin çağrılmasının proje dosyalarının _PackageTempDir özelliği tarafından belirtilen dizine yerleştirilmesine neden olduğunu gösterir.

Hedefimizde çağırdığımız ilk görev, üzerine görevin yalnızca PublishDestination özelliği ayarlanmadıysa gerçekleşmesini sağlayan bir koşul yerleştirdiğimiz Hata görevidir. Bu sizi yakalayacak ve PublishDestination özelliğini belirtmeyi unutmanız durumunda derlemede hata yapacaktır. Daha sonra, zaten mevcut değilse, bu PublishDestination dizinini oluşturmak için MakeDir görevini çağırıyoruz.

Ardından, _PackageTempDir klasörü altında bulunan tüm dosyaları temsil eden PublishFiles adlı bir Öğe tanımlarız. Ardından, tüm bu dosyaları Yayınlama Hedefi klasörüne kopyalayan Kopyalama görevi çağrılır. Copy öğesindeki DestinationFiles özniteliği biraz karmaşıktır; öğelerin bir dönüşümünü gerçekleştirir ve yollarını PublishDestination klasöründe köklenen yeni yollara dönüştürür (bu% () s'nin ne anlama geldiğini görmek için Bilinen Öğe Meta Verilerine bakın).

Bu hedefi komut satırından çağırmak için artık bu komutu basitçe uygulayabiliriz (açıkça proje dosyası adını ve özelliklerini size uyacak şekilde değiştiririz):

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem

3
Yeni hedef için kod parçacığını anlamıyorum (01 02 03 ... gösteriyor). Lütfen düzeltebilir misin?
fan711

2
Fan711'e katılıyorum. Yine de, çözüm bağlantıda anlatılıyor - o zaman kopyalamak ne için?
Антон Курьян

4
@ АнтонКурьян: Bağlantılar bir süre sonra kaybolma eğilimindedir, bu yüzden stackoverflow.com'daki sorular ve cevaplar her zaman dış kaynaklara dayanmadan bağımsız olmalıdır.
Oliver

Sonuçlar, yayınlama profili MSBuild tarafından hiç kullanılmıyor gibi görünüyor ve bunun yerine bir paket yapıyor (belki bir varsayılan?). Microsoft.Web.Publishing.targets'ın, dağıtım klasöründen (FileSystem için) doğru türü seçerek, profilin yapmak üzere ayarlandığı şeyi çoğaltmak için aşağıdaki çözümünüz ne yapar. Görünüşe göre bu sorunu çözmek yerine burada tekerleği yeniden icat ediyorsunuz. Ancak MSBuild günlüğünüz olmadan kesin olarak söyleyemeyiz.
Çalışmam

1
GregS'nin çözümü benim için çalışmıyor. İyi
derlenir

19

Yukarıdaki tüm cevapları denedikten sonra hala sorun yaşadım (Visual Studio 2013 kullanıyorum). Yayınlama klasörüne hiçbir şey kopyalanmadı.

Buradaki sorun, MSBuild'i bir çözüm yerine tek bir projeyle çalıştırırsam, Visual Studio sürümünü belirten ek bir parametre koymam gerektiğiydi:

/p:VisualStudioVersion=12.0

12.0VS2013 içindir, kullandığınız sürümle değiştirin. Bu parametreyi ekledikten sonra işe yaradı.

Tam komut satırı şöyle görünür:

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

Burada buldum:

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

Belirtiyorlar:

Bir çözüm yerine bağımsız bir proje belirtirseniz, Visual Studio sürümünü belirten bir parametre eklemeniz gerekir.


12

Bana öyle geliyor ki yayınlama profiliniz kullanılmıyor ve bazı varsayılan paketleme yapıyor. Microsoft Web Yayımlama hedefleri yukarıda yaptığınız her şeyi yapar, yapılandırmaya bağlı olarak doğru hedefleri seçer.

TeamCity MSBuild adımından benimkini sorunsuz çalıştırdım, ancak profile giden açık bir yol belirledim, onu .pubxml olmadan adıyla çağırmanız yeterli (örn. FileSystemDebug). Sizinki olan standart klasörde olduğu sürece bulunacaktır.

Misal:

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

Bunun, normalde "C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v11.0 \ Web" konumunda bulunan Microsoft Web Publish hedeflerinin Visual Studio 2012 sürümleri kullanılarak yapıldığını unutmayın. Kullanılan belirli dağıtım türleri hedefleri için dağıtım klasörüne göz atın


MS birkaç yıl önce yayınlandığından bu yana pek çok iyileştirme yaptı, güncellenmiş programlama için teşekkürler.
P. Roe

3

Bilginize: Derleme sunucusunda çalıştırmayla aynı sorun (msbuild 15 yüklü Jenkins, bir .NET Core 2.1 web projesinde VS 2017'den sürülmüştür).

Benim durumumda, profili yok sayan msbuild ile "yayınlama" hedefinin kullanılmasıydı.

Böylece msbuild komutum şununla başladı:

msbuild /t:restore;build;publish

Bu, yayınlama sürecini doğru bir şekilde tetikledi, ancak "/ p: PublishProfile = FolderProfile" kombinasyonu veya varyasyonu, kullanmak istediğim profili ("Klasör Profili") seçmek için hiçbir zaman işe yaramadı.

Yayınlama hedefini kullanmayı bıraktığımda:

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

(Aptalca) bunun bir fark yaratmayacağını düşündüm, ancak DeployOnBuild anahtarını kullanır kullanmaz profili doğru bir şekilde aldı.


2

Aslında, yukarıdaki problemi nasıl çözeceğime dair tüm cevaplarınızı kendi çözümüme birleştirdim:

  1. Pubxml dosyasını ihtiyaçlarıma göre oluşturuyorum
  2. Daha sonra, tüm parametreleri pubxml dosyasından msbuild.exe için "/ p: foo = bar" parametre listeme kopyalıyorum
  3. Pubxml dosyasını atıyorum

Sonuç şu şekildedir:

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


çalışmıyor -
Araç Seti

1

Öncelikle, çözümü (projeyi) yayınlayabilen geliştirici bilgisayarın Visual Studio sürümünü kontrol edin. gösterildiği gibi VS 2013 için

 /p:VisualStudioVersion=12.0

projeyi ne tür bir görsel stüdyo sürümünün oluşturması gerektiğini belirlemek için yukarıdaki komut satırını ekleyin. Önceki cevaplar olarak, bu, tüm çözümü değil, yalnızca bir projeyi yayınlamaya çalıştığımızda gerçekleşebilir.

Yani kodun tamamı şuna benzer

"C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ msbuild.exe" "C: \ Program Files (x86) \ Jenkins \ workspace \ Jenkinssecondsample \ MVCSampleJenkins \ MVCSampleJenkins.csproj" / T: Build; Paket / p : Configuration = DEBUG / p: OutputPath = "obj \ DEBUG" / p: DeployIisAppPath = "Varsayılan Web Sitesi / jenkinsdemoapp" /p:VisualStudioVersion=12.0


1
Üzgünüm shammakalubo, soruyu çok yanlış yorumladın.
P. Roe

1
@shammakalubo Cevap doğru, ancak tam olarak belirtilmedi. Bu parametrenin OP tarafından belirtilen komuta eklenmesi gerekiyor ve daha sonra şu hale gelecektir: MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0Bu parametre eksik olan ve sorunumu çözen şeydi. Cevabı tamamen belirtmeniz yeterli!
Syed Waqas

@WaqasShah Teşekkürler, Bahsettiğiniz gibi cevabımı düzenledim ve tam kodu nasıl görüneceğini yayınladım.
Shammie

0

Proje klasöründen çalıştırın

msbuild / p: DeployOnBuild = true /p:PublishProfile="release-file.pubxml "/ p: AspnetMergePath =" C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v10.0A \ bin \ NETFX 4.8 Araçları "/ p: Configuration = Release

Bu, web.config Transform ve AspnetMergePath ile ilgilenir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.