Visual Studio Post build command line Deployment - visual-studio

In Visual Studio am creating a post-build event for Deploying using
md "$(SolutionDir)Deploy\bin"
which created the bin folder inside Deploy folder, inside my Solution.
How do I point this to the folder in some remote machine (where I have the web server)?
$(SolutionDir) to some other folder on a remote machine?
It may look simple to you. :) This is the first time am trying this stuff.
Thanks

The easiest way is to replace $(SolutionDir) with \\server\share

Just as an alternative, I like to keep my .sln and .csproj files "clean".
Then use a second (mini) .msbuild ( which is just a .xml file) to build the .sln, and then do these copy type events as a second action.
Here is a basic example:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapper">
<PropertyGroup>
<WorkingCheckout>.</WorkingCheckout>
<WorkingOutputs>m:\working\outputs</WorkingOutputs>
</PropertyGroup>
<Target Name="AllTargetsWrapper">
<CallTarget Targets="Clean" />
<CallTarget Targets="Build" />
<CallTarget Targets="CopyItUp" />
</Target>
<Target Name="Clean">
<RemoveDir Directories="$(WorkingOutputs)" />
<MakeDir Directories="$(WorkingOutputs)" />
<Message Text="Cleaning done" />
</Target>
<Target Name="Build">
<MSBuild Projects="$(WorkingCheckout)\MySolution.sln" Targets="Build" Properties="Configuration=$(Configuration)">
<Output TaskParameter="TargetOutputs" ItemName="TargetOutputsItemName"/>
</MSBuild>
<Message Text="Build completed" />
</Target>
<!-- -->
<Target Name="CopyItUp" >
<ItemGroup>
<MyExcludeFiles Include="$(WorkingCheckout)\**\SuperSecretStuff.txt" />
<MyExcludeFiles Include="$(WorkingCheckout)\**\SuperSecretStuff.doc" />
</ItemGroup>
<ItemGroup>
<MyIncludeFiles Include="$(WorkingCheckout)\MyCsProject\bin\$(Configuration)\**\*.*" Exclude="#(MyExcludeFiles)"/>
</ItemGroup>
<Copy
SourceFiles="#(MyIncludeFiles)"
DestinationFiles="#(MyIncludeFiles->'$(WorkingOutputs)\%(RecursiveDir)%(Filename)%(Extension)')"
/>
</Target>
</Project>

Related

How to publish file from subfolder to main application folder?

I have a WinForms NET4.8 desktop app that I publish using ClickOnce. I have a dll file in a project subfolder that I need published to the same directory as the main app. I have the following in my csproj file:
<PropertyGroup>
<UnreferencedDlls>lib\twaindsm.dll</UnreferencedDlls>
</PropertyGroup>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="AfterBuild">
<Message Text="Copying unreferenced DLLs to bin" Importance="High" />
<CreateItem Include="$(UnreferencedDlls)">
<Output TaskParameter="Include" ItemName="_UnReferencedDLLs" />
</CreateItem>
<Copy SourceFiles="#(_UnReferencedDLLs)" DestinationFolder="$(OutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>
<Target Name="CustomCollectFiles">
<Message Text="Publishing unreferenced DLLs" Importance="High" />
<ItemGroup>
<_CustomFiles Include="$(UnreferencedDlls)" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>$(OutputPath)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
The file is published to the subfolder.
I change this line:
<DestinationRelativePath>$(OutputPath)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
to:
<DestinationRelativePath>$(OutputPath)\%(Filename)%(Extension)</DestinationRelativePath>
But it still doesn't work.
How can I force the file to be published to the same folder as the app?
I don't know if it can help you: %(RecursiveDir)
If the Include attribute contains the wildcard **, this metadata
specifies the part of the path that replaces the wildcard.
Maybe you can try to change the path of the dll. I put it into ProjectDir\lib\Debug\ and here is my code:
<PropertyGroup>
<UnreferencedDlls>lib\**\ClassLibrary1.dll</UnreferencedDlls>
</PropertyGroup>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="AfterBuild">
<Message Text="Copying unreferenced DLLs to bin" Importance="High" />
<CreateItem Include="$(UnreferencedDlls)">
<Output TaskParameter="Include" ItemName="_UnReferencedDLLs" />
</CreateItem>
<Copy SourceFiles="#(_UnReferencedDLLs)" DestinationFolder="bin\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>
<Target Name="CustomCollectFiles">
<Message Text="Publishing unreferenced DLLs" Importance="High" />
<ItemGroup>
<_CustomFiles Include="$(UnreferencedDlls)" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
You can also refer to this page hope it can help you.

