Build only the VS Setup project via command line - c#

I have a solution that contains many projects and a setup project (.vdproj).
I want to be able to build ONLY the setup project via command line.
I tried to use
devenv /build Debug "C:\\MySolution\MySolution.sln" /project "CSharpWinApp\CSharpWinApp.vdproj" /projectconfig Debug
but it also built the rest of my solution projects and I want to avoid it. I tried it few times in a row - no project has changed but it stil built it all. I tried to remove the .vdproj project dependencies but it didn't work. I got the message "This dependency was added by the project system and cannot be removed".
Any suggestions?

Use the following command line to build setup projects.
Note: Support for setup projects has been dropped from Visual Studio 2012.
devenv "c:\your solution file.sln" /Project "c:\your setup project file.vdproj" /Build "Release"
If you really have to use msbuild, create a msbuild project file and use the Exec task to call the command line above as demonstrated in Hassan's answer.

you can isolate your setup in a setup solution to be sure that it will not compile your application.
for building your setup project you can do this with TFSBuild 2010 as follow:
First, to automate the building of .vdproj project, you’re going to need to write your own msbuild file because they are not in msbuild format and therefore TFS Build does not know what to do with them. I found some good examples on the net on how to do this, but I updated mine a little for 2010. Here it is:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<Target Name="Build">
<PropertyGroup>
<DevEnv>$(ProgramFiles)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com</DevEnv>
<SolutionFile>$(MSBuildProjectDirectory)\MySolution.sln</SolutionFile>
<ProjectFile>$(MSBuildProjectDirectory)\MySetupProject\MySetup.vdproj</ProjectFile>
<Configuration>Release</Configuration>
</PropertyGroup>
<Exec Command="$(DevEnv) $(SolutionFile) /Rebuild $(Configuration) /Project $(ProjectFile) /ProjectConfig $(Configuration) /Log" ContinueOnError="false" IgnoreExitCode="false" WorkingDirectory="$(MSBuildProjectDirectory)" />
</Target>
</Project>
thank to Leonard Woody

Related

How to exclude one project out of multiple project from one solution during building using MSBuild in command prompt? [duplicate]

I need to build a solution, but exclude one project. How should I do it?
I searched a lot about this issue, but nothing could help.
An ItemGroup section rises the following exception:
Invalid element . Unknown task or datatype.
PropertyGroup also rises the exception.
Below is my code sample:
<project name="TI 8.1.6 build script">
<ItemGroup>
<Solution Include="${ROOT}\Core\TI Core.sln" Exclude="${ROOT}\Utilities\DTS Indexing Service\Tdi.Origami.IndexUpdaterServiceSetup\Tdi.Origami.IndexUpdaterServiceSetup.wixproj"/>
</ItemGroup>
...
</project>
How can I do this?
You can exclude projects at the solution level for a specific build configuration by using the Configuration Manager Dialog in Visual Studio:
Then you can simply invoke msbuild on the solution file specifying the build configuration to use:
msbuild /property:Configuration=Release MySolution.sln
The solution suggested by Enrico is the most versatile solution that would work always. An alternative solution might be to use a <MSBuild> task directly. This will work for you if you have all your project files under a particular directory, or be able to easily enumerate all projects you want to build (i.e. number of projects in your solution is not very big).
For example, this MSBuild file will build every project under your current directory except for a specific project:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<MyProjectReferences Include="**\*.*proj" />
<MyProjectReferences Exclude="Utilities\DTS Indexing Service\Tdi.Origami.IndexUpdaterServiceSetup\Tdi.Origami.IndexUpdaterServiceSetup.wixproj" />
</ItemGroup>
<Target Name="BuildAllExceptWixProject">
<MSBuild Projects="#(MyProjectReferences)" Targets="Build" />
</Target>
</Project>
Then you can build that using command line msbuild <myproject> /t:BuildAllExceptWixProject
In your solution file (.sln), remove the Build.0 entries. For example:
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyProject", "MyProject.vcxproj", "{2281D9E7-5261-433D-BB04-176A61500CA3}"
EndProject
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2281D9E7-5261-433D-BB04-176A61500CA3}.Debug|x86.Build.0 = Debug|x64
If you delete this "Build.0" entry, it will load in the solution fine, but will not be built, either through the GUI or via external MSBuild.
Since VS 2019 and MSBuild 16.7, the right way is to use Solution filters. Ref
create a master.proj file:
in another ItemGroup add DefaultExclude properties for programs - put it in front of the solution
-- BA was Canadian
Configuration=Release
Release
drop the master.proj into the directory with the programs and msbuild the master.proj
compiles everything except... that HelloWorld

C# Build failed using MSbuild without Visual Studio [duplicate]

Trying to build my project on the build server gives me the following error:
Microsoft (R) Build Engine Version 4.0.30319.1
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\TeamData\Microsoft.Data.Schema.SqlTasks.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
I solved this problem a few months ago, with installing Visual Studio 2010 on the Build Server. But now I'm setup a new server from scratch, and I want to know if there any better solution to solve this issue.
To answer the title of the question (but not the question about the output you're getting):
Copying the following folder from your dev machine to your build server fixes this if it's just web applications
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications
Remove x86 according to how your build breaks. If you have other project types you will probably need to copy the entire msbuild folder.
The solution would be to install redistributable packages on build server agent. It can be accomplished multiple ways, out of which 3 are described below. Pick one that suits you best.
Use installer with UI
this is the original answer
Right now, in 2017, you can install WebApplication redists with MSBuildTools. Just go to this page that will download MSBuild 2017 Tools and while installation click Web development build tools to get these targets installed as well:
This will lead to installing missing libraries in C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications by default
Use command line
disclaimer I haven't tested any of the following proposals
As #PaulHicks and #WaiHaLee suggested in comments, it can also be installed in headless mode (no ui) from CLI, that might actually be preferable way of solving the problem on remove server.
Solution A - using package manager (choco)
choco install visualstudio2017-workload-webbuildtools
Solution B - run installer in headless mode
Notice, this is the same installer that has been proposed to be used in original answer
vs_BuildTools.exe --add Microsoft.VisualStudio.Workload.WebBuildTools --passive
Building and publishing WAPs is not supported if VS is not installed. With that said, if you really do not want to install VS then you will need to copy all the files under %ProgramFiles32%\MSBuild\Microsoft\.
You will need to install the Web Deploy Tool as well. I think that is it.
UPD: as of VS2017, there is workload in Build Tools that eliminates this problem completely. See #SOReader answer.
If you'd prefer not to modify anything on build server, and you still want the project to build right out of source control, it might be a good idea to put the required binaries under source control. You'll need to modify the imports section in your project file to look like this:
<Import Project="$(SolutionDir)\BuildTargets\WebApplications\Microsoft.WebApplication.targets" />
<Import Condition="false" Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
The first line is the actual import from the new location that is relative to the solution directory. The second one is a turned-off version (Condition="false") of the original line that allows for Visual Studio to still consider your project to be a valid Web Application Project (that's the trick that VS 2010 SP1 does itself).
Don't forget to copy the C:\Program Files (x86)\Microsoft\VisualStudio\v10.0\WebApplications to BuildTargets folder under your source control.
You can also use the NuGet package MSBuild.Microsoft.VisualStudio.Web.targets, referencing them within your Visual Studio project(s), then change your references as Andriy K suggests.
Based on this post here you can simply download the Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package and the targets are installed.
This avoids the need to install Visual Studio on the build server.
I have just tried this out now, and can verify that it works:
Before:
error MSB4019: The imported project "C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets"
was not found. Confirm that the path in the declaration is
correct, and that the file exists on disk.
After the install:
[Builds correctly]
This is a far better solution than installing Visual Studio on a build server, obviously.
The latest Windows SDK, as mentioned above, in addition to the "Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package" for Microsoft.WebApplication.targets and "Microsoft Visual Studio Team System 2008 Database Edition GDR R2" for Microsoft.Data.Schema.SqlTasks.targets should alleviate the need to install Visual Studio 2010. However, installing VS 2010 maybe actually be less overall to download and less work in the end.
Add dependency through NuGet & set a Build Parameter
Goal: no changes / installs necessary to the build agents
I have taken a hybrid approach to the NuGet approach by Lloyd here, which was based off of the committing binary dependencies solution by Andrik.
The reason why is I want to be able to add new build agents without having to pre-configure them with items such as this.
On a machine with Visual Studio, Open the solution; ignore that the web project fails.
In the NuGet package manager, add MSBuild.Microsoft.VisualStudio.Web.targets, as Lloyd mentioned.
This will resolve the binaries to [solution]\packages\MSBuild.Microsoft.VisualStudio.Web.targets.nn.n.n.n\tools\VSToolsPath\
You can copy these to a references folder & commit,
Or just use them where they are at. I chose this, but I'm going to have to deal with the version number in the path later.
In Version 7, I did the following. This may not have been necessary, and based on the comments is definitely not needed now. Please see the comments below.
Next, in your TeamCity build configuration, add a build Paramenter for env.VSToolsPath and set it to the VSToolsPath folder; I used ..\packages\MSBuild.Microsoft.VisualStudio.Web.targets.11.0.2.1\tools\VSToolsPath
When building on the build/CI server, turn off the import of Microsoft.WebApplication.targets altogether by specifying /p:VSToolsPath=''. This will, essentially, make the condition of the following line false:
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
This is how it's done in TeamCity:
If you migrate Visual Studio 2012 to 2013, then open *.csproj project file with edior.
and check 'Project' tag's ToolsVersion element.
Change its value from 4.0 to 12.0
From
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" ...
To
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" ...
Or If you build with msbuild then just specify VisualStudioVersion property
msbuild /p:VisualStudioVersion=12.0
Solution Source
It seems the new version of msbuild does not ship with Microsoft.WebApplication.targets. To fix you need to update your csproj file as so:
1) Edit the web app csproj (right click). Find the section in the csproj towards the bottom concerning build tools. It should look like so.
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
2) You need to add one VSToolsPath line below the VisualStudioVersion tag so it looks like so
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<!--Add the below line to fix the project loading in VS 2017 -->
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<!--End -->
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
Reference link:
https://alastaircrabtree.com/cannot-open-vs-2015-web-project-in-vs-2017/
This is all you need. Only 103MB. Don't install everything
I have found this on MS connect:
Yes, you need to install Visual Studio
2010 on your build machine to build
database projects. Doing so does
not require an additional license of
Visual Studio.
So, this is the only option that I have for now.
Anyone coming here for Visual Studio 2017. I had the similar issue and couldn't compile the project after update to 15.6.1.
I had to install MSBulild tools but still the error was there.
I was able to fix the issue by copying the v14.0 folder from C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio to the same folder as v15.0 and that resolved all the errors.
So now my folder structure looks like below, where both folders contain the same content.
If you are using MSBuild, as in the case of a build server, what worked for me is:
Change the following:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
to:
<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
My Msbuild command is: *"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" solution.sln /p:Configuration=Debug /p:Platform="Any CPU"*
Hope this helps someone.
My solution is a mix of several answers here.
I checked the build server, and Windows7/NET4.0 SDK was already installed, so I did find the path:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets`
However, on this line:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
$(MSBuildExtensionsPath) expands to C:\Program Files\MSBuild which does not have the path.
Therefore what I did was to create a symlink, using this command:
mklink /J "C:\Program Files\MSBuild\Microsoft\VisualStudio" "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio"
This way the $(MSBuildExtensionsPath) expands to a valid path, and no changes are needed in the app itself, only in the build server (perhaps one could create the symlink every build, to make sure this step is not lost and is "documented").
I fixed this by adding
/p:VCTargetsPath="C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\V120"
into
Build > Build a Visual Studio project or solution using MSBuild > Command Line Arguments
I tried a bunch of solutions, but in the end this answer worked for me: https://stackoverflow.com/a/19826448/431522
It basically entails calling MSBuild from the MSBuild directory, instead of the Visual Studio directory.
I also added the MSBuild directory to my path, to make the scripts easier to code.
I was having this issue building a SQL Server project on a CI/CD pipeline. In fact, I was having it locally as well, and I did not manage to solve it.
What worked for me was using an MSBuild SDK, capable of producing a SQL Server Data-Tier Application package (.dacpac) from a set of SQL scripts, which implies creating a new project. But I wanted to keep the SQL Server project, so that I could link it to the live database through SQL Server Object Explorer on Visual Studio. I took the following steps to have this up and running:
Kept my SQL Server project with the .sql database scripts.
Created a .NET Standard 2.0 class library project, making sure that the target framework was .NET Standard 2.0, as per the guidelines in the above link.
Set the contents of the .csproj as follows:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="MSBuild.Sdk.SqlProj/1.0.0">
<PropertyGroup>
<SqlServerVersion>Sql140</SqlServerVersion>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
I have chosen Sql140 as the SQL Server version because I am using SQL Server 2019. Check this answer to find out the mapping to the version you are using.
Ignore the SQL Server project on build, so that it stops breaking locally (it does build on Visual Studio, but it fails on VS Code).
Now we just have to make sure the .sql files are inside the SDK project when it is built. I achieved that with a simple powershell routine on the CI/CD pipeline that would copy the files from the SQL Server project to the SDK project:
Copy-Item -Path "Path.To.The.Database.Project\dbo\Tables\*"
-Destination (New-item -Name "dbo\Tables" -Type Directory -Path "Path.To.The.DatabaseSDK.Project\")
PS: The files have to be physically in the SDK project, either in the root or on some folder, so links to the .sdk files in the SQL Server project won't work. In theory, it should be possible to copy these files with a pre-build condition, but for some obscure reason, this was not working for me. I tried also to have the .sql files on the SDK project and link them to the SQL Server project, but that would easily break the link with the SQL Server Object Explorer, so I decided to drop this as well.
In case if you're trying to deploy a project using VSTS, then issue might be connected with checking "Hosted Windows Container" option instead of "Hosted VS2017"(or 18, etc.):
I fixed this by running the build in a docker container, specifically dotnet/framework/sdk. It includes the VS build tools.
Creating a new project and copying over the settings should probably provide the best guidance in what to do. This is what it looks like on mine
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
In my case, It was just a Port-Block.
After installation of MSBuild tools from Microsoft, define the MSBuild path in the environment variable, so that it can be run from any path.
Edit the .csproj file in any notepad editor such as notepad++, and comment the
Check for the following elements,
-->
Make sure you use import only once, choose whichever works.
Make sure you have the following folder exists on the drive, "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0" or whichever version is referenced by MSBuild target at "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets"
From the command prompt, run the following command, to check
C:>msbuild "C:\\DotnetCi.sln" /p:Configuration=Release /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false
choose /p switch as appropriate, refer to enter link description here
enter image description here

How can I get the clickonce build script used by visual studio to publish my application

I have a pretty large multi-project solution. I currently build it in Visual Studio, and then publish using the right-click=> publish option. This works very well.
I am now in the position where I need to automate at least the clickonce publishing beyond what I can do in Visual Studio. I have successfully created a publish.xml file which I can use with msbuild and mage to create something that looks like a clickonce. However, there is a lot of complexity in the config I have in the visual studio interface that I would like to simply be able to copy into my publish.xml file.
Is it possible to get visual studio to generate a file that provides the properties used by MSBuild and/or Mage when visual studio publishes from the right click=> publish process?
Basically, I would like a configuration file that I could use to do something like msbuild publish.xml (or similar) and get exactly the publish result that visual studio makes.
I currently use VS2017. The application is winforms using c#
Here is my publish.xml. It is not supposed to be anything beyond a test
<Project>
<PropertyGroup>
<OutputPathBuild>C:\Users\d_000\Documents\Visual Studio 2017\Projects\CP\CP.UI.Winforms\bin\x86\Debug</OutputPathBuild>
<Version>1.0.0.0</Version>
<OutputPathDeployment>C:\Users\d_000\Documents\CP Deploy\test</OutputPathDeployment>
<Mage>C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\mage.EXE</Mage>
</PropertyGroup>
<Target Name="Deployment">
<Error Condition="'$(Version)'==''" Text="The Version property must be defined in order to build the Deployment task."/>
<ItemGroup>
<DeploySource Include="$(OutputPathBuild)\**"/>
</ItemGroup>
<Copy SourceFiles="#(DeploySource)" DestinationFolder="$(OutputPathDeployment)\v$(Version)\%(RecursiveDir)"/>
<Exec Command='"$(Mage)" -New Application -ToFile "$(OutputPathDeployment)\v$(Version)\MyApp.manifest" -Name MyApp -Version $(Version) -Processor X86 -FromDirectory "$(OutputPathDeployment)\v$(Version)" -IconFile Resources\CPIcon.ico'/>
<Exec Command='"$(Mage)" -New Deployment -ToFile "$(OutputPathDeployment)\MyApp.application" -Name MyApp -Version $(Version) -Processor X86 -AppManifest "$(OutputPathDeployment)\v$(Version)\MyApp.manifest" -IncludeProviderURL true -ProviderURL "http://example.com/download/MyApp/MyApp.application" -Install true'/>
<!-- Grr... Mage tool has a bug whereby -MinVersion only works in Update mode... -->
<Exec Command='"$(Mage)" -Update "$(OutputPathDeployment)\MyApp.application" -MinVersion $(Version)'/>
<Copy SourceFiles="$(OutputPathDeployment)\MyApp.application" DestinationFiles="$(OutputPathDeployment)\MyApp.v$(Version).application"/>
</Target>
</Project>
EDIT:
I need to customize what is in the publish process, so I am looking to find out what Visual Studio is doing. Essentially I want to get the commands run in visual studio, copy them and tweak them so I can automate several different builds with different delpoy URLs and update URLs
The work of k7 helped me get to my solution - so I marked it as the answer, but this gives details of how I solved it in the end.
So, it turns out that all the information to run a publish is included in the project file, and you can almost just run this through msbuild (line breaks added for clarity). For those new to the architecture of the csProj file, it contains lots of properties for the project used in building, publishing and configuring generally, and also a set of targets, which are kind of like different jobs you can run. You run them by specifying the /t: option using msbuild. Targets not specified aren't executed.
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj" /t:publish
The gotchas are that;
if you refer to the project in the build command instead of the solution, then you also need to specify the solution folder
unless you specify rebuild before publish, any updates you make to your project config will not be reflected in the output - which is an issue if you are publishing under multiple configurations
Specify where to deploy
You likely also want to specify platform and config
In this case, my command became
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\\
At this point I am just rebuilding and publishing my project, just like I can in visual studio.
When I wanted to customize, I just added the additional information into the command line to override;
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release
/p:PublishDir="C:\Users\me\Documents\Deploy\web\\
/p:UpdateUrl=http://example.com/
/p:ExcludeDeploymentUrl=false
I wanted to take this a bit further and cut down some of the commands, so I modified myProj.csProj - but I wanted to keep the code separate. I did this by adding an import directly after my publish info in the project file (this is the property group with members likePublishURL and UpdateEnabled). This goes straight after the relevant tag
<Import Project="CustomBuild.targets" />
The CustomBuild.targets file contained by different configs.
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishType>none</PublishType>
</PropertyGroup>
<Choose>
<When Condition="'$(PublishType)' == 'web'">
<PropertyGroup>
<PublishDir>C:\Users\me\Documents\Deploy\Web\</PublishDir>
<PublishUrl>C:\Users\me\Documents\Deploy\Web\</PublishUrl>
<MapFileExtensions>false</MapFileExtensions>
<UpdateUrl>http://www.example.com/myAppUpdate</UpdateUrl>
<ExcludeDeploymentUrl>false</ExcludeDeploymentUrl>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
</PropertyGroup>
</When>
<When Condition=" '$(PublishType)' == 'network' ">
<PropertyGroup>
<PublishDir>C:\Users\me\Documents\Deploy\Network\</PublishDir>
<PublishUrl>C:\Users\me\Documents\Deploy\Network\</PublishUrl>
<MapFileExtensions>false</MapFileExtensions>
<UpdateUrl>\\DummyServer\Share\</UpdateUrl>
<ExcludeDeploymentUrl>true</ExcludeDeploymentUrl>
</PropertyGroup>
</When>
</Choose>
</Project>
This code provides me with two configs (web and network) that I can use from the command line with a simple switch (in my case PublishType) like this;
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\bin\msbuild.EXE"
"C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\myProj"
/:SolutionDir="C:\Users\me\Documents\Visual Studio 2017\Projects\mySoln\\"
/t:rebuild /t:publish
/p:PlatformTarget=x86 /p:Configuration=Release /p:PublishType=web
My code does not specify autoincrementing of the build because it is not relevant to me, but this is relatively easy to do with a bit of research into the msbuild tool and targets - or using the info from k7 above.
If you want to create ClickOnce for different stages you have to manipulate the proj file before you call MSBuild.
1) Read your .proj file
$projFilePath = Get-ChildItem $sourceRootDirectory -Filter $ProjectFileName -Recurse
$XmlDocument = [xml] (Get-Content -Path $projFilePath.FullName -Encoding UTF8)
2) You have to update this attributes in your proj files:
$ClickOnceForStages.Split("Dev", "Test", "UAT", "Prod") | Foreach {
$XmlDocument.project.PropertyGroup[0].ApplicationRevision = $BuildRevision
$XmlDocument.project.PropertyGroup[0].ApplicationVersion = $BuildVersion
$XmlDocument.project.PropertyGroup[0].ProductName = "MyProductName.$_"
$XmlDocument.project.PropertyGroup[0].AssemblyName = "MyAssemblyName.$_"
$XmlDocument.project.PropertyGroup[0].PublishUrl = "MyClickOnceDropUncPath_$_"
}
You have to make sure that:
$BuildRevision and $BuildVersion
have a increased version for each build.
3) Save the document without manipulating the orginal proj file.
$currentProjFilePath = $projFilePath.FullName +"_" + $_ + ".proj"
$XmlDocument.Save($clickOnceProjFilePath)
4) Call MSBuild to create a ClickOnce installer.
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
The combination of your proj file with the ClickOnce configuration and the MSBuild parameter:
"/target:publish"
creates a ClickOnce installer.
This is the full MSBuild statement which I use to create a ClickOnce installer:
"$clickOnceProjFilePath",
"/target:publish",
"/p:PublishDir=$outputDirectory",
"/p:Configuration=Release"

Adding and running custom target by msbuild

I am struggling with seemingly very basic task at the moment, that is addding a new custom target to csproj file and run it from the command line using msbuild.
I did an extensive research on the net but I found no solution that is actually working.
Let's say that I add the following target to my csproj file:
<Target Name="TeamCity">
<Message Text="I am Running!"/>
</Target>
or even something that depends on Build:
<Target Name="TeamCity" DependsOnTargets="Build">
<Message Text="I am Running!"/>
</Target>
This is what msbuild documentation suggests.
But running the target seems to be a mission impossible.
While I am able to run predefined target on csproj:
msbuild MySolution.sln /t:MyProject:Rebuild /p:Configuration="Release" /p:Platform="Any CPU"
I am not able to run the target I just added - that is TeamCity target:
msbuild MySolution.sln /t:MyProject:TeamCity /p:Configuration="Release" /p:Platform="Any CPU"
I always get error MSB4057: The target "TeamCity" does not exist in the project.
What is the deeply kept secret to make this running?
PS. Please note that I need the task to be working on a project level not on a solution. And I need to run msbuild MySolution.sln ... not as many incorrectly suggest msbuild MyProject.csproj ...
The secret is pretty simple - you can't make this running.
Because, msbuild generates intermediate project file (YourSolution.sln.metproj) but that will not have the imports from YourProject.csproj, including the .targets files. That's why YourCustomTarget is not recognized.
What you can try is using Before/After Targets to inject your targets in predefined build flow.
Hope it will help.

roslyn compiler not copied to AspnetCompileMerge folder using msbuild

I have a .NET MVC project that I'm trying to deploy using Jenkins.
I had been letting Jenkins run msbuild, then copying the resulting files out using RoboCopy. I wanted to switch to just use a publish profile. The publishing profile works fine on my local machine using Visual Studio, but on the Jenkins host it fails using msbuild.
The error it gives is
ASPNETCOMPILER : error ASPRUNTIME: Could not find a part of the path 'C:\Program Files (x86)\Jenkins\jobs\myProject\workspace\myProject\obj\Debug\AspnetCompileMerge\Source\bin\roslyn\csc.exe'. [C:\Program Files (x86)\Jenkins\jobs\myProject\workspace\myProject\calendar.csproj]
I'm using the Microsoft.Net.Compilers nuget package to pull in the C# compiler, because some of the collaborators on the project are still on Visual Studio 2013, but we're using C#6 language features in the project.
Thing is, the project built just fine using MSBuild on jenkins before I added the publish flag. It's only since adding the /p:DeployOnBuild=true;PublishProfile=MyProfile setting that it started failing... yet the publish step works fine from withing Visual Studio, and the roslyn compiler even gets copied to the obj\Debug\AspnetCompileMerge\Source\bin\ folder on my local machine. What gives?
Honestly, since msbuild14 is available on the Jenkins server, it probably doesn't even need the roslyn csc.exe file. Is there a way I can make msbuild ignore it?
My Publish Profile
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>\\myserver\someshare\mysite</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<PrecompileBeforePublish>True</PrecompileBeforePublish>
<EnableUpdateable>True</EnableUpdateable>
<DebugSymbols>False</DebugSymbols>
<WDPMergeOption>DonotMerge</WDPMergeOption>
</PropertyGroup>
</Project>
What I've Tried So Far
I've tried updating the compiler package.
Manually copying compiler
I added steps to my .csproj file to force-copy the missing compiler files to the AspnetCompileMerge directory (I'd already been copying them to the bin\roslyn directory to resolve another problem)
<Target Name="CopyRoslynFiles" AfterTargets="BeforeBuild">
<ItemGroup>
<RoslynFiles Include="$(SolutionDir)packages\Microsoft.Net.Compilers.1.1.1\tools\*" Exclude="$(SolutionDir)packages\Microsoft.Net.Compilers.1.1.1\tools\*.sys" />
</ItemGroup>
<MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
<MakeDir Directories="$(WebProjectOutputDir)\obj\$(Configuration)\AspnetCompileMerge\Source\bin\roslyn" />
<Copy SourceFiles="#(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
<Copy SourceFiles="#(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\obj\$(Configuration)\AspnetCompileMerge\Source\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>
Turning off Updateability in the publish profile
Based on Wesley Rathburn's answer on a similar question, I tried making the precompiled site so it could not be updated in the publish profile:
<EnableUpdateable>False</EnableUpdateable>
Though this revealed some dead code that needed removed in my views, it didn't fix the error during the jenkins build.
Running MsBuild locally
I can successfully run the msbuild command on my local machine. It deploys to the server and everything. Here's the command I run in powershell:
&"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /p:Configuration=Debug "/p:DeployOnBuild=true;PublishProfile=MyProfile" myproject\myproject.csproj
Removing the statements that copy the compiler entirely
It occurred to me that maybe I didn't need the statements to copy the roslyn compiler to the bin folder anymore, since msbuild14 was available on Jenkins now (and I'm not sure it was when I first built the project). Sadly, same error occurs. It's looking for the roslyn\csc.exe file, even though there's no apparent need for it to do so!
Just putting this here, because I spent two days trying to resolve this same issue (roslyn csc.exe not copied), but none of these answers solved my problem.
It turns out that Microsoft.CodeDom.Providers.DotNetCompilerPlatform 1.0.6 (and 1.0.7) is broken. Downgrade to 1.0.5.
I was getting the same errors as everyone else here, but I'm using VS 2017, and both local WebDeploy as well as AzureDeploy were broken (no csc.exe found). I tried all the suggestions that I could find on the internet (most of them redirect back to this SO post) but nothing worked until I downgraded to 1.0.5.
So I hope this is helpful to anyone who is struggling and has just recently upgrade to 1.0.6!
See:
https://github.com/aspnet/RoslynCodeDomProvider/issues/13
and
https://github.com/dotnet/roslyn/issues/21340
So, the workaround I'm using for now (which I don't entirely like), is just to remove the dependencies on the Compilers and CodeDOM Compilers packages. I also had to clear out the references in the .csproj and web.config files. That involved removing those packages from a shared assembly as well.
This will break the project for people still using Visual Studio 2013, which I don't like, but it builds on my Jenkins host now, which I do like. If anyone has a better solution, I'd be happy to hear it.
So yeah, I have this problem too with VS2017 & VS2019 and Microsoft.CodeDom.Providers.DotNetCompilerPlatform2.0.1 too. Did a lot of troubleshoooting msbuild and digging deep and trying to do my own workarounds and the changes in build file that just did nothing, but that didn't seem right at all. So I started looking in a different direction.
What I discovered was I couldn't build a .csproj directly and have either the nuget targets in Microsoft.CodeDom.Providers.DotNetCompilerPlatform get run by msbuild, or my own custom ones.
However using msbuild with the .sln with a target of myproj:Rebuild made everything work.

Categories

Resources