Calling batch/script files from VC6/VC2005/VC2008 project files - visual-studio

Is there a way to invoke an external script or batch file from VC6 (and later) project files?
I have a background process that I need to kill before attempting to build certain projects (DLLS, executables) and haven't found a way to successfully do so from the project itself. I'd like simply to call a batch file with a taskkill command in it.
(Yes, I could run the batch file from a command line before building the projects, but I don't always remember to do so and having it done automatically would be more convenient and less irritating for the whole development team.)

You can create a utility project (configuration type: Utility in the project property pages) that has a post build event. You then call the batch file from that Post-Build event. If I remember correctly, utility configuration appeared in VS2005. But I believe the same can be achieved with another type of configuration on VC6.
Here is an example of a setup (this is the text of the Command Line property of the Post-Build Event):
set solutionDir=$(SolutionDir)
set platformName=$(PlatformName)
set configurationName=$(ConfigurationName)
call $(SolutionDir)PostBuild.bat
As you can see, you have all the flexibility of customizing the batch environment based on VisualStudio macros.
If you want to have this batch file called every time you build, add a dependency to the requiring project (your main executable or dll project for example). You can add your batch file to the solution items for convenient access (right-click on the solution and select Add -> Existing Item...).
You can even invoke the build command on this utility project to force the execution of the batch file.
At work we have a similar setup to start our unit tests each time a build is triggered.

You could invoke it from a custom build step or a build event.

At least for C# in Visual Studio 2008, you can open the project file and find within the file the following comment:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
Uncomment the one that works best for you, in this case the "BeforeBuild" item. Then substitute your batch file for the one I have here:
<Target Name="BeforeBuild">
<Exec Command="MyBatchFile.bat" />
</Target>
That's all there is to it; whenever you build that project, this will take place each and every time.
That said, I do not know if this works the same for VS 2005 or, especially, VC6. YMMV!

Related

Running SPIR-V compiler as pre-build event in VS2017 if only the shader code was modified

So I've look at a few questions here which popped up after a search, but I still haven't managed to get this to work.
My project has two files, main.cpp and shader.comp.
The shader needs to be compiled before the main program is ran and I have a small .bat script that does just that. It's set to run as a pre-build event.
However, if I edit shader.comp and leave main.cpp unmodified since I last ran the project, there is no need to rebuild the project (according to VS anyway), so there is no need to run any pre-build events and my shader doesn't get compiled.
Is there a way to tell VS2017 (or VS2019) that if some file is modified, then run something, or at least a way to add an arbitrary file to list of files that VS checks against when deciding whether to run the build or not?
I've tried setting "Exclude from build" to "No" in the file properties, but no matter what "Item type" I choose, editing just the shader won't trigger the rebuild.
It's possible to define the shader that needs to be compiled as Custom Build Tool in the properties of the file (as Item Type). This will open another menu in the properties where cmd script and similar can be written.
In this particular case, value for Command Line was:
glslangValidator.exe -V -o "%(RootDir)%(Directory)%(Filename).spv" "%(FullPath)"
And the Outputs:
%(RootDir)%(Directory)%(Filename).spv
In short, if file defined in Outputs doesn't exists or is older than the owner of this property (the file that needs to be compiled), the Command Line argument will be ran in cmd.
Official documentation has more info on this.
Maybe you can get some help from this issue. You can specify the files for VS Up-To-Date check.
<Project...>
...
<ItemGroup>
<UpToDateCheckInput Include="shader.comp" /> <!--when this file is in the project folder-->
<!--<UpToDateCheckInput Include="path/shader.comp" />-->
</ItemGroup>
</Project>
And this script into your project file. Then if there's any change to shader.comp file,VS will build your project.
Note: In this way, if you only change the shader.comp file , but not change the source file(xx,cpp), the build will start but vs will skip the compile target of C++ source code. Only when you modify the source code main.cpp, then VS will run the pre-build event and compile the code. Let me know if it's what you want, hope i didn't misunderstand anything :)

Running post deployment script after Web Deploy

