C# 使用 msbuild 从解决方案发布一个 Web 项目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16891530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:04:03  来源:igfitidea点击:

Publish one web project from solution with msbuild

c#msbuildteamcitywebdeploy

提问by Caleb Jares

I'm trying to deploy one of the web projects in my solution to a server. I am using msbuild on TeamCity like so:

我正在尝试将解决方案中的 Web 项目之一部署到服务器。我在 TeamCity 上使用 msbuild,如下所示:

msbuild MySolution.sln /t:WebSite:Rebuild /p:DeployOnBuild=True /p:PublishProfile=Prod ...

However, when I run it, msbuild still tries to build my WebServiceproject, even though my WebSiteproject does not depend on it (but it does depend on a Servicesproject also in the solution). How do only publish one project, aka just WebSite?

但是,当我运行它时,msbuild 仍然尝试构建我的WebService项目,即使我的WebSite项目不依赖于它(但它确实依赖于Services解决方案中的一个项目)。如何只发布一个项目,又名 just WebSite

I have also tried building the project file using

我也尝试使用构建项目文件

msbuild WebSite/WebSite.csproj /p:DeployOnBuild=True ...

but it then complains that it can't restore packages:

但它随后抱怨它无法恢复软件包:

[07:47:17]WebSite\WebSite.csproj.teamcity: Build target: Build
[07:47:17][WebSite\WebSite.csproj.teamcity] RestorePackages
[07:47:17][RestorePackages] Exec
[07:47:17][Exec] C:\TeamCity\buildAgent\work\cab8a3d752df3a51\.nuget\NuGet.targets(90, 15): error MSB4064: The "LogStandardErrorAsError" parameter is not supported by the "Exec" task. Verify the parameter exists on the task, and it is a settable public instance property.
[07:47:17][Exec] C:\TeamCity\buildAgent\work\cab8a3d752df3a51\.nuget\NuGet.targets(89, 9): error MSB4063: The "Exec" task could not be initialized with its input parameters. 
[07:47:17][WebSite\WebSite.csproj.teamcity] Project WebSite\WebSite.csproj.teamcity failed.

When I disable NuGet Package Restore, CoreCompile (Csc) fails with errors I've never heard of and shouldn't be happening:

当我禁用 NuGet 包还原时,CoreCompile (Csc) 失败并出现我从未听说过且不应该发生的错误:

