Using MSBuild Conditions on COMReferences - visual-studio

How can I specify a Condition for a COMReference in my *.csproj file? The following does not appear to work:
<COMReference Include="SomeComLib" Condition=" '$(Configuration)' == 'Debug' ">
...
</COMReference>
I have some COM references in a C# project in Visual Studio 2008. I would like them to automatically use non-isolation mode when I am in Debug, but automatically switch to Isolation mode when I make a Release build. I thought I could achieve this by specifying two different COMReferences in my *.csproj file, which are selected based on the Condition.

I think your strategy should work, but if not, you could also move the Condition to the ItemGroup that encloses the ComReferences.

Related

How to get Visual Studio to transform specific T4 Templates on build?

Is it possible to get Visual Studio to build only a specific set of T4 Templates on build?
Currently I use the solution provided here to make Visual Studio transform all of my T4 Template files upon build. However, I have a T4 Template that runs into this issue when it is transformed during build time. Therefore, I want to transform all templates except this particular one.
More specifically, I have the following code in my .csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<TransformOnBuild>true</TransformOnBuild>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
</PropertyGroup>
which "works" to rebuild most of my T4 Templates the way I want.
However, I have a T4 Template included in that .csproj that makes use of the Host variable in such a way that it causes the transformation to fail during build time (see here).
It is necessary that all of the templates except the latter are transformed upon build, so is there any way I can achieve this behavior?
Note: This type of <PropertyGroup> is used across multiple projects in multiple solutions, so for the sake of keeping things the same across the board I would prefer to continue using this for my transformations, if at all possible.
Add a condition to the metadata item for the template you don't want to transform as follows:
<Content Include="TextTemplate2.tt" >
<Generator Condition="$(BuildingInsideVisualStudio)=='true'">TextTemplatingFileGenerator</Generator>
<LastGenOutput>TextTemplate2.txt</LastGenOutput>
</Content>
This will stop the Microsoft.TextTemplating.targets from recognising the file as one that needs to be transformed, except when building inside Visual Studio.

Visual Studio 2015 - Running Post Build Events only when built from the GUI

I have a Visual Studio 2015 solution that builds 10 projects. In each project there are a pre and post build event to call ant to resolve and publish the code. These events should be triggered before and after every project build, so moving the events to the solution isn't going to work.
Each of the projects should also be capable of building from the command line using ant. When it builds from the command line the events are triggered, but it would be preferable if they weren't.
Does anyone know if there is there a way of VS/MSBuild determining if it is being triggered from within the GUI or from the command line?
I am not sure that you can do this in the PostBuildEvent, but you can use the AfterBuild target and add a condition like this:
<Target Name="AfterBuild">
<Exec Command="SOME_COMMAND" Condition=" '$(BuildingInsideVisualStudio)' == 'true' " />
</Target>
You will need to edit the project file by hand in order to do this, as the project properties does not let you control this.
If you're using Visual Studio 2017 you will need to add the conditional statement as an attribute to the PostBuildEvent.
<PostBuildEvent Condition="'$(BuildingInsideVisualStudio)' == 'true'">
This will prevent the post build events from running when dependencies are rebuilt.

Visual Studio 2010 Conditional References on first startup

I would have been glad to comment on an answer to this question visual studio 2010 conditional references but for some reason I cannot find this feature, thus a new question.
My problem is that the conditional reference only works correctly starting from the second startup. On the first startup of the solution, or if I remove the *.suo file, the conditional references are not processed and the solutions fails to build.
My condition is this one:
<Choose>
<When Condition=" '$(Configuration)'=='DebugUsingDLL' or '$(Configuration)'=='ReleaseUsingDLL' ">
<ItemGroup>
<ProjectReference>...</ProjectReference>
</ItemGroup>
</When>
</Choose>
I understand that the selected Configuration is stored in the *.suo file, which is why this works fine as long as the *.suo exists on the disk.
However, because we are using solutions to automate our builds , we always check out the source in a new folder, but the *.suo file must not be check in because it is user dependent.
To better understand, we use four configurations "Debug" "Release" "DebugUsingDLL" and "ReleaseUsingDLL", and we have different projects for DLLs and for static libraries: thus the references must change based on that.
I tried to only have DebugUsingDLL and ReleaseUsingDLL in the solution, which would mean the test should always yield true for this solution, but the reference are not processed correctly either.
Can you confirm this looks like a bug in the IDE ?
Can you suggest an alternative ?

Only sign assemblies with strong name during release build