Minimal Visual Studio project with custom target only: Disable IntelliSense and allow single file processing?

For our Visual Studio Solution, I want to create one project that just generates some files with custom scripts. I have a somewhat-working solution, further reduced to provide as an example here:
This is my minimal.vcxproj:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Universal|Win32">
<Configuration>Universal</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<None Include="common.fooconf" />
</ItemGroup>
<ItemGroup>
<Foo Include="file1.foo" />
<Foo Include="file2.foo" />
</ItemGroup>
<Target Name="Build" Inputs="common.fooconf;#(Foo)" Outputs="Output\%(Foo.Filename).bar">
<MakeDir Directories="Output" />
<Exec Command='TYPE "common.fooconf" "%(Foo.FullPath)" > "Output\%(Foo.Filename).bar"' />
</Target>
<Target Name="Clean">
<RemoveDir Directories="Output" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
</Project>
And I need this minimal.vcxproj.filters to make the three contained files show up in VS's solution explorer:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="common.fooconf"/>
</ItemGroup>
<ItemGroup>
<Foo Include="file1.foo"/>
<Foo Include="file2.foo"/>
</ItemGroup>
</Project>
Now there are still two problems:
When loading the project, I get error : Designtime build failed for project '[...]\minimal.vcxproj' configuration 'Universal|Win32'. IntelliSense might be unavailable. Check *.designtime.log files in your %TEMP% directory. If I look up in the log, the error is error MSB4057: The target "GetClCommandLines" does not exist in the project. Of course IntelliSense doesn't make sense here (TYPE is just a placeholder for a custom script), but there must be a way of getting rid of this warning.
Build (e.g. via F7) works like a charm (even incremental), but it would be really important for us to trigger processing single files (e.g. CtrlF7). But I can't find out how to make this work.
Using Visual Studio 2019, I needed to add the following targets to have the project load without warnings. This was done by checking the designtime logs and incrementally adding targets, until there were no more warnings.
<Target Name="GetProjectDirectories" />
<Target Name="GetClCommandLines" />
<Target Name="GetGeneratedFiles" />
<Target Name="GetAssemblyReferences" />
<Target Name="GetWinMDReferences" />
<Target Name="GetComReferences" />
<Target Name="GetSDKReferences" />
<Target Name="GetProjectReferences" />
<Target Name="GetForeignReferences" />
<Target Name="GetResolvedReferences" />
<Target Name="GetResolvedSDKReferences" />
<Target Name="GetProjectReferencesInfo" />
<Target Name="GetResolvedLinkLibs" />

Get static content to copy to TFS Build Drop location

I'm using TFS 2013 / VS 2013.
For various reasons, I need some static content copied to a TFS build drop location. I've created a custom project type that simply copies a directory structure/files to an output path.
I would expect that TFS would then take everything in the output path and copy it to the drop location, but it's not. No files from my project show up in the drop location.
Here is my proj file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputPath>db\</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Target Name="Build">
<Copy SourceFiles="#(Content)" DestinationFiles="#(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Exec Command="rd /s /q $(OutputPath)" Condition="Exists($(OutputPath))" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<ItemGroup>
<Content Include="**\*.*" Exclude="db\**\*.*;*.csproj;*.rgdbproj;*.vspscc" />
</ItemGroup>
</Project>
When I build this in Visual Studio, I get the desired directory structure to appear in the /db folder.
In TFS 2013 you can specify a pre-build and post-build script. You can run PowerShell scripts to copy the files. See below question on how to do it. You will have to use TfvcTemplate.12.xaml for that.
Where can we open the `Post-build script` box of a build process template?
I was able to resolve this issue by changing all my references from OutputPath to OutDir. Apparently, OutputPath is deprecated and OutDir is what TFS Build pays attention to. Here is my final build script:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputPath>db\</OutputPath>
<OutDir>db\</OutDir>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Target Name="Build">
<Copy SourceFiles="#(Content)" DestinationFiles="#(Content->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Exec Command="rd /s /q $(OutDir)" Condition="Exists($(OutDir))" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<ItemGroup>
<Content Include="**\*.*" Exclude="db\**\*.*;*.csproj;*.rgdbproj;*.vspscc" />
</ItemGroup>
</Project>
In your build file, you can define a target for copying files:
<Target Name="CopySomeFiles">
<ItemGroup>
<SomeFiles Include="$(SourceFolder)\*.*"></SomeFiles>
</ItemGroup>
<Copy SourceFiles="#(SomeFiles)" DestinationFolder="$(DestFolder)" SkipUnchangedFiles="false"/>
</Target>
You can then add this target where you want, e.g. after compile:
<Target Name="AfterCompile"
DependsOnTargets="CopySomeFiles">
</Target>

