Visual Studio Express 2012 for Web - don't generate bin and obj folders - visual-studio

Can I turn off generating these folders on build? They contain some .dll, .pdb and other files I don't need. I'm just using Typescript compilation.

Yes, it is possible. I relied on the following nice overview on how to hijack a build process:
http://sedodream.com/2013/06/01/HijackingTheVisualStudioBuildProcess.aspx
Three main tricks:
1) project_name.csproj is the one you need to modify, it is XML MSBUILD file.
2) You cannot remove dependency from WebApplication.targets, you need to "deactivate" them as below.
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
3) You have to implement general contract for clean/build/rebuild targets.
Mine looks like:
<Target Name="Build">
<Exec Command="call node_modules\.bin\tsc.cmd src/main.ts --out js/game.min.js > $(Temp)\tscout.txt" IgnoreExitCode="true" WorkingDirectory="$(SolutionDir)" />
<Exec Command="type $(Temp)\tscout.txt" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build">
</Target>
<Target Name="Clean">
<RemoveDir Directories="js">
</RemoveDir>
</Target>

You could create a New WebSite instead of New Project. That one should not create any binary output.

Related

How to copy and rename file to output folder as part of build

I believe this is more of an msbuild-related question.
Have a .net core app and I need to conditionally publish a file and based on the build config selected in Visual Studio 2019, the file should be renamed before publishing to the target.
So Im looking at modifying the csproj file (which is nothing but an msbuild file itself)
I dont see a condition option on the copy task
https://learn.microsoft.com/en-us/visualstudio/msbuild/copy-task?view=vs-2019
The goal Im after, is if I have 3 different files
tester-notes.dev.json
tester-notes.debug.json
tester-notes.prod.json
If prod is selected as a build config, I want the file published to be tester-notes.prod.json, but renamed to tester-notes.json
Assuming you have three files(build action = None) in Solution Explorer when developing:
You can use something similar to this script to rename and copy to publish folder if you're using FileSystem publish mode:
<ItemGroup Condition="$(Configuration)=='Dev'">
<FileToRename Include="$(ProjectDir)\tester-notes.dev.json" />
</ItemGroup>
<ItemGroup Condition="$(Configuration)=='Debug'">
<FileToRename Include="$(ProjectDir)\tester-notes.debug.json" />
</ItemGroup>
<ItemGroup Condition="$(Configuration)=='Prof'">
<FileToRename Include="$(ProjectDir)\tester-notes.prof.json" />
</ItemGroup>
<Target Name="DoSthAfterPublish1" AfterTargets="Publish" Condition="$(Configuration)=='Dev'">
<Copy SourceFiles="#(FileToRename)" DestinationFiles="#(FileToRename->Replace('.dev.json','.json'))"/>
<Move SourceFiles="$(ProjectDir)\tester-notes.json" DestinationFolder="$(PublishDir)" OverwriteReadOnlyFiles="true"/>
</Target>
<Target Name="DoSthAfterPublish2" AfterTargets="Publish" Condition="$(Configuration)=='Debug'">
<Copy SourceFiles="#(FileToRename)" DestinationFiles="#(FileToRename->Replace('.debug.json','.json'))"/>
<Move SourceFiles="$(ProjectDir)\tester-notes.json" DestinationFolder="$(PublishDir)" OverwriteReadOnlyFiles="true"/>
</Target>
<Target Name="DoSthAfterPublish3" AfterTargets="Publish" Condition="$(Configuration)=='Prof'">
<Copy SourceFiles="#(FileToRename)" DestinationFiles="#(FileToRename->Replace('.prof.json','.json'))"/>
<Move SourceFiles="$(ProjectDir)\tester-notes.json" DestinationFolder="$(PublishDir)" OverwriteReadOnlyFiles="true"/>
</Target>
And if you can reset tester-notes.debug.json to tester-notes.Debug.json,, then we may combine the three targets into one by using DestinationFiles="#(FileToRename->Replace('.$(Configuration).json','.json'))". Hope it makes some help :)
In addition:
According to the Intellisense we can find the Copy task supports Condition:

msbuild not working properly with tfs 2010 and importet Microsoft.TeamFoundation.Build.targets

i'm stuck with extending my msbuild project file and tfs 2010. What i want to achieve is to automatically generate the documentation for my source code after the build. I searched the web and found out, that the file Microsoft.TeamFoundation.Build.targets defines a lot of customizable targets for either desktop- or team-build. One of them is the GenerateDocumentation-Target which i want to use. The Problem i have is, that despite i imported this file, the overloaded targets are not invoked by msbuild. The header of my vcxproj-File looks as follows:
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
after this i include the team build targets file with the statement
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets"/>
At the very end of this project file i tried to overload some targets as suggested in the TeamFoundation target file:
<Target Name="GenerateDocumentation">
<Message Text="GenerateDocumentation invoked" Importance="high"/>
</Target>
<Target Name="BeforeBuild">
<Message Text="BeforeBuild invoked" Importance="high" />
</Target>
<Target Name="AfterBuild">
<Message Text="AfterBuild invoked" Importance="high" />
</Target>
but except the AfterBuild-Target neither the GenerateDocumentation nor BeforeBuild target is called for a local build nor a build with the build server. Am i'm missing something? Is the DefaultTarget="Build" correct? I tried to change this to DefaultTarget="DesktopBuild" but then calling msbuild resulted in a variety of errors (MSB4018). In the project file the target file $(VCTargetsPath)\Microsoft.Cpp.targets is imported too. When removing this import, the GenerateDocumentation target is called, but not the other ones (including ResourceCompile which i need too). Can i use both of them somehow?
Thanks in advance...
what about adding this at the end of your build task...
<CallTarget Targets="GenerateDocumentation"></CallTarget>
</Target>

Copy DLL files to bin directory after one-click publishing in VS2010

I have a web application in VS2010 which has a number of DLLs that need to be copied into the bin directory after doing a publish in VS2010.
I've tried putting the following into my .csproj file (which sits in the root folder of the web applications) but it doesn't seem to work:
<Target Name="AfterBuild">
<ItemGroup>
<_CircularDependencies Include="DLLs\Circular\Dependencies\*.dll" />
</ItemGroup>
<Copy
SourceFiles="#(_CircularDependencies)"
DestinationFiles="#(_CircularDependencies->'bin\%(Filename)%(Extension)')"
SkipUnchangedFiles="true" />
</Target>
For bonus points, I have another set of DLLs copied to be copied post-publish, but I want to use one set when doing a debug publish (for Win32) and a different set when doing a release publish (x86).
Thanks!
OK, I've managed to get this working fully. Thanks to the answers provided above, I've been able to add some MS Build commands to the .csproj file to copy the appropriate DLLs from various folders into the bin folder based on the current build configuration. However as these are unmanaged DLLs (i.e. not .NET) I can't create normal references to them and they fail to be copied during the publish. I got around this by dynamically adding the files to the project as 'content'.
The solution came in three parts. Firstly, create an item group for the files near the top of the .csproj file (I've tried to use generic filenames here to make it clearer), with conditions based on the current build configuration:
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<_UnmanagedDLLs Include="Win32DLLs\*.dll" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<_UnmanagedDLLs Include="x64DLLs\*.dll" />
</ItemGroup>
Then add another item group to include these DLLs (as content, not references) in the build:
<ItemGroup>
<Content Include="#(_UnmanagedDLLs->'bin\%(Filename)%(Extension)')" />
</ItemGroup>
Finally, at the bottom of the .csproj file, I do the copy on the AfterBuild target:
<Target Name="AfterBuild">
<Copy SourceFiles="#(_UnmanagedDLLs)" DestinationFiles="#(_UnmanagedDLLs->'bin\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
It means I can do a debug publish for my windows 32 staging box and a release publish for my x64 production box while keeping my bin folder out of SVN.
Once you get the copy working, separate sets for debug/release is easy with a condition:
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<_CircularDependencies Include="DLLs\Circular\Dependencies\*.dll" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<_CircularDependencies Include="DebugDLLs\Circular\Dependencies\*.dll" />
<_CircularDependencies Include="DebugDLLs\Circular\Dependencies\*.pdb" />
</ItemGroup>
If you want your copy to happen after publish, not after build you need to change your target from:
<Target Name="AfterBuild">
to
<Target Name="AfterPublish">

How to turn off caching of build definitions in Visual studio

In project file I import my own target file
<Import Project="Build\CopyDependencies.target" />
and later I call target from that target file
<CallTarget Targets="CopyDependencies" UseResultsCache="false" />
If I edit CopyDependencies.target file I have to reload whole solution and only then changes to CopyDependencies.target take effect. I believe it is some sort of build definitions caching in Visual Studio? If it is, maybe it can be turned off?
Thanks #KazR
Here is a smaller Solution that you can insert into your .csproj file
<Target Name="AfterBuild">
<PropertyGroup>
<TempProjectFile>Build.$([System.Guid]::NewGuid()).proj</TempProjectFile>
</PropertyGroup>
<Copy SourceFiles="Build.proj" DestinationFiles="$(TempProjectFile)" />
<MSBuild Projects="$(TempProjectFile)" />
<ItemGroup>
<TempProjectFiles Include="Build.????????-????-????-????-????????????.proj"/>
</ItemGroup>
<Delete Files="#(TempProjectFiles)" />
</Target>
Problem solved
I don't know how you would disable the VS cache, however I may have a workaround that would allow you to edit the build target without having to reload the solution.
You could use the MSBuild task in your proj file to call a wrapper target that copies your CopyDependencies.target file to CopyDependencies.[RandomNumber].target, then invokes your CopyDependencies target in the newly created file, and finally deletes it.
This would force VS to reload the target on each invocation as the filename is different.
Here's an example:
myProject.proj
Add this to the AfterBuild target:
<MSBuild Projects="Wrapper.target" Targets="MyWrappedTarget" UnloadProjectsOnCompletion="true"/>
Wrapper.target
Here we have the target that will - at build time - copy the real target file and invoke the desired build target within it (I've used an inline c# task which is only available in MSBuild 4.0):
<UsingTask TaskName="RandomNumber" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Number ParameterType="System.Int32" Output="true"/>
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<!-- CDATA -->
Random rndGenerator = new Random();
Number = rndGenerator.Next(Int32.MaxValue);
<!-- CDATA -->
</Code>
</Task>
</UsingTask>
<Target Name="MyWrappedTarget">
<Message Text="MyWrappedTarget target called"/>
<RandomNumber>
<Output TaskParameter="Number" PropertyName="FileNumber"/>
</RandomNumber>
<PropertyGroup>
<CopiedTarget>inner.test.$(FileNumber).target</CopiedTarget>
</PropertyGroup>
<Copy SourceFiles="inner.test.target" DestinationFiles="$(CopiedTarget)"/>
<MSBuild Projects="$(CopiedTarget)" Targets="_innerTestTarget"/>
<Delete Files="$(CopiedTarget)"/>
</Target>
inner.test.target
This contains the real build target you want to execute, in this example it's a simple file copy.
<Target Name="_innerTestTarget">
<Message Text="This is a inner test text message"/>
<Copy SourceFiles="x.txt" DestinationFiles="x1.txt"/>
</Target>
This isn't production ready, but hopefully illustrates my point.
With this (slightly convoluted) process in place, you can change the inner.test.target file without having to reload the solution in VS.
Here's a solution that doesn't require any MSBuild scripting at all.
I noticed that unloading and reloading a project doesn't get around the cache, but closing and reopening the solution does. In addition, Visual Studio will prompt you to reload the solution if it notices the .sln file has changed. And finally, this superuser question explains how to touch a file in Windows.
Putting these together, I added a Visual Studio external tool to touch the current solution file. Here's how:
Select TOOLS > External Tools ...
Click the Add button to add a new tool.
Set properties as follows:
Title: Reload Solution
Command: cmd.exe
Arguments: /c copy "$(SolutionFileName)"+>nul
Initial directory: $(SolutionDir)
and turn on Use Output window
Click OK to close the External Tools window
Now if you have made changes to your MSBuild files, just select TOOLS > Reload Solution and all your build files will be reloaded.
I'm using Windows 7 64-bit and Visual Studio 2012 Express for Windows Desktop.
I have a different solution, not involving temporary files:
Include.targets file:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Foobar">
<Copy SourceFiles="test.source" DestinationFiles="testFoobar.dest" />
</Target>
</Project>
Project file:
....
<Target Name="BeforeBuild">
<Exec Command="$(MSBuildToolsPath)\MSBuild.exe Include.targets /t:Foobar" ContinueOnError="false" />
</Target>
....
in this case VS does not recognize the MSBuild command, and does not cache the file.
happy coding!
Before running MSBuild I run this to clear the download cache:
call "%VS120COMNTOOLS%vsvars32.bat"
echo Clear download cache
gacutil -cdl

msbuild custom task

I have a custom MSBuild task that takes in a set of JavaScript files, minifies them, and outputs them, with the extension .min.js. When I do a normal build through Visual Studio, it works perfectly and the .min.js files are output to the same directory as the original files. When I try to deploy using the Publish feature in Visual Studio, only the original .js files make it to the publish directory.... How can I get the output of my task to be counted as "content" so that it will end up in the published folder?
EDIT:
I was able to figure it out by adding the Output tag inside my task and then creating an ItemGroup around that:
<Target Name="AfterBuild">
<ItemGroup>
<JavaScriptFiles Include="Scripts\*.js" Exclude="Scripts\*.min.js" />
</ItemGroup>
<JsCompress Files="#(JavaScriptFiles)" OutputPath="Scripts">
<Output TaskParameter="CompressedFiles" ItemName="CompressedFiles" />
</JsCompress>
<ItemGroup>
<Content Include="#(CompressedFiles)" />
</ItemGroup>
</Target>
Build and Publish are separate targets. Add a target to your project, abstract your minification to its own target, then make the AfterBuild and Publish target depend on the minification target. Something like this:
<Target Name="AfterBuild" DependsOnTargets="Build;Minify">
</Target>
<Target Name="Publish" DependsOnTargets="Build;Minify">
</Target>
<Target Name="Minify" DependsOnTargets="Build">
<ItemGroup>
<JavaScriptFiles Include="Scripts\*.js" Exclude="Scripts\*.min.js" />
</ItemGroup>
<JsCompress Files="#(JavaScriptFiles)" OutputPath="Scripts">
<Output TaskParameter="CompressedFiles" ItemName="CompressedFiles" />
</JsCompress>
<ItemGroup>
<Content Include="#(CompressedFiles)" />
</ItemGroup>
</Target>
This snippet, of course, means you have to have a build target, which may or not be the case. For that reason you may need to modify this. Hope this helps!
Change the file properties. Check the Build Action and Copy to Output Directory properties for those files.

Resources