VS2017 delete NuGet files in post build event - nuget

What is the order of execution of project post build events related to a NuGet package copying its files? I have a NuGet package that copies unnecessary files to my output directory (there are both DLLs and EXEs, in my case I don't need the latter). The usual idea of
del /f /q "$(TargetDir)directory\*.exe"
doesn't work, very probably it's called before VS (MSBuild) actually copies those files.

very probably it's called before VS (MSBuild) actually copies those files.
According to the info in the comment:
the <Target Name="CopyNativeBinaries" AfterTargets="Build">, this is
from the package targets file.
This import MSBuild target would executed copy task after build completed, which cause delete command line in the post-build to fail. That is the reason why CopyNativeBinaries target comes four steps after PostBuildEvent.
To resolve this issue, we could convert the post-build event command line to the target with the order after target CopyNativeBinaries:
Detail Steps:
Remove the post-build event.
Unload your project. Then at the very end of the project, just before the end-tag, place below scripts:
<Target Name="DeleteFile" AfterTargets="CopyNativeBinaries">
<ItemGroup>
<FileToDelete Include="$(TargetDir)directory\*.exe"/>
</ItemGroup>
<Exec Command="del /F /Q "#(FileToDelete)""/>
</Target>
After this setting, the DeleteFile will executed after the target CopyNativeBinaries.

This works for me (MSBUILD v15)
<Target Name="BeforeClean">
<Exec Command="del /F /Q $(TargetDir)*.exe"/>
<Exec Command="del /F /Q $(TargetDir)*.example"/>
</Target>

Related

Copy files to bin folder with .nuspec files

I have .nuspec file to create my package which contains nothing but a folder with text and other format files. I pack the folder like this:
<files>
<file src="myData\**\*.*" target="content" copyToOutput="true" />
</files>
When I install the nuget package I want this folder to be in my bin folder/output folder so that my program can relatively reference the files present. How can I achieve this since my nuget package doesn't have any .csproj to have .target file to copy files?
This isn't the exact answer to your question, but I am not sure if you can achieve this without a .target file. As a workaround, you can create an empty .csproj with a .target file which shall copy the items of your content folder:
<Project>
<Target Name="CopyToDeployFolder" AfterTargets="Build">
<Exec Command="xcopy.exe $(MSBuildThisFileDirectory)\..\content $(OutputPath) /e /y /i /r" />
</Target>
<Target Name="CopyToPublishFolder" AfterTargets="Publish">
<Exec Command="xcopy.exe $(MSBuildThisFileDirectory)\..\content $(PublishDir) /e /y /i /r" />
</Target>
</Project>

NAnt: How to Load External NAnt Scripts Inside A Custom Task

In short, my problem is:
How to load an NAnt script in side a custom task, and execute it?
Detailed explanation:
In our current project build, we need to execute external programs. The external programs need to be located before the build kicks off. (coz it takes so looong time)
What I want is to have some NAnt module, like those FindXXX.cmake modules in CMake, so I can have modules like:
<?xml version="1.0"?>
<project name="FindSQLServerCore" default="FindSQLServer">
<target name="FindSQLServer">
<module>
<path>
<pathelement dir="C:\Program Files\Microsoft SQL Server\100\Tools\Binn" />
<pathelement dir="C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn" />
</path>
<files>
<file name="SQLCmd.exe" />
</files>
</module>
</target>
</project>
And when I need to include SQLServer in my build script, I can do:
<find module="SQLServer" required="true" />
My way to do it is by create 2 custom tasks: FindTask & ModuleTask.
FindTask is going to locate the FindXXX.include and loaded it into current NAnt project.
ModuleTask is going to find specified file under given path and return results.
But I cannot find ways to create & execute NAnt tasks by loading a build script in FindTask. The Project.CreateTask(XmlNode) only accepts node that is already loaded but not from newly loaded XML.
Is there a way to create task by loading a build script inside a custom task?
Or is my way doing this the NAnt style? Any better ways to achieve same goal?
PS. You might ask why not just use
<include file="FindSQLServer.include" />
The reason I'm not doing it this way is I want to pass the required parameter in, but not set it as a variable and pass it in.
You can get the NANT extension here:NAntFind#github
One way to load an NAnt script and execute it inside a custom task is to create a new project, and load the script using the project, then execute. Example:
var findProject = new Project(nantModule, Level.Info, Project.IndentationLevel);
findProject.Execute();
If the project fails, an exception should be thrown out.

Building Windows 8 Phone App on Command Line

I'm currently porting an existing cross platform framework to Windows Phone 8.
The build process is fully automated and we are using a rock solid CI system.
I can build and deploy Windows Phone 8 samples from Visual Studio (Express 2012),
but now I need to integrate that into our build scripts.
Did anybody ever successfully build (and deploy) a Win Phone 8 app via the commandline?
(Or ant, make, scons, whatever...)
If yes, how?
Any hints are welcome.
I used the following bat file to build WP7 code (+ant automation on top of it). It may be helpful for you.
build.bat
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe build.xml /t:BuildAndCopy /p:Revision=123
where build.xml is something like (build itself goes under BuildAll target)
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="C:\Program Files (x86)\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<Major>1</Major>
<Minor>0</Minor>
<Build>0</Build>
<Revision>x</Revision>
<OutputPath>Build\</OutputPath>
<OutputPathDebug>..\Build\Debug\</OutputPathDebug>
<OutputPathRelease>..\Build\</OutputPathRelease>
</PropertyGroup>
<Target Name="BuildAll" DependsOnTargets="Clean; Version">
<msbuild Projects="SomeApp.sln" Properties="Configuration=Release;OutputPath=$(OutputPathRelease)"/>
<msbuild Projects="SomeApp.sln" Properties="Configuration=Debug;OutputPath=$(OutputPathDebug)"/>
</Target>
<Target Name="Clean">
<RemoveDir Directories="$(OutputPath)" Condition="Exists('$(OutputPath)')"/>
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')"/>
</Target>
<Target Name="Version">
<Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)"/>
<XmlUpdate
Namespace=""
XmlFileName="WindowsPhone\Properties\WMAppManifest.xml"
XPath="//App[#Version]//#Version"
Value="$(Major).$(Minor).$(Build).$(Revision)"/>
</Target>
<ItemGroup>
<AppFiles Include="$(OutputPath)\**\*.xap"/>
</ItemGroup>
<Target Name="BuildAndCopy" DependsOnTargets="BuildAll">
<Copy
SourceFiles="#(AppFiles)"
DestinationFiles="#(AppFiles->'\\fs\Public\projects\mobile\SomeAppWP\$(Major).$(Minor).$(Build).$(Revision)\%(RecursiveDir)%(Filename)%(Extension)')"
/>
<Copy
SourceFiles="#(AppFiles)"
DestinationFiles="#(AppFiles->'\\fs\Public\projects\mobile\SomeAppWP\latest\%(RecursiveDir)%(Filename)%(Extension)')"
/>
</Target>
</Project>
It should be easy. I'll assume you have the following file structure
$/WP8App/SampleApp.sln
You will have to use the paths and solution file in your project. Execute the following instructions, and make sure to update solution file and path:
Open a command prompt
Execute: %VS110COMNTOOLS%vsvars32.bat
Execute: %VS110COMNTOOLS%..\..\VC\WPSDK\WP80\vcvarsphoneall.bat
Execute: MSBuild "WP8App/SampleApp.sln" /t:rebuild
/p:Configuration=Release /p:Platform="Any CPU" /v:d
Please notice:
The computer where you're going to run these commands should have the development environment for WP8 already set up.
If your application uses native libraries (such as PlayerFramework http://playerframework.codeplex.com/ which are installed into VS, these libraries should also be installed before running the commands)
I have used this process on VS2012 Pro and VS2012 Premium and Jenkins as Build Server.
Good luck,
Herb
Thanks to Sergei's MSBuild.exe hint I was able to build a simple sample via the command line.
https://github.com/AndreasOM/wp8-directx-commandline
There is a build.bat included, which should be enough to get you started to build for "windows phone 8" with the build system of your choice.
It's fairly hacky at the moment,
but once I get the current project done
I will clean it up.
Hint:
Never define a "CL" environment variable when working with "CL.exe" ;)