[07:54:43]WebSite\WebSite.csproj.teamcity: Build target: Build (13s)
[07:54:55][WebSite\WebSite.csproj.teamcity] CoreCompile
[07:54:55][CoreCompile] Csc
[07:54:56][Csc] Areas\Api\Services\TripService.cs(19, 104): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Helpers\StatisticsUtility.cs(11, 35): error CS1031: Type expected
[07:54:56][Csc] Helpers\StatisticsUtility.cs(11, 53): error CS1002: ; expected
[07:54:56][Csc] Helpers\StatisticsUtility.cs(16, 28): error CS1519: Invalid token '(' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(16, 37): error CS1519: Invalid token ',' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(17, 27): error CS1519: Invalid token '(' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(17, 32): error CS1519: Invalid token ')' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 17): error CS1519: Invalid token 'for' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 26): error CS1519: Invalid token '<=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 45): error CS1519: Invalid token '-' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 51): error CS1519: Invalid token '++' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 34): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 37): error CS1519: Invalid token '==' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 51): error CS1519: Invalid token ')' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 63): error CS1519: Invalid token '++' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(25, 41): error CS1519: Invalid token '>' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(25, 53): error CS1519: Invalid token ')' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(27, 36): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(27, 48): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(28, 36): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(29, 37): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(29, 48): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
[07:54:56][Csc] Helpers\StatisticsUtility.cs(29, 50): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(30, 33): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(30, 44): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
[07:54:56][Csc] Helpers\StatisticsUtility.cs(30, 50): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(32, 21): error CS0116: A namespace does not directly contain members such as fields or methods
[07:54:56][Csc] Helpers\StatisticsUtility.cs(35, 50): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\StatisticsUtility.cs(38, 21): error CS0116: A namespace does not directly contain members such as fields or methods
[07:54:56][Csc] Helpers\StatisticsUtility.cs(40, 50): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\StatisticsUtility.cs(42, 21): error CS1022: Type or namespace definition, or end-of-file expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(8, 59): error CS1031: Type expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(8, 80): error CS1002: ; expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(10, 55): error CS1519: Invalid token '(' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(10, 60): error CS1520: Class, struct, or interface method must have a return type
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(10, 82): error CS1002: ; expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(13, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(15, 60): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(18, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(20, 25): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(23, 28): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(26, 28): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 24): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 84): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(32, 28): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(35, 9): error CS1022: Type or namespace definition, or end-of-file expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(23, 26): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(26, 26): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 22): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 83): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(32, 26): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Controllers\SessionController.cs(13, 51): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Helpers\JsonNetResult.cs(13, 44): error CS1031: Type expected
[07:54:56][Csc] Helpers\JsonNetResult.cs(13, 72): error CS1041: Identifier expected, 'object' is a keyword
[07:54:56][Csc] Helpers\JsonNetResult.cs(13, 91): error CS1002: ; expected
[07:54:56][Csc] Helpers\JsonNetResult.cs(16, 38): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(16, 59): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(17, 64): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(17, 90): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(18, 32): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(18, 46): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(19, 33): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(22, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(25, 37): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(32, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(35, 37): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(40, 9): error CS1022: Type or namespace definition, or end-of-file expected
[07:54:56][Csc] Mailers\ITripMailer.cs(13, 132): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Mailers\TripMailer.cs(54, 85): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Services\Impl\AuthorizationService.cs(12, 70): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Services\Impl\AuthorizationService.cs(43, 77): error CS0241: Default parameter specifiers are not permitted
[07:54:56][WebSite\WebSite.csproj.teamcity] Project WebSite\WebSite.csproj.teamcity failed.

采纳答案by Sayed Ibrahim Hashimi

I blogged about this at http://sedodream.com/2013/03/06/HowToPublishOneWebProjectFromASolution.aspxa few months back. I've copied the details here as well, see below.

几个月前,我在http://sedodream.com/2013/03/06/HowToPublishOneWebProjectFromASolution.aspx 上写了一篇关于这个的博客。我也在这里复制了详细信息,请参见下文。



Today on twitter @nunofcostaasked me roughly the question “How do I publish one web project from a solution that contains many?”

今天在 Twitter 上@nunofcosta 粗略地问了我一个问题“我如何从包含多个项目的解决方案中发布一个 Web 项目?”

The issue that he is running into is that he is building from the command line and passing the following properties to msbuild.exe.

他遇到的问题是他正在从命令行构建并将以下属性传递给 msbuild.exe。

/p:DeployOnBuild=true
/p:PublishProfile='siteone - Web Deploy'
/p:Password=%password%

You can read more about how to automate publishing at http://sedodream.com/2013/01/06/CommandLineWebProjectPublishing.aspx.

您可以在http://sedodream.com/2013/01/06/CommandLineWebProjectPublishing.aspx阅读有关如何自动发布的更多信息。

When you pass these properties to msbuild.exe they are known as global properties. These properties are difficult to override and are passed to every project that is built. Because of this if you have a solution with multiple web projects, when each web project is built it is passed in the same set of properties. Because of this when each project is built the publish process for that project will start and it will expect to find a file named siteone – Web Deploy.pubxmlin the folder *Properties\PublishProfiles*. If the file doesn't exist the operation may fail.

当您将这些属性传递给 msbuild.exe 时,它​​们被称为全局属性。这些属性很难覆盖,并且会传递给每个构建的项目。因此,如果您有一个包含多个 Web 项目的解决方案,那么在构建每个 Web 项目时,它会在同一组属性中传递。因此,在构建每个项目时,该项目的发布过程将启动,并且会在文件夹 *Properties\PublishProfiles* 中找到名为siteone – Web Deploy.pubxml的文件。如果文件不存在,操作可能会失败。

Note: If you are interested in using this technique for an orchestrated publish see my comments at https://stackoverflow.com/a/14231729/105999before doing so.

注意:如果您有兴趣使用此技术进行编排发布,在这样做之前在https://stackoverflow.com/a/14231729/105999 上查看我的评论。

So how can we resolve this?

那么我们如何解决这个问题呢?

Let's take a look at a sample (see links below). I have a solution, PublishOnlyOne, with the following projects.

让我们看一个示例(见下面的链接)。我有一个解决方案PublishOnlyOne,其中包含以下项目。

  1. ProjA
  2. ProjB
  1. 项目A
  2. 项目B

ProjA has a publish profile named ‘siteone – Web Deploy', ProjB does not. When trying to publish this you may try the following command line.

ProjA 有一个名为“ siteone – Web Deploy”的发布配置文件,而 ProjB 没有。尝试发布此内容时,您可以尝试以下命令行。

msbuild.exe PublishOnlyOne.sln /p:DeployOnBuild=true /p:PublishProfile='siteone – Web Deploy' /p:Password=%password%

See publish-sln.cmd in the samples.

请参阅示例中的 publish-sln.cmd。

If you do this, when its time for ProjB to build it will fail because there's no siteone – Web Deployprofile for that project. Because of this, we cannot pass DeployOnBuild. Instead here is what we need to do.

如果你这样做,当 ProjB 构建它的时候会失败,因为没有该项目的站点 - Web 部署配置文件。因此,我们无法通过 DeployOnBuild。相反,这是我们需要做的。

  1. Edit ProjA.csproj to define another property which will conditionally set DeployOnBuild
  2. From the command line pass in that property
  1. 编辑 ProjA.csproj 以定义另一个属性,该属性将有条件地设置 DeployOnBuild
  2. 从命令行传递该属性

I edited ProjA and added the following property group before the Import statements in the .csproj file.

我编辑了 ProjA 并在 .csproj 文件中的 Import 语句之前添加了以下属性组。

<PropertyGroup>
<DeployOnBuild Condition=" '$(DeployProjA)'!='' ">$(DeployProjA)</DeployOnBuild>
</PropertyGroup>

Here you can see that DeployOnBuild is set to whatever value DeployProjA is as long as it's not empty. Now the revised command is:

在这里,您可以看到 DeployOnBuild 设置为 DeployProjA 的任何值,只要它不为空即可。现在修改后的命令是:

msbuild.exe PublishOnlyOne.sln /p:DeployProjA=true /p:PublishProfile='siteone – Web Deploy' /p:Password=%password%

Here instead of passing DeployOnBuild, I pass in DeployProjA which will then set DeployOnBuild. Since DeployOnBuild wasn't passed to ProjB it will not attempt to publish.

在这里,我没有传递 DeployOnBuild,而是传递 DeployProjA,然后它将设置 DeployOnBuild。由于 DeployOnBuild 未传递给 ProjB,因此它不会尝试发布。

You can find the complete sample at https://github.com/sayedihashimi/sayed-samples/tree/master/PublishOnlyOne.

您可以在https://github.com/sayedihashimi/sayed-samples/tree/master/PublishOnlyOne找到完整的示例。

回答by arni

There is a much simplersolution for this. MSBuild supports targeting a single project while building the solution. You do this by putting the project name in the Target parameter. Note that this is the visual name of the project you specify in the solution (not necessarily the same as the name of the .csproj file).

对此有一个更简单的解决方案。MSBuild 支持在构建解决方案时针对单个项目。您可以通过将项目名称放在 Target 参数中来完成此操作。请注意,这是您在解决方案中指定的项目的视觉名称(不一定与 .csproj 文件的名称相同)。

Note: The only "trick" needed here is to replace the dots (.) in the project name with underscores (_).

注意:此处唯一需要的“技巧”是将项目名称中的点 (.) 替换为下划线 (_)

Example MSBuild command line, if your project name is "Your.Project.Name":

示例 MSBuild 命令行,如果您的项目名称是“Your.Project.Name”:

msbuild.exe YourSolutionName.sln /T:"Your_Poject_Name" /P:DeployOnBuild=true /P:PublishProfile=YourPublishProfile.pubxml

You may also specify a build target for that project, but this target should exist for all projects in the solution:

您还可以为该项目指定一个构建目标,但该目标应该存在于解决方案中的所有项目中:

msbuild.exe YourSolutionName.sln /T:"Your_Poject_Name:Rebuild" /P:DeployOnBuild=true /P:PublishProfile=YourPublishProfile.pubxml

Sources

来源

  1. This is partially documented in MSDN since Visual Studio 2008: https://msdn.microsoft.com/en-us/library/ms164311(v=vs.140).aspx
  2. Special thanks to Vasil Trifonov for pointing out the replacement trick: http://www.codeproject.com/Articles/654910/How-to-build-a-specific-project-from-a-solution-wi
  1. 自 Visual Studio 2008 以来,这部分记录在 MSDN 中:https: //msdn.microsoft.com/en-us/library/ms164311(v=vs.140).aspx
  2. 特别感谢 Vasil Trifonov 指出替换技巧:http: //www.codeproject.com/Articles/654910/How-to-build-a-specific-project-from-a-solution-wi