Odpowiedź znalazłem tutaj:
http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
Program Visual Studio 2010 ma świetne nowe funkcje publikowania projektów aplikacji sieci Web, które umożliwiają łatwe publikowanie projektu aplikacji sieci Web jednym kliknięciem przycisku. Za kulisami transformacja Web.config i tworzenie pakietów jest wykonywane przez ogromny skrypt MSBuild, który jest importowany do pliku projektu (znajdującego się w: C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft .Web.Publishing.targets). Niestety, skrypt jest niezwykle skomplikowany, niechlujny i nieudokumentowany (poza niektórymi często błędnie zapisanymi i przeważnie bezużytecznymi komentarzami w pliku). Duży schemat blokowy tego pliku i trochę dokumentacji o tym, jak się do niego podłączyć, byłyby fajne, ale niestety brakuje (a przynajmniej nie mogę go znaleźć).
Niestety, oznacza to, że publikowanie za pomocą wiersza poleceń jest znacznie bardziej nieprzejrzyste, niż powinno. Zaskoczył mnie brak dokumentacji w tym zakresie, ponieważ w dzisiejszych czasach wiele sklepów korzysta z serwera ciągłej integracji, a niektóre nawet wdrażają zautomatyzowane (w czym funkcje publikowania VS2010 mogą bardzo pomóc), więc pomyślałem, że włączenie tego ( łatwo!) byłby dość głównym wymaganiem dla tej funkcji.
W każdym razie, po przekopaniu się godzinami przez plik Microsoft.Web.Publishing.targets i uderzeniu głową w ścianę prób i błędów, udało mi się dowiedzieć, jak Visual Studio wydaje się wykonywać swoje magiczne kliknięcie „Publikuj w systemie plików” oraz funkcje „Tworzenie pakietu wdrożeniowego”. Zajmę się trochę skryptami MSBuild, więc jeśli nie jesteś zaznajomiony z MSBuild, sugeruję sprawdzenie tej strony MSDN z kursem awaryjnym.
Opublikuj w systemie plików
Okno dialogowe Publikuj w systemie plików VS2010 Publikuj w systemie plików zajęło mi trochę czasu, ponieważ spodziewałem się rozsądnego wykorzystania programu MSBuild. Zamiast tego VS2010 robi coś dość dziwnego: wywołuje MSBuild w celu wykonania pewnego rodzaju pół wdrożenia, które przygotowuje pliki aplikacji internetowej w folderze obj projektu, a następnie wydaje się, że wykonuje ręczną kopię tych plików (tj. Poza MSBuild) do docelowego folderu publikowania. To naprawdę dziwne zachowanie, ponieważ MSBuild jest zaprojektowany do kopiowania plików (i innych rzeczy związanych z kompilacją), więc miałoby sens, gdyby cały proces był tylko jednym celem MSBuild, do którego odwołał się VS2010, a nie celem, a następnie ręczną kopią.
Oznacza to, że zrobienie tego za pomocą programu MSBuild w wierszu polecenia nie jest tak proste, jak wywołanie pliku projektu z określonym celem i ustawienie niektórych właściwości. Musisz zrobić to, co powinien był zrobić VS2010: samodzielnie stworzyć cel, który wykona wdrażanie w połowie, a następnie skopiuje wyniki do folderu docelowego. Aby edytować plik projektu, kliknij prawym przyciskiem myszy projekt w VS2010 i kliknij Zwolnij projekt, a następnie kliknij ponownie prawym przyciskiem myszy i kliknij Edytuj. Przewiń w dół, aż znajdziesz element Import, który importuje cele aplikacji internetowej (Microsoft.WebApplication.targets; sam ten plik importuje wspomniany wcześniej plik Microsoft.Web.Publishing.targets). Pod tym wierszem dodamy nasz nowy cel o nazwie 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>
Ten cel zależy od celu PipelinePreDeployCopyAllFilesToOneFolder, który jest tym, co VS2010 wywołuje przed wykonaniem ręcznej kopii. Przeglądanie Microsoft.Web.Publishing.targets pokazuje, że wywołanie tego celu powoduje umieszczenie plików projektu w katalogu określonym przez właściwość _PackageTempDir.
Pierwszym zadaniem, które wywołujemy w naszym celu, jest zadanie Error, na którym umieściliśmy warunek, który zapewnia, że zadanie zostanie wykonane tylko wtedy, gdy właściwość PublishDestination nie została ustawiona. Spowoduje to złapanie Cię i błąd kompilacji na wypadek, gdybyś zapomniał określić właściwość PublishDestination. Następnie wywołujemy zadanie MakeDir, aby utworzyć katalog PublishDestination, jeśli jeszcze nie istnieje.
Następnie definiujemy element o nazwie PublishFiles, który reprezentuje wszystkie pliki znalezione w folderze _PackageTempDir. Następnie wywoływane jest zadanie kopiowania, które kopiuje wszystkie te pliki do folderu docelowego publikacji. Atrybut DestinationFiles w elemencie Copy jest nieco złożony; wykonuje transformację elementów i konwertuje ich ścieżki do nowych ścieżek zakorzenionych w folderze PublishDestination (sprawdź dobrze znane metadane elementu, aby zobaczyć, co oznaczają te% () s).
Aby wywołać ten cel z wiersza poleceń, możemy teraz po prostu wykonać to polecenie (oczywiście zmieniając nazwę pliku projektu i właściwości, aby Ci odpowiadały):
msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
Condition="false"
istnieje w celu zapewnienia zgodności z poprzednimi wersjami. VS2010 wymaga, aby ten import istniał, nawet jeśli zostanie pominięty z powodu fałszywego stanu. Jeśli spojrzysz ponownie, zobaczysz, że csproj zawiera inny import, dla$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets
którego jest rozpoznawany plik docelowy dla bieżącej wersji programu Visual Studio.