Setting PATH environment variable on ant build.xml works on cygwin but not on cmd or PowerShell

I was trying to set PATH enviroment variable on an ant build.xml through this answer.
It works on cygwin but not on cmd or PowerShell.
Some information:
Apache Ant 1.6.5 (I know there is a newer version (1.8.4), but for internal reasons I have to use this older version)
Powershell v2.0
cmd v6.1.7601
cygwin 2.774
Windows 7
You may need to use the exec task a little differently on Windows/cmd environments.
Let's use the windows command set as an example. set will print environment variables. A normal exec task running a set command might look like:
<exec executable="set" outputproperty="set.output">
<env key="MY_VAR" value="MY_VAL"/>
<echo message="${set.output}"/>
</exec>
But using this form of the exec task should throw an IOException: The system cannont find the file specified.
When running ant under windows cmd shell, the exec task can also be invoked via cmd, like this:
<exec executable="cmd" outputproperty="set.output">
<arg line="/c set"/>
<env key="MY_VAR" value="MY_VAL"/>
<echo message="${set.output}"/>
</exec>
This is the equivalent command; the actual command executed is cmd /c set, which is running set in a cmd sub-process.
The reason why this is necessary is only a little complicated and is due to the way that the commands are located by Win32 ::CreateProcess. The ant exec docs briefly explain this.
Note that I haven't tried either of these using PowerShell, so I have no experience which, if either, will work.
In my own ant build scripts I typically have two versions of each target that require special handling for windows platforms, with an isWindows test that looks like this:
<target name="check-windows">
<condition property="isWindows">
<os family="windows"/>
</condition>
</target>
Then I can switch between versions of the same task using:
<target name="my-target-notwindows" depends="check-windows" unless="isWindows>
...
</target>
<target name="my-target-windows" depends="check-windows" if="isWindows>
...
</target>
<target name="my-target" depends="my-target-notwindows,my-target-windows">
...
</target>
Unfortunatelly was an ant bug related to 1.6.5 version. I was able to update to 1.8.4 and everything works fine.

Nant Build Error-- Nested build failed

I have a HelloNAnt.build file inside the directory:
D:\third party components\nant\WhatThis
My nant exe is placed at
C:\Program Files\nant
So I cd to D:\third party components\nant\WhatThis, type in the following command line:
"C:\Program Files\nant\bin\nant.exe" HelloNAnt.build
I got a build failed error, saying target HelloNAnt.build does not exist in this project.
What actually went wrong?
The content of HelloNAnt.build:
<?xml version="1.0"?>
<project name="Hello World" default="hello">
<target name="hello">
<echo>Hello</echo>
</target>
</project>
You omitted the -buildfile option, which specifies the path to the buildfile that you want NAnt to run:
"C:\Program Files\nant\bin\nant.exe" -buildfile:HelloNAnt.build
However, in your case, you needn't provide any options at all. NAnt will search the current directory for a file with a .build extension and run it.