MSBuild - want to get the output assembly - visual-studio

I have a .targets file in a folder named .pack I have this:
<PropertyGroup>
<TaskAssembly>$(OutputPath)netstandard2.1\Test.dll</TaskAssembly>
</PropertyGroup>
Why instead of MyProject\bin\Debug\netstandard2.1\MyProject.dll it locates like the below line?
MyProject\.pack\bin\Debug\netstandard2.1\MyProject.dll
Why .pack is there!?
Then wanted to use it with a Using task
<UsingTask
TaskName="brand.ProBuild.Tasks.TestFunction"
AssemblyFile="$(TaskAssembly)"
/>
Defined as inline address, played with slashes, cleared bin/obj, restarted, don't why it can't understand some addresses.
Defined and used several path variables in my targets files, some working correctly and some are troublesome especially when want to use parents or some problems with slashes '/', don't know maybe some addresses are working randomly. But what is wrong with the $(OutputPath) ?!
Visual-studio 2019, .Net Standard 2.1 (It has multiple targets I want to get that specific dll)

You should check in your main project, before the import node like <Import Project=".pack\xxx.targets" />, check whether you defined the outputpath property again like
<outputpath>.pack\bin\Debug\</outputpath>
Suggestion
From your description, you created a custom MSBuild task dll to use its new custom task in another project, first, please make sure that the Test.dll is in the output folder of your project called MyProject.
Then, check whether you have redefined the outputpath before the import xml node.
Like this:
<PropertyGroup>
<outputpath>.pack\bin\Debug\</outputpath>
</PropertyGroup>
..........
<Import Project=".pack\xxx.targets" />
........
<UsingTask
TaskName="brand.ProBuild.Tasks.TestFunction"
AssemblyFile="$(TaskAssembly)"
/>
If so, you should change OutputPath to bin\Debug\.
In addition, if it does not help you, please share the xxx.csproj of project MyProject with us so that we can troubleshoot your issue more quickly.
Update 1
Since you have only one targets file in your project, I suggest you could follow these suggestions:
1) close VS Instance, enter your project folder, delete the .vs hidden folder under the solution folder, bin and obj folder. Then ,restart your project to test again.
2) you can define the correct value in the xxx.csproj file before the imports xml node to force the correct value of outputPath.
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<OutputPath>bin\Release\</OutputPath>
</PropertyGroup>
.......
<Import Project="xxx.targets"/>

Related

$(ProjectDir) prebuild event macro incorrect