The scenario is: I'm building my solution with TeamCity, I'm not running the build account as an administrator; so I get problems with the strong name keys.
I know of a few solutions out there, like running the build as an administrator and registering the certificates in the proper container.
Is there anyway to sign the assemblies within a solution file only during a release build and not during a debug build. Or are there any similar solutions?
I think it is strange that there isn't a MSBuild parameter that can be set wether the assemblies should be signed or not. Because if you look at the csproj-files there is an option there for signed or not signed
Another option is to edit the project file. By default if you enable assembly signing in Visual Studio it will be used for all build configurations. The project file contains an element like the following.
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
If you only want to sign the assemblies during a specifc build configuration, such as RELEASE. You can put the <SignAssembly> and <AssemblyOriginatorKeyFile> in the PropertyGroup element with the Condition that identifies your build configuration.
So if you want to sign your assembly during a release build, you can change your project file to the following.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<!-- other element of this PropertyGroup -->
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
Note: When you change your project file, to the following. you cannot change the signing settings of the Project Properties in Visual Studio. That means in Visual Studio is signing of the assembly disabled, also if you change the build configuration in Visual Studio.
Here's a solution where the assembly is signed in Release configuration, but not in Debug configuration. It uses the signing facilities from the project, not using the [AssemblyKeyFile] attribute. It's basically the same as Jehof's answer but in other words.
Set up the project for signing in the Signing tab in project preferences.
Unload the project, and edit it in the XML editor. Locate the SignAssembly property. Move that property into the two configuration dependent property groups. In the Debug configuration, set the property to false.
This will look something like this:
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<!-- ... -->
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<SignAssembly>true</SignAssembly>
</PropertyGroup>
Visual Studio works correctly even when changing build configurations, with the exception of the Sign the assembly check box in the Signing tab. I tested with Visual Studio 2008.
Cave-Eats:
You need to remove the [AssemblyKeyFile] attribute for this to work.
If you have [InternalsVisibleTo] attributes, you need to maintain two versions, like this:
#if DEBUG
[assembly: InternalsVisibleTo("MyLib.NUnit")]
#else
[assembly: InternalsVisibleTo("MyLib.NUnit, PublicKey=<your public key>")]
#endif
In other words, MyLib.NUnit must also be signed in Release configuration.
You can use preprocessor directives:
#if SIGN
//Only the Release build is signed
#pragma warning disable 1699 //We can't use the compiler switch
[assembly: AssemblyKeyName("KeyContainerName")]
#pragma warning restore 1699
#endif
Then define the SIGN symbol in the Release configuration.
You must install the key into a key container using sn.exe. Alternatively, you can use [AssemblykeyFile] to specify a path.
The #pragma suppresses this warning.

Does Msbuild recognise any build configurations other than DEBUG|RELEASE

I created a configuration named Test via Visual Studio which currently just takes all of DEBUG settings, however I employ compiler conditions to determine some specific actions if the build happens to be TEST|DEBUG|RELEASE.
However how can I get my MSBUILD script to detect the TEST configuration??
Currently I build
<MSBuild Projects="#(SolutionsToBuild)" Properties="Configuration=$(Configuration);OutDir=$(BuildDir)\Builds\" />
Where #(SolutionsToBuild) is a my solution. In the Common MsBuild Project Properties it states that $(Configuration) is a common property but it always appears blank?
Does this mean that it never gets set but is simply reserved for my use or that it can ONLY detect DEBUG|RELEASE. If so what is the point in allowing the creation of different build configurations?
I haven't done much with defining an MSBUILD configuration file but I have done builds of different configurations using a batch file like this
msbuild /v:n /p:Configuration=Release "Capture.sln"
msbuild /v:n /p:Configuration=ReleaseNoUploads "Capture.sln"
I defined the ReleaseNoUploads configuration inside Visual Studio.
Here's what I had to do for that (this is Visual Studio 2005):
Open the Tools:Options menu, go to the Projects and Solutions:General option, and check Show advanced build configurations.
From there, go to the Build:Configuration Manager menu
In the dialog that pops up, click on the Active solution configuration pulldown and click <New...> to create a new build configuration.
Sure, you can have as many custom build configurations as you want to define. See this related question for how the setup might look.
How to conditionally deploy an app.config based on build configuration?
Note that when 'inside visual studio', the $(Configuration) and $(Platform) are always set by VS using the Configuration Manager stuff in the dropdowns at the top. Whereas if you want to set these values using msbuild from the command line, you must pass in the values explicitly (as in #MarkBiek's answer).
(Most VS project templates will 'default in' a value for Configuration/Platform, so that you can use the command-line MSBuild without specifying these values explicitly. This is good, but makes these two useful/common properties appear a little more magical/weird than they actually are.)
Normally what I do to have Release and Debug both build from a single MSBuild script is:
<PropertyGroup Condition="'$(Configuration)'==''">
<Configuration>Debug;Release</Configuration>
</PropertyGroup>
Then add this but of MSBuild secret sauce:
<Target Name="configurations">
<CreateItem Include="$(Configuration)">
<Output TaskParameter="Include" ItemName="Configuration" />
</CreateItem>
</Target>
And then for each target do something like this:
<Target Name="Compile" DependsOnTargets="configurations" Inputs="#(Configuration)" Outputs="target\%(Configuration.FileName)">
<MSBuild Projects="#(MyProjects)" Targets="Build" Properties="Configuration=%(Configuration.Identity);WarningLevel=1" />
</Target>

Resources