Moving a file in MSBuild using relative path - msbuild

I'm trying to move all files of a certain type to a directory relative to the file itself and I'm wondering if it's possible using MSBuild.
Basically, I'm using the Microsoft AJAX Minifier to minify all Javascript and CSS files on my site. This outputs .min.js and .min.css files into the same directory as the Javascript and CSS files. Because my site has numerous skins, there are JS and CSS files located in numerous directories. I want to be able to add a task that runs after the AJAX Minifier that moves all .min.js and .min.css files to /min/ relative to the file location. So /Skin1/somescript.min.js would move to /Skin1/min/somescript.min.js and /Skin2/somescript.min.js would move to /Skin2/somescript.min.js.
The only way I know to accomplish a copy/move requires knowledge of the absolute directory (or should I say directory relative to the Project file) but I can't seem to find a way to move based on a directory relative to the file I'm moving.
Can this be done?

<CreateItem Include="wwwroot\**\*.min.js;wwwroot\**\*.min.css">
<Output TaskParameter="Include" ItemName="FilesToMove" />
</CreateItem>
<Move SourceFiles="#(FilesToMove)" DestinationFiles="#(FilesToMove->'wwwroot\%(RecursiveDir)\min\%(Filename)%(Extension)')"/>
Assuming you're using the Move task from MSBuild community tasks. If not, you could just copy and then delete the originals instead.

Related

Packaging a Repast model as a jar file without including the source code?

I want to create a model jar file but not include the source code. Is it possible? The Repast model installer includes the source code by default, but I would like to hide it from the recipient of the model.
Yes, it’s possible but there is an important caveat. Compiled Java code distributed as binary files like jars can be trivially de-compiled back into the original source code with remarkable accuracy. If your goal is to protect proprietary source code then code obfuscation is required – see https://www.excelsior-usa.com/articles/java-obfuscators.html for more details. Code obfuscation is unfortunately a fairly complicated subject.
There are two ways to omit the project source code from the Repast model installer:
Method 1 – Remove /src elements from the model installer configuration files. This will instruct the model installer to omit /src files in the installer jar. The compiled agent classes will be in the usual project /bin folder.
In the /installer/installation_compnents.xml file, around line 156 comment the following:
<!--
<pack name="Sources" required="no">
<description>The model source code</description>
<file src="$StagingOptionalArea/src" targetdir="$INSTALL_PATH/Geography"/>
</pack>
-->
The “” denote the start and end of the code block that is commented. Next, in the /installer/installation_coordinator.xml file, comment around line 62:
<!-- Copy optional files to a separate directory -->
<copy todir="${StagingOptionalArea}" overwrite="true" failonerror="false">
<fileset dir="." casesensitive="no">
<!-- <include name="**/src/**" /> -->
<include name="**/docs/**" />
</fileset>
</copy>
Here you only want to comment the single line that copies the /src folder and not the /docs folder (although you can if you like). Now just build the model installer as usual.
Method 2 – export the /src folder to a jar file. This method does not require any changes to the default installer files as in the first method. However it requires deleting the source code after exporting it to a JAR file which means you would need to work on a copy of the project to preserve your source code. To export the model code to a JAR file, right click on the /src folder and select Export… -> Java -> JAR file. In the export dialog, make sure the src folder is checked in the “Select resources to export” box and then specify the JAR file name and location. The best place to export the jar file in in the project /lib folder. Most other options should be left as default. Make sure that “Export Java source files and resources” is unchecked, otherwise it will copy the source into the jar file. After the JAR files is generated and you verify that it exists in the /lib folder, then delete the contents of the /src folder but not the /src folder itself. This will permanently delete the model source code, so again please work on a copy of the project if you take this route. Simply renaming or deleting the /src folder will cause the installer to fail, so the delete is required for this method. Last, the user_path.xml file in the .rs folder needs to be updated to reflect the change in the source code location. Change the line to assuming that the exported model JAR file is in the /lib folder. All of the model code is now in the single JAR file in your project/lib folder. The /src and /bin folder should be empty at this point. build the model installer as usual. The option to install source code will still appear in the installer, but no source is contained in the installer JAR so no source will be copied upon installation.

Visual Studio ASP.NET Web API Precompiled files placed in a different folder with TFS

I have an asp.net web api project whose output needs to be packaged in a setup project using wix.
I would like to precompile the site. The problem is that the precompilation process generates variable file names (ie. *.compiled files in particular).
I also would like to build the setup in a TFS build.
It seems that my only option is to generate a .wxs file wihtin the prebuild step of the wix project.
The .wxs files source paths are using $(var._My_Web_Project_.TargetDir). This seems to be translated to a Sources based directory.
I'm using paraffin to do that already and it works perfectly fine when building the solution with visual studio.
When building the solution through a TFS build, the .compiled files are copied to a Binaries folder, whereas all the other related web site files are copied to a Sources based directory.
The build errors are like the following :
The system cannot find the file 'd:\BuildAgents\___basedir___\Binaries\___web_project_dir\_PublishedWebSites\___site___\bin\textsample.cshtml.c6fb271c.compiled'.
The file is indeed in the Sources directory.
'd:\BuildAgents\___basedir___\Sources\___web_project_dir\_PublishedWebSites\___site___\bin\textsample.cshtml.c6fb271c.compiled'
I think I somehow need to redefine the aspnet_compiler output or something like this, but can't figure out how to do that.
The msbuild command line arguments are the follwing:
/p:GenerateProjectSpecificOutputFolder=true /p:VisualStudioVersion=14.0 /p:DeployOnBuild=true /p:PublishProfile=local /p:CleanWebProjectOutputDir=False /verbosity:d
EDIT 1: I'm using XAML build.
Any help appreciated.
EDIT 2:
With the new task based build, it works as is (no need to use an additional Copy Files task).
The aspnet_compiler output the .compiled files in the correct folder :
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p D:\BuildAgents\vNext\_work\1\s\Softs\__Solution__\__Web_Project\obj\Release\AspnetCompileMerge\Source -c D:\BuildAgents\vNext\_work\1\s\Softs\__Solution__\__Web_Project__\obj\Release\AspnetCompileMerge\TempBuildDir
In the new tasks based build system, it's easy to copy files from a source folder to a target folder with Copy Files task.
Source Folder: Folder that contains the files you want to copy.
Contents: Specify minimatch pattern filters (one on each line) that you want to apply to the list of files to be copied.
Target Folder: Folder where the files will be copied. In most cases you specify this folder using a variable.

How do I set up the MSBuild script to use the outdirectory's set in the csproj files while building the entire solution?

I'm not sure how I can get the MSBuild script to use the outputpath, outputdirectory values from the CSproj files. I've seen examples where I set the outputpath in the MSscript but that dumps the all the output in one big folder. I want the individual projects to have their own output paths and MSbuild to build the solution in such a way that the output for the projects and created in the corresponding output directories. Thanks.
There is not an easy way. One option is to extend MSBuild and have it copy the output from each project to a common folder.
If you look at the Microsoft.Common.Targets file in the c:\Windows\Microsoft.Net\Framework\v4.*\ you can see how it does load a custom targets file at both the beginning and end of that folder. If you add a Custom.After.Microsoft.Common.Targets to the C:\Program Files (x86)\MSBuild\v4\ folder you can have it load a file say $(SolutionDir)\Solution.targets. This will allow you to extend each solution differently and you can add any custom actions you want inside every solution that applies to every project. I use this and it works great.
Thanks for your answers guys. I found a way to run the solution without giving a specific output folder. I had to fix the output folder path to /bin in the csprojs and then running MSbuild with the solution was able to pick up those paths from the csprojs and build the output into those folders.

How to specify root folder for Package target?

I publish my web application using msbuild by calling following command:
msbuild myweb.csproj /T:Package /P:PackageLocation=obj\Output\myweb.zip
The content of zip file has always deep folder structure containing full path from drive root to the project folder. Is there any way how to make it more flat? I would like to have a project folder like root in zip.
You can use _PackageTempDir instead of PackageLocation for IIS-like flat structure, but if you want to keep the .zip and .cmd with manifests then no, you can't really get away from absolute paths without rewriting Microsoft.Web.Publishing.targets or a custom task due to the way the var is used.
<_PackageTempDir>$(PackageTempRootDir)\PackageTmp</_PackageTempDir>
<_PackageTempDirFullPath>$([System.IO.Path]::GetFullPath($(_PackageTempDir))</_PackageTempDirFullPath>
<_MSDeployDirPath Include="$(_PackageTempDir)" />
<_MSDeployDirPath_FullPath>#(_MSDeployDirPath->'%(FullPath)')</_MSDeployDirPath_FullPath>
You can however trick msbuild and flatten it a little bit by hiding the absolute path with a local share, something like this:
net share foo=D:\Temp
msbuild WebApplication1.csproj /t:Package /p:PackageTempRootDir=\\localhost\foo
That'll change your deep local path to something like obj\Debug\Package\WebApplication1.zip\Content\_S_Slocalhost_Sfoo\PackageTmp

how to harvest all files in one folder with wix

I have the following requirement: I wish to harvest all files in one folder to my install packet, but the files in that folder may increase or decrease, how can i do it automatically? and if i have two file sources, i wish file in source 2 auto-overwrite file in source 1 with same file name, how can i do this?
thanks!
You can't include several file from Wix directly, but you can use a tool named "heat" to do it for you. Be careful it is not recommended to use it automatically on build.
Link to the Doc.
I don't understand your second question.
Sure you can harvest all files in one folder even the number is not stable.
For example:
heat dir "src" -gg -sfrag -out src.wxs
This will harvest the sub folder "src" as a single fragment to the file src.wxs. You will then use candle and light to pack them into your msi.
If the number of files changes, just re-run heat and the src.wxs will be updated.