Why doesn't my MSBuild project build incrementally?

I have a project which generates a class from its XSD definition, then builds it. My problem is that, even though I specify the inputs and outputs of my Xsd target, it still gets executed every time I build the Visual Studio solution. What could be the problem here?
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" InitialTargets="Xsd" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- snip -->
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="request.cs">
<DependentUpon>request.xsd</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="key.snk" />
</ItemGroup>
<ItemGroup>
<Xsd Include="request.xsd" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="Xsd" Inputs="#(Xsd)" Outputs="request.cs">
<Exec Command='"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\xsd.exe" "#(Xsd)" /c /o:..\.. /n:Order.Messaging' />
</Target>
</Project>
Remove Xsd target from InitialTargets
Initial targets are typically used for error checking.
and add dependency to BeforeBuild Target:
<Target Name="BeforeBuild" DependsOnTargets="Xsd" />

TeamCity MSBuild 4.0 Help

I need some help with my MSBuild file i created a while ago.
All i want to do is build the solution, publish a project inside the solution and than copy the files to a directory
At the moment when i set Teamcity to .net 4 msbuild, msbuild 4.0 tools and for 86 i get an error stating
error MSB4067: The element <ItemDefinitionGroup> beneath element <Project> is unrecognized.
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Run">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets"/>
<PropertyGroup>
<OutputFolder>$(OutputDir)</OutputFolder>
<DeploymentFolder>$(DeploymentDir)</DeploymentFolder>
<CompilationDebug />
<CustomErrorsMode />
<ContentEditorsEmail />
<AdministratorsEmail />
</PropertyGroup>
<Target Name="Run">
<CallTarget Targets="Compile" />
<CallTarget Targets="Publish" />
<CallTarget Targets="Deploy" />
</Target>
<Target Name="Clean">
<ItemGroup>
<BinFiles Include="bin\*.*" />
</ItemGroup>
<Delete Files="#(BinFiles)" />
</Target>
<Target Name="Compile" DependsOnTargets="Clean">
<MSBuild Projects="WebCanvas.ZakisCatering.Website.sln"
Properties="Configuration=Release"/>
</Target>
<Target Name="Publish">
<RemoveDir Directories="$(OutputFolder)" ContinueOnError="true" />
<MSBuild Projects="WebCanvas.ZakisCatering.Website\WebCanvas.ZakisCatering.Website.csproj"
Targets="ResolveReferences;_CopyWebApplication"
Properties="Configuration=Release;WebProjectOutputDir=$(OutputFolder);OutDir=$(WebProjectOutputDir)\" />
</Target>
<Target Name="Deploy">
<RemoveDir Directories="$(DeploymentFolder)"
ContinueOnError="true" />
<ItemGroup>
<DeploymentFiles Include="$(OutputFolder)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(DeploymentFiles)"
DestinationFolder="$(DeploymentFolder)\%(RecursiveDir)" />
</Target>
</Project>
I'm getting that error code too, although complaining about a different element:
error MSB4067: The element <ArtifactAssemblies> beneath element <ItemGroup> is unrecognized.
I did notice that Teamcity is invoking the 2.0 version of MSBuild, which could explain why msbuild is struggling with the xml.
'C:\Windows\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe'
'#"D:\BuildAgent\work\2f016459feee51ce\Build\BuildSolution.msbuild.teamcity.msbuild.tcargs"
"D:\BuildAgent\work\2f016459feee51ce\Build\BuildSolution.msbuild.teamcity.patch.tcprojx"'
working dir =
'D:\BuildAgent\work\2f016459feee51ce'
Microsoft (R) Build Engine Version
2.0.50727.4016 [Microsoft .NET Framework, Version 2.0.50727.4200]
I fixed the 2.0 msbuild problem by adding to the .\conf\buildagent.properties file on the team city build agent machine, the following:
env.MSBuild=%system.DotNetFramework4.0_x86_Path%
Restart the service after that and problem solved.
Unfortunately, they don't package the WebApplications targets.
I can't find an SDK that has these targets packaged without having VS installed...no way.
I don't understand why MS makes CI so difficult.

Resources