Passing parameters to msbuild from within Visual Studio - msbuild

As the title says: How can I pass parameters to the msbuild process(es) initiated by Visual Studio?
I need to modify the MSBUILDDEBUGPATH parameter as our solution has many post-build events making use of xcopy (which I don't like, but thats the way it is).
This results in the creation of many batch files in the folder C:\Users\MyUser\AppData\Local\Temp\tmp[guid].exec.cmd which execution gets prevented by our greate HIPS software resulting in killing all msbuild.exe processes.

Related

MSBuild creates BAT file, call it and delete it immediately, how can I see BAT content?

I'm diagnosing a Visual Studio project building problem, and I want to see what MSBuild.exe actually does. However, from Procmon, I see MSBuild creates BAT file, call it and delete it immediately, then how can I see that BAT's content?
For example, real BAT command is hidden inside tmpd60d571fd9d549e5b2b31bb1f2ba51a7.exec.cmd.
"C:\Windows\system32\cmd.exe" /Q /C C:\Users\win7evn\AppData\Local\Temp\tmpd60d571fd9d549e5b2b31bb1f2ba51a7.exec.cmd
MSBuild.exe writes cl.exe, link.exe, Prebuild/Postbuild custom commands etc into those temporary bat files. Specifically, I want to see how exactly MSBuild is calling my custom commands and how does he pass parameters to me from within a bat file.
The ideal way, I think, may be some tools that can intercept file deleting operation, and make a backup(copy) of that file, so we can investigate the "deleted" files later. Procmon only records ReadFile and WriteFile byte count, but not their byte content, so I think Procmon is not enough.
==== Update ====
According to stijn's answer(env-var MSBUILDPRESERVETOOLTEMPFILES=1), I tried it on VS2019 with success. The content in the xxx.exec.cmd is like this:
Two things to note:
We don't need to pass /verbosity:d parameter.
On VS2010, the MSBuild version may be too old, no effect.
Final comment: I think this feature of "seeing true .bat content" is critical, because, I may use many macros in my Custom-build/Prebuild/Postbuild commands, like $(ProjectDir), $(Configuration), or even my own defined macros of any name, so I need a global view of the macro expansion result, instead of checking each macro from VSIDE UI one by one(so many mouse clicking and time consuming) . The .bat content is the exact global view I need.
Msbuid creates .cmd files when it runs the Exec task, depending on what problem you are diagnosing it might be enough to just know what statements are added in those files, which can be found here: https://github.com/dotnet/msbuild/blob/main/src/Tasks/Exec.cs.
Otherwise set the MSBUILDPRESERVETOOLTEMPFILES environment variable to 1 so the files do not get deleted, then run with /v:D to see which files were created.

How to read VS 2015 publish output path

I'm running a batch file from Visual Studio during the AfterPublish event. I'm doing a file system publish, and having trouble with the second parameter as in:
<Exec Command="$(SolutionDir)\PostBuildEventPublish.bat "$(ProjectDir)" "$(ProjectDir)"" />
I really need the second parameter to point to the output path where I specified to publish to. The above line works now since I wanted to test if the batch file was working in the first place but now I need the batch file to work against where I'm publishing to.
Thanks much for any help
See this answer: How to pass command line parameters to a bath file?
If you are passing the parameters in the right way, then maybe there is a problem with your bath code.

Build only ChangeSet using MSBuild in Visual Studio Online

I have set up a Build Definition to build a solution on Visual Studio Online (VSO). It's working fine, but it builds all the code every time when I check in the code.
How can I build a particular changeset from the code?
How can I use/pass this number to the "MSBuild Arguments" to use it there for deployment?
You need to turn off the CI build feature(Uncheck "Continuous integration (CI)" option under "Triggers" tab in your build definition) if you don't want it to build all the code every time when you check in.
To build a particular changeset, you can enter the changeset number in "Source Version" textbox when you queue a new build. (In Git, it is "Commit" textbox)
To pass the version number to MSBuild Arguments, you can use the pre-defined variable "$(Build.SourceVersion)", it is filled with the source version number you specified when you queue the build.

How to use CustomAction in WIX Bundle?

To give you a background - I have a 4 MSI's which comes from our vendor and this has to go to our company servers (we are looking at around 3500 servers). As of now, my counterparts are managing this using vbs, ps1 scripts. But the problem with the script is that everytime an update comes we have to worry about uninstalling the existing package before running the new one and a ton of hardcoding.
I want to automate the whole process (with very less hardcoding) by setting up a WIX script to package all the 4 MSI's together. I read about the WIX bundle and used that to create a single MSI. But now there are lot of a variables to be passed to the 4 MSI's, so I thought of using custom actions to set these variables based on the environment/machine where the MSI is running. But I cant make custom action to work? Am i missing something?
A little bit of googling and I saw something like there are no CustomActions in Bundle? can someone confirm?
Also if there are no CA's what are my options? how can I manipulate the variables to be passed on to the 4 MSI's? Most of them needs to be set based on the machine its being run (like install path, user id's, app pool id's etc).
There is a fourth option, a useful lightweight hack, identified by Vijay Kotecha (see http://vijayskotecha.blogspot.com/2013/07/wix-bootstrapper-custom-action.html),...
Essentially, build an <ExePackage> around a pass-through .bat or .cmd batch file. The batch/command file contains the single line '%*' which re-executes all of the command line arguments as a first class command.
Thus:
<ExePackage ... SourceFile="SourcePath\WixCustomAction.cmd"
InstallCommand="my_custom_action.exe my_custom_parameters" />
<ExePackage ... SourceFile="SourcePath\WixCustomAction.cmd"
InstallCommand="my_next_action.exe my_next_parameters" />
Where WixCustomAction.cmd is a file containing only '%*'.
These <ExePackages> can be placed into the <Bundle><Chain> successively as needed using different InstallCommands as needed.
As I see it, you have three options:
Depending on what information you need, you can use the WixUtilExtension to perform simple tasks such as reading registry keys and performing file searches, which you can then pass the results to your installation packages as properties.
Implement custom actions in the individual installation packages themselves (not in the bundle).
Write your own custom bootstrapper application to determine all the properties you need to set, and then pass them to your installation packages. This is more complex than the #1 and #2, but if your interested the following links should get you started:
introducing managed bootstrapper applications and
write a wpf wix installer

TFS 2010: Perform different builds and command line task in sequence?

my build process with TFS 2010 should perform different task one after the other like:
Build 1st project in solution
Execute MSBuild via command line (to publish the project)
Execute a 3rd party tool via command line (to obfuscate the binaries)
Build a 2nd project in the solution (an InstallShield project)
How can I achieve this? I can define several project in the Build Definition but how can I invoke several command line task between these build steps? And the MSBuildArguments in the Build Definition: Are these arguments for every msbuild call for each project/solution?
Thanks
Konrad
At first, you need to add in your build definition the distinct *.*proj instead of one big *.sln - or (even better) construct more than one *.sln & order them to get build in the build definition. So you could organize a Project1.sln, Project2.sln etc that are only used from the Build.
In addition to that, you would have to make changes in the build process template to get this.By default you get something like that, that executes each set project/solution within a bigger foreach:
A good way would be to enhance this as a sequence, where all your custom action are set as InvokeProcess activities:
Obviously, you would have to insert here a flow control, so that Publish & Dotfuscator execute the first time (where Project1.sln gets build), while ISDEV executes the second time (where Project2.sln gets build). In the sample below I used a switch & packed Publish & Dotfuscator in a new Sequence.
Finally, you would have to have a counter of some sort. The most immediate option is to set a new Int32 Variable with default == 1 and increase it by hand during execution. In the sample below this is done in the lower Assign:
This final override of Complie the Project, along with a changed Build Definition should get what you 're after.
The team build definition takes a list of sln's and msbuild project files. You can put simply split your InstallShield project out into it's own solution ( most developers won't have a copy of InstallShield anyways likely ) and write an msbuild targets file for steps 2 and 3. Then just tell your build definition to build solution 1, the targets file and solution 2.
You could also choose to put the stuff in the targets file in a postbuild event for one of the projects in solution 1.
I wouldn't do this in workflow.