I am using Visual Studio 2017 and I have a pre-build event.
I have a project located at C:\Project\src\Project\, with a batch file doSomething.bat at C:\Project\src\Project\doSomething.bat.
In my pre-build event, I want to run doSomething.bat, so I have this script:
cd $(ProjectDir) && call ./doSomething.bat
However, $(ProjectDir) actually places me in C:\Project\src\Project\bin\Debug\netcoreapp1.1\
This is not what the documentation states. How can I fix this?
For SDK-based projects PreBuildEvent and PostBuildEvent are evaluated too early to receive "final" values for a lot of properties, they are even considered to be deprecated (see https://github.com/dotnet/project-system/issues/1569)
As a quick workaround, you can use $(MSBuildProjectDirectory) or $(MSBuildThisFileDirectory) which will give you the directory that the .csproj file is in.
For a more integrated solution, you can add a custom target to the csproj file like this (no cd step needed):
<Target Name="MyAfterBuild" AfterTargets="Build">
<Exec Command="test.bat" />
</Target>
There is a workaround on how to make it resolve common macros and properties correctly (discussed on the thread, mentioned by #MartinUllrich).
See an example on the link. The key points of the solution is to modify the .csproj file so:
The root tag stays without attributes: just <Project> rather than <Project Sdk="Microsoft.NET.Sdk">
Import Sdk.props at the beginning: <Import Sdk="Microsoft.NET.Sdk.Web" Project="Sdk.props" />
Import Sdk.targets before pre-, post- build events: <Import Sdk="Microsoft.NET.Sdk.Web" Project="Sdk.targets" />
I had this happen after I'd manually edited the project file.
I'd inadvertently moved this line:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
to below the <PropertyGroup><PreBuildEvent> ... elements from its original position above them.
Try this:
Open your project file, eg MyProject.csproj (or MyProject.vbproj).
Find <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> (or <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />).
Move it to directly above the beginning of your build event elements (<PropertyGroup><PreBuildEvent> ...)
Clean the project/solution, recompile and you should be good.
Note: I also had another project that had this error out of the box so I think it can "just happen" as well.

Can I add a common reference path in an MSBuild target/project file?

I'm trying to write a custom project (targets?) file that is to be included in several projects.
For example, inside all of my .csproj and .vbproj files I have:
<Import Project="..\MyCustomTargets\custom.targets"/>
Inside that file I have a custom target (AfterBuild) which copies the compiled files to another location.
However, I'd like to add a reference path that each project can look to when trying to resolve references. Is this possible?
For example, I'd like to add something like this to my .targets file:
<AdditionalReferencePath>C:\LookHereForReferences</AdditionalReferencePath>
I've found a few links that describe a little about how to do this but I can't get it working.
I'd like to add a reference path that each project can look to when trying to resolve references. Is this possible?
You can set a Property Group in your .targets file:
<PropertyGroup>
<AdditionalReferencePath>C:\LookHereForReferences</AdditionalReferencePath>
</PropertyGroup>
After import this targets file in to the project file, you can look it by $(AdditionalReferencePath) when trying to resolve references:
<Import Project="Common.targets" />
<Target Name="Test" AfterTargets="Build">
<Message Text="$(AdditionalReferencePath)"></Message>
</Target>

Visual Studio 2010: How to publish an ASP.NET web app to a target folder with MSBUILD?

In Visual Studio 2010, you know how you can change your configuration (debug, release, etc), right-click a project in the solution explorer, click publish, and have all the important web app project files for the selected configuration copied to a target folder along with an xdt-transformed web.config? Well, I am looking for the MSBUILD equivalent of exactly that.
My challenge to you: Provide the ONE LINE that I need to execute at my command prompt in order to accomplish this. No third party programs. No tutorial videos. Just a single, straight-up command that I can literally copy from your response, paste into a command window, modify as necessary to support my directory structure, and then hit enter.
If not, then perhaps someone could provide a link to a complete MSBUILD reference showing every command, switch, and value I can use at the command line.
Put the below to ProjectPublish.MSBuild.xml file (change PropertyGroup as needed):
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Publish">
<PropertyGroup>
<ProjectFile>Path\To\Web.csproj</ProjectFile>
<PublishDir>Path\For\Publish\Output</PublishDir>
<TempDir>Path\To\Temp\Folder</TempDir>
<BuildConfig>Release|Debug</BuildConfig>
</PropertyGroup>
<Target Name="Publish">
<MSBuild Projects="$(ProjectFile)"
Properties="Configuration=$(BuildConfig);WebProjectOutputDir=$(PublishDir);OutDir=$(TempDir)\;BuildingProject=true"
Targets="ResolveReferences;_CopyWebApplication" />
</Target>
</Project>
Calling this from command line (or .bat file) should do the trick:
%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ProjectPublish.MSBuild.xml
I found the solution I was looking for after all these months here
In case the above link goes bad, here's the skinny of what it says:
Unload then edit your project file. Look for the line where it's importing Microsoft.WebApplication.targets. Will look like:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
Beneath that line, paste in this XML:
<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>
Now, run this in a command prompt within the same folder as your project file:
msbuild TestWebApp.csproj "/p:Platform=AnyCPU;Configuration=Debug;PublishDestination=C:\pub" /t:PublishToFileSystem
Remember to specify the path to MSBUILD in the command or add the path to your global path environmental variable (which is what I did). On my machine, it was here:
C:\Windows\Microsoft.NET\Framework\v4.0.30319
To test this, I put a config transform in my Web.Release.config to add an AppSetting key (if you do this, make sure the AppSettings node is present in your base config file or you will get an error). When I used the above command to build the debug configuration, the key was not present in the published config file as expected. However, when I used the release config, the key was successfully added to the file.
I really wish Microsoft hadn't obfuscated the heck out of this. At any rate, this is the simplest solution I have found anywhere on the internet. I hope it helps the rest of you.

Avoiding local dependencies for MSBuild Community Tasks within Visual Studio 2010

I'm trying to start taking advantage of the MSBuild Community Tasks so right after installing the .msi package I've imported MSBuild.Community.targets within the <Project> element this way:
<Import Project="lib\MSBuild.Community.Tasks.targets" />
Interestingly I've noticed such file have a reference to the local installation path in MSBuildExtensionsPath and given that in lieu of keeping code dependencies as clean as possible I'm willing to pay the overhead of distributing/versioning them with every project, I was wondering if is it possible to sort of override the default/installation location with a project-relative one in the .cproj file?
The actual layout would be like:
Dotnet.Samples.Foobar
\src
Foobar.cs
\lib
MSBuild.Community.Tasks.targets
MSBuild.Community.Tasks.dll
Any guidance will be sincerely appreciated. Thanks much in advace for any suggestion you might want to share.
In MSBuild.Community.Tasks.targets specified the path to the dll.
<PropertyGroup>
<MSBuildCommunityTasksPath Condition="'$(MSBuildCommunityTasksPath)' == ''">$(MSBuildExtensionsPath)\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
<MSBuildCommunityTasksLib>$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll</MSBuildCommunityTasksLib>
</PropertyGroup>
You can override the path in the project.
<PropertyGroup>
<MSBuildCommunityTasksPath>lib</MSBuildCommunityTasksPath>
</PropertyGroup>
And leave import the same:
<Import Project="lib\MSBuild.Community.Tasks.targets" />

Ignore file from delete during WebDeploy

I'm using TeamCity to build and deploy a collection of MVC Applications via msbuild and WebDeploy.
In a step previous to my solution build/deploy, I copy an app_offline.htm to the deploy directory so that I can perform SQL updates and other web/solution management steps including the build.
One of the setting in the WebDeploy is to delete files that aren't included in the project, or not needed to run the site. This deletes my app_offline.htm file each time. While I understand this is kind of the desired result, is there a way to exclude this file from being deleted from the deployment directory upon the deploy?
I've tried adding an ItemGroup with the ExcludeFromPackageFiles option, with no results.
I had a similar problem, wanting to keep minified javascript files in the deployment package even though they're not part of the project.
I added a custom MSBuild target for this, that works for me:
<!-- ====== Package the minify files ===== -->
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles1;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>
MakeEmptyFolders
</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<Target Name="CustomCollectFiles1">
<ItemGroup>
<!-- =====Controls\Javascript folder ==== -->
<_CustomFilesForRootFolder Include=".\Controls\Javascript\*.min.js">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension) </DestinationRelativePath>
</_CustomFilesForRootFolder>
<FilesForPackagingFromProject Include="%(_CustomFilesForRootFolder.Identity)">
<DestinationRelativePath>.\Controls\Javascript\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
This other question " Custom app_offline.htm file during publish " suggests one possible way for the final result you describe:
I use my own
app_offline.htm_
file in the solution, which gets
published. My deployment script then
renames it (removing the trailing _)
to make it active.
I can then run my db scripts/do
whatever then rename the file bringing
the site back.

Resources