How to get literal string value of Project Pre Build Event property - visual-studio

For my work I have to define a pre build event in a powershell script, which will be added to the target project that I install the NuGet package in. The script installs fine the first time, the pre build event is being added the right way like this:
xcopy $(SolutionDir)Some\Path $(ProjectDir)Some\Other\Path
When I uninstall and install my NuGet package again, the existing pre build events are being requested from the target project. The problem is that when an environment variable like $(ProjectDir) or $(SolutionDir) is being used in the pre build event, my powershell script gets the value that is associated with the variable. Like so:
c:\Path\To\Solution\Dir
or:
C:\Path\To\Project\Dir
But I want it to give me the string with the env variables in it.
How can I get the literal value from the pre build events in powershell?
Tim
UPDATE::
I have done a little more research and concluded that the environment variables in the build events won't be replaced UNLESS it is a Windows Installer project.

How to get literal string value of Project Pre Build Event property
AFAIK, you can't get literal string value of Project Pre Build Event property. Because Macros are expanded by the Preprocessor, which happens even before the code is compiled. It is a purely textual replacement.

Related

Visual Studio Team Services - edit link settings

I just noticed on Visual Studio Build task the following:
To have parameters for common settings such as the solution file seems like a good idea to me, given that some parameters are used in more than 1 task... But I honestly don't like to use the wildcards, I'd rather use the path to the solution file.
If I click on Link Settings I am not able to edit the value for the Solution setting, is there a way to change it?
When you link a setting from a build task it will not be editable in the Task itself. To edit it you need to go to the Process section of your build definition. There you can see a new parameter is added that maps to the solution setting in your MSBuild task.
You can see in the above image, the new parameter that was added to the process section of the build definition. You can clearly see if you unlink the setting from the build definition, the parameter will be removed. Here if you want, you can select the full path to the solution instead of using a wildcard
For anyone coming to this answer later, I'm using Azure DevOps Server 2019, and the names of things have changed. I can get to the definition of "Solution" by going to Task -> Pipeline -> Parameters.

add msbuild property in nuget

I want to create a nuget package that will add a custom msbuild property before PostBuildEvent property (because I need to use it inside post build event) and after imports (so that I can use TargetDir property) without the user being asked to reload the solution. Is this possible?
I tried using Set-MSBuildProperty from NuGet Power Tools, but that adds property in first property group; I also tried Get-MSBuildProject and "$buildProject.Xml.AddPropertyGroup().AddProperty()", but that adds new property group after immediately after last existing property group (but that may still be before imports). What's worse, both these methods result in an ugly dialog that asks whether changes to project files should be discarded or overwritten (both terms sound equally bad).
MSBuild does have a PreBuildEvent, which executes after linking is complete but before the actual build begins. Would that work?
Thanks,
Clay

Indirect way to reference "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\datasvcutil.exe" in a prebuild event

I am running the datasvcutil.exe command in a prebuild event.
datasvcutil.exe is located in "C:\Windows\Microsoft.NET\Framework64\v4.0.30319" (on 64 bit machines.)
I can just hard code this as C:\Windows\Microsoft.NET\Framework64\v4.0.30319\datasvcutil.exe, but that seems rather brittle. When a hypothetical .net v4.0.30320 comes out my prebuild event will not work anymore.
With the Visual Studio Command prompt, I can call datasvcutil.exe with out the path. I am wondering if there is a similar indirect way to call this from my pre-build event command line.
Since the tool you need is in the same path as MSBuild.exe you could simply reference it with $(MSBuildBinPath)\DataSvcUtil.exe which would make it also independent of Framework / Framework64
I like Filburts answer above. But if you really want to be courageous, you can invoke:
%VS100COMNTOOLS%\VCVarsQueryRegistry.bat
rem and query one of the %FrameworkDIR32% or %FrameworkDIR64% environment variables, depending on your choice
If you are even more courageous, MSBuild is capable of reading registry by itself - the following link may help: http://msdn.microsoft.com/en-us/library/ms171458.aspx (check the "Registry Properties" section)

How to emulate /p msbuild parameter in Visual Studio build?

That the logical follow-up for the my previous question: "How to check all projects in solution for some criteria?"
I was given quite a good answer to use CustomAfterMicrosoftCommonTargets, CustomBeforeMicrosoftCommonTargets. They do work, so I decided not to stop in the middle.
Issue is that I don't want machine-wide tasks. It's not a good idea neither for me (it will affect other builds. sure, this can be handled, but still), nor for my teammates (I don't want to let them put something in system folders... ), nor for build server.
What is needed: solution to be built from scratch out of source control on clean machine with either Visual Studio or MSBuild.
It appeared that Custom*MicrosoftCommonTargets are regular properties.
So, how to specify this property? It works pretty fine when to set it from command line.
That's strange, but it appears that bit of magic present here: property passed as command line parameter to one build is transitively passed to all nested builds!
That's fine for build server. But this won't work with Visual Studio build. And even declaring solution-level property won't help: neither static, nor dynamic properties are transfer to nested builds.
...I have a hacky idea to set environment variable on before solution build and erase it on after. But I don't like it. Any better ideas?
I use a bit different technique then #Spider M9. I want that all projects in solution tree/all subdirectories from current directory use extended build throw Custom*MicrosoftCommonTargets. I don't like to be forced to change every new project to import custom targets/props.
I place special file, let's say msbuild.include, in the root directory and my custom targets loader for every project tries to find it in ., ..\, ..\..\, and so on. msbuild.include contains flags that triggers execution of custom actions. If loader can't find this file it disables loading all custom targets and stoppes. This gives me ability to use my build extensions with projects from work repositories and to not use with opensource projects.
If you are interested in I can publish loader. It's a pretty simple and elegant solution.
For example I can sign any assembly in all projects in all subfolders with my key.
I always set up every project to import a standard .props file. Use the GetDirectoryNameOfFileAbove property function (see MSDN) to find it. Do this as the first line of every project file. Once established, you can redirect from that file to other imports. Another trick is to have that standard import (that would obviously be under version control) import conditionally another .props file only if it exists. This optional file would not be in version control, but is available for any developer to create and modify with their own private/temporary properties or other behavior.

Can Xcode insert the version number into a library's filename when building?

If I am building a dynamic library called Awesome, Xcode outputs the built product as libAwesome.dylib. Is there a way to have Xcode insert the filename, so it gets built as libAwesome.1.0.0.dylib?
Set your Product Name to Awesome.${DYLIB_CURRENT_VERSION}.
DYLIB_CURRENT_VERSION is set by Current Library Version in the build settings.
Oh, and to see a list of all such environment variables, just make a new Run Script Build Phase, leave it empty, but check the "Show environment variables in build log" box, and then build. If you show the log for that build phase, it'll show all the environment variables along with their values. And then you can use them in the same way as above.

Resources