Get publish directory in MSBuild - msbuild

I have an asp.net mvc application that I am publishing with Publish feature of Visual Studio and I have a custom MSBuild task that needs the directory that I am publishing to so it knows where to copy some custom build files to...
I've tried $(OutDir), $(PublishDirectory) and a bunch of others... how do I get this path?

For me what worked was:
$(PublishUrl)
And i got what i was needing: My publish directory.
Thanks.

I was able to combine $(ProjectDir) & $(PublishDir) to get the publishing folder. However, I was publishing SharePoint app but I think it should work for other cases as well.
For example to call a program
<Exec Command=""$(ProjectDir)\app.exe" "$(ProjectDir)$(PublishDir) ""/>

You should be able to use the PackageArchiveRootDir property to resolve that. The default value for that is obj\Debug\Package. So if you need the full path you just combine the MSBuildProjectDirectory with the PackageArchiveRootDir like: $(MSBuildProjectDirectory)\$(PackageArchiveRootDir).

Related

MSBuild not publishing dll.config of dependency for ClickOnce

My C# projectA published via ClickOnce depends on projectB. I need the projectB.dll.config file for projectA to work. While MSBuild copies over projectB.dll.config to projectA/bin/ConfigXY correctly, it is not published. VisualStudio (2017) doesn't even show the file in Application->Publish->Application Files.
As a workaround, I added this to A.csproj:
<Content Include="..\projectB\bin\Release\projectB.dll.config">
<Link>projectB.dll.config</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Now VS shows the file in the "Application Files" list, but this of course works only for the Release build config. Since I have lots of configs in project A that map to different configs in B, I cannot simple use $(Configuration) in the path.
I have found some suggestions to include ..\**\*.dll.config, but that seems dangerous, as when both the Debug and Release folder exist (from a previous build), I might end up with the wrong one.
What's the right way to do this?
I’d like to post this as a comment, but due to the limitations, I post it as an answer and I am sorry for that.
I did some tests, and it seems, to include the project.dll.config file to be published(shown in Application > Publish > Application Files), we need to include this file to the projectA.
I guess you mean you want to use “..\XXX\XXX\Release\projectB.dll.config” path for Release build and use ““..\XXX\XXX\Debug\projectB.dll.config” path for Debug build without using $(Configuration) right?
Generally, MSBuild uses $(configuration) to switch the configuration mode, if it is not available for you, to my knowledge, from MSBuild side, it is hard or not possible to switch/match the configuration mode.

Exclude folder when building from VSO to Azure website

I am trying to exclude certain files/folders from deployment of a web project in Visual Studio Online to an Azure website.
The web project has a Content folder with CSS, JS, build scripts and so on, which are only necessary for development, once deployed to Azure the CSS and JS is loaded from a CDN. Currently the build from VSO is copying all those files to the webroot in Azure, which is unnecessary and a potential security issue in case of the build scripts.
Now I know this can be prevented by setting the build action of a file to None, but this a very tedious solution because there is a lot of development going on, new files get added all the time and it is easy to forget this setting.
First I tried setting the Content folder to Cloaked in the build definitions source settings, but this only causes VSO to not download this folder on build, msbuild will still complain that those files are missing.
Is there a way to tell msbuild to ignore the whole Content folder? I already tried adding /p:ExcludeFoldersFromDeployment="Content" as a msbuild argument in the build definition, and also tried the solutions in here How to get Visual Studio 'Publish' functionality to include files from post build event?, but nothing is working.
I was studying msbuild log files and came up with a solution that is good enough for us to work with.
The first thing I learned was that I cannot prevent msbuild from copying files with build action Content to the output directory, at least not without changing the Microsoft.WebApplication.targets file, which I didn't want to do and am not even sure is possible with VSO build.
Anyway because of this we cannot set the source settings of our Content folder to Cloaked in the build definition, since this will cause the build to fail.
What we ended up doing was described in this answer: https://stackoverflow.com/a/3140349/1230302
So by adding the ExcludeFoldersFromDeployment statement to the .csproj file, the Content folder is excluded from the webroot.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\</OutputPath>
<ExcludeFoldersFromDeployment>Content</ExcludeFoldersFromDeployment>
</PropertyGroup>
It is not an ideal solution, but at least this way nothing gets deployed if a developer forgets to set the build action to None.
The built in continuous delivery options are designed for convenience. Of you need something custom, like skipping deployment of files that have not changed, then you will need to write something yourself.
You can easily call PowerShell to complete any task from the build process.
If you'd like to customize your build as part of the VSO build system, you can just override your BuildTemplate.xaml file.
Visual Studio Build uses Windows Workflow (xaml) to make a workflow on what the build is supposed to do. You can edit this file and do any modifications to the directory structure before or after the build.
Here is an example.

TeamCity config

We're pretty new to TeamCity at work. We have a build & deployment pckage setup which is using MSBuild/MSDeploy to ship changes to our web servers. However, we have a few issues (apologies for putting a few questions on the same post). For clarification our solutions looks like so:
Project Folder
WebApp (includes .csproj file. Includes a folder called "media" - this folder is not in SVN)
Libraries (includes referenced assemblies)
Our issues:
There is a specific folder within the Libraries folder that must be copied into the bin directory after build (because of an assembly redirect). We have always used a PostBuild event, however this doesnt work in TeamCity.
The folder "media" within the WebApp folder is not included in SVN. When the TeamCity package is executed it deletes this folder. I would like to prevent TeamCity from deleting just this folder.
When we run the TeamCity task, we get an ERROR_FILE_IN_USE error for one of the files teamcity is trying to delete during the sync task. I have read about using the app_offline.htm file to combat this - but quite how Im not sure.
I'm going to guess that some of these settings can be command line parameters in the msbuild job - I think it would be better to store these in the csproj file rather than just in teamcity if it is possible?
thanks in advance
Al
A few questions on the information provided
Can you clarify what you mean by post-build command doesnt work? Does it fail or does it just not do what you expect?
How have you setup your post-build command? does it reference specific filepaths? TeamCity executes MSBuild in the same was as you could from the command line or from visual studio.
Regarding the MSDeploy folder issue, you can configure MSDeploy with a Skip Action, here's a link to another post describing how to do this
Prevent MSDeploy (selectively) from deleting folders on target IIS server
Because MSDeploy is trying to deploy into a folder being used by IIS you are also seeing the file locking issue. There are two solutions
1. Add a teamcity step to stop IIS (using PowerShell) before deploying. This will cause downtime.
2. Deploy to a different folder and then switch IIS to point to your new folder. This is a much better solution as you also have roll back.
A much easier solution to all of this is to use a Deployment Tool such as Octopus Deploy to deploy your application. You can learn more about Octopus Deploy at http://octopusdeploy.com/

What parameters does TeamCity pass to MSBuild under the covers?

I just downloaded TeamCity 7 today and decided to get it up and running for my Azure solution. I am not trying to do anything fancy (yet) and started with a very basic command line build:
msbuild /t:Publish /p:Configuration=Release;TargetProfile=Production;PublishDir=S:\HoursTracker\Deployments
This builds successfully and produces a package that looks like this*:
I then attempted to configure TeamCity in an identical fashion:
This builds successfully and produces a package that looks like this*:
What I don't understand is why there is such a huge discrepancy in the size of the MVC project. Publishing directly from Visual Studio produces the exact same result as my MSBuild command so I'm convinced that TeamCity is the odd man out. Since I assume TeamCity is not broken, can someone please educate me on how to properly configure it so that I get the expected output?
*I have renamed the package files with .zip so that the details were viewable for this post.
Ming's answer helped me solve the mystery. After inspecting the contents of the zip files, I discovered the difference was that my MSBuild package contained bin and obj folders and the TeamCity package did not.
After making this discovery, I realized that I could specify multiple targets to MSBuild and prepended "Clean" to my targets switch like so:
msbuild /t:Clean;Publish /p:Configuration=Release;TargetProfile=Production;PublishDir=S:\HoursTracker\Deployments
As expected, this removed those folders. So apparently, TeamCity specifies "Clean" implicitly for you. Mystery solved.
Windows Azure packages may be larger than we expect. You can rename the cssx file to zip and you will find out what’s inside the package. In addition to the web application’s usual files, there’re a bunch of Windows Azure files. For example, if you enable diagnostics, you will see a diagnostics folder, where you’ll find files used by Windows Azure diagnostics runtime.
Best Regards,
Ming Xu.
Why you specified x64 for msbuild runner? Try selecting tools version as well. You have not specified /p:Platform parameter. Does publish task involve rebuild?
TeamCity starts msbuild with number of /p: parameters taken from " properties and environment variables " section, plus some well-known parameters like configuration name or project name.

How to specify MSDeploy parameters from MSbuild

I have a web application that I am trying to deploy and have the web.config file parametrised.
I can build the package by running
msbuild myproj.csproj /T:package
now when it produces the package, i get a file in the directory.
Archive.SetParameters.Xml
This file has Parameters in it that if I change they would end up in the deployed package. My Question is, how can i define more parameters so that when I build the project it has my extra parameters in the file.
I belive i could do it using MSDeploy -declareParam But how would I do this from MSBuild? or the .csproj file.
My end goal is to have a parametrised Web.config file for deployment into multiple environments.
Ok so turns out this is fairly easy, after some significant googling eventually found this post
http://vishaljoshi.blogspot.com/2010/07/web-deploy-parameterization-in-action.html
VS 2010 makes your life easier by allowing you to simply drop the
Parameters file in the root of your web project and if a file with the
name Parameters.xml is found in the root of your project it passes it
to Web Deploy which then parameterizes your web…