I have the following problem and I'm surprised that I can't find any straightforward solution on SO or MSDN.
I have existing *.pubxml profiles in several of my web applications and I would like to execute post deployment script - powershell script - which reorganizes WebSite and its child applications slightly.
I'm not usign Web Deployment Package - just Web Deploy.
The script is deployed successfully but the problem is - how should I execute it automatically after deployment?
I have two scenarios:
Execute by simply "Publish..." from Visual Studio.
Execute as part of TFS Build definition (TFS 2013).
You can try to define a “Target” by MSBuild to achieve your requirement.
For the first scenario:
The Visual Studio build process is defined by a series of MSBuild .targets files that are imported into your project file. One of these imported files, Microsoft.Common.targets. This file contains a set of predefined empty targets that are called before and after some of the major targets in the build process.
So you can define a "Target" element whose "AfterTarget" attribute's value is set to "MSDeployPublish":
<Target Name="CustomPostPublishActions" AfterTargets="MSDeployPublish" >
<Exec Command="..\PostDeploymentScript.sp1 " />
</Target>
For the second scenario:
You can add a PowerShell build task as MrHinsh`s suggestion.
You should switch to deploying from Build & Release only in VSTS/TFS.
You can then add a PowerShell build task and either point at a script or use Inline if it's short. If it is a script that you use in many builds you might want to write your own build task.

Publish web application from MSBuild Script using VS2010 targets resets working directory

I am trying to automatically publish and deploy my .Net 4 web application automatically from a build script to be run by our continuous integration server. I am using the new _WPPCopyWebApplication target from VS2010 to perform the publish, however it appears to reset the current working directory of the msbuild project to c:\ this causes my prebuild steps to fail as they have relative paths to some external tools. The task I am running from our master.build file is as follows:
<Target Name="PublishWeb">
<MSBuild
Projects="$(ProjectPath)"
Targets="ResolveReferences;_WPPCopyWebApplication"
Properties="WebProjectOutputDir=$(DeployPath);OutDir=$(TempOutputFolder)$(WebOutputFolder)\;OutputPath=$(ProjectPath)\bin\Debug;" />
</Target>
This does not happen when using the legacy _CopyWebApplication. Does anyone have any idea how to resolve this problem?
Two possibilities come to mind:
Use the Exec task to call msbuild.exe, and supply a specific working directory.
Your pre-build steps are evaluated by MSBuild and can reference any MSBuild property, so make your paths relative to something specific, like $(MSBuildProjectDirectory), or $(MSBuildThisFileDirectory), instead of just relative to the current directory.

Project file with just files and no built output

How can I make a project file (VS 2008) that just has some data files in and has no built output?
I can make an empty project and add my data files to it (which get copied to the output folder
), but it produces an EmptyProject.dll after I do a build. I want just my data files in the output directory and not some empty DLL or EXE.
I want the data files to be the only thing in this project as the project will be shared in a couple of solutions.
Our application is C#. All of our normal code projects are C#.
The data files are schemas (XSD). I want these schemas to be in the output folder, but I don't want them included with an existing project. I would like a project named "Schemas" that has nothing in except the XSD files and does nothing except copy the XSD files to the output folder. I would like this in a project file so that the same schemas project can be referenced in multiple solutions.
I don't know of a way to suppress the creation of the .dll file. BUT... here's an easy workaround. In the project properties, Build Events tab, write a Post-build event command line that will delete the file. Something like:
del path\filename.dll
Expanding on Scott's answer:
Create a new project of type Empty project
In Properties->Application, change Output type to Class Library
In Properties->Build->Advanced, change Debug Info to None
In Properties->Build Events, set the Post-build event command line to del $(TargetPath)
That way, the project creates only a DLL, which gets deleted. At the same time, the "copy to output directory" settings on your data files is respected.
Possibly another way is editing the csproj file by replacing this:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
with this:
<Target Name="Build" />
<Target Name="Rebuild" />
Then builds don't create anything. It worked for me.
Same general idea should work for any xxproj file. Just replace the <Import Project...> tags with the <Target...> tags.
I'd be interested in knowing if this causes any issues or doesn't work for anyone.
What do you need a project for if you're not building it?
You can use solution folders to "store" files...
Why not just disable building this project for all configurations (use the Configuration Manager) - that way it won't build.
Great stuff. Expanding on Scott > Daniel's answer:
Safe to remove all References and Properties (AssemblyInfo.cs)
If it is a node/grunt/gulp project then you can invoke it in your Build Events > *Post-build event command line * eg: gulp build or gulp clean
Perhaps you can add removal or obj and bin output folders to your node/grunt/gulp clean scripts mitigating the need for del $(TargetPath)

Checking a file out (TFS) for a pre-build action

I've added a pre-build action for an ASP.NET web control (server control) project, that runs jsmin.exe on a set of Javascript files. These output files are part of the source control tree and are embedded into the assembly.
The problem is when the pre-build runs, jsmin can't write the file as it's readonly. Is it possible to check the file out before hand? Or am I forced to set the file's attributes in the command line.
Any improved solution to the problem is welcome.
Update
One small issue with Mehmet's answer -you need to prepend the VS directory:
"$(DevEnvDir)tf" checkout /lock:none "$(ProjectDir)myfile"
If you're using Team Foundation Server, you can use team foundation command line utility (tf.exe) to check out the file(s) during pre-build and then check them back in during post-build. If you're using something else for source control, you can check if they have a command line tool like tf.exe.
If you do not want to check the files in as part of the build (which you normally wouldn't for this sort of thing) then I would simply set the attributes of the .js files before running jsmin on them. The easiest way of setting the files read-writeable is to use the the Attrib task provided by the MSBuild community extensions. The same community extensions also provide a JSCompress task for easily calling JSMin from MSBuild.
Therefore you'd have something like the following (not tested):
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<!-- rest of TFSBuild.proj file -->
<Target Name="AfterGet">
<Message Text="Compressing Javascript files under "$(SolutionRoot)"." />
<CreateItem Include="$(SolutionRoot)\**\*.js">
<Output TaskParameter="Include" ItemName="JsFiles"/>
</CreateItem>
<Attrib Files="#(JsFiles)" ReadOnly="false"/>
<JSCompress Files="#(JsFiles)" />
</Target>
Note that by modifying the files after getting them may well cause issues if you tried to move to an incremental build.

Resources