How to have global settings defined in a solution in VC++? - visual-studio

I have a number of solutions with a large number of projects in them. I would like to be able to define global settings for the solution that are used by all projects. For example an include directory. I want to be able to change the include directory in one place for all projects in the solutions.
When I searched for a solution I found a good description of the problem that matches mine exactly but the solution suggested there, project property sheets, are defined per project and not per solutions.
I could use environment variables or Visual studio settings, but then everyone that needs to compile the code has to define the exact same settings.
Can anyone suggest a way to do this? Thanks.

We use property sheets to accomplish this. A single property sheet can be assigned to all the projects in the solution. From then on you can change a setting in that one property sheet and it will affect all the projects.
Advanced tip: We actually use multiple property sheets, (e.g. one for release target types, one for debug target types). The tip is that the order is very important. If you're editing the project files by hand then the last property sheet will override settings in the previous property sheets in the list. If you're editing in the GUI, then the TOP one overrides the ones below it.

As others have suggested, property sheets can do what you want. The trick is to use InheritedPropertySheets as you would use #include in C++. NOTE: the XML is slightly different for project files and property sheet files. Here's a contrived and simplified example of two projects (prjA.vcproj and prjB.vcproj) including the same property sheet (sln.vsprops) which itself includes another (strict.vsprops):
strict.vsprops
<VisualStudioPropertySheet ...>
<Tool Name="VCCLCompilerTool" WarningLevel="3" WarnAsError="true"/>
</VisualStudioPropertySheet>
sln.vsprops
<VisualStudioPropertySheet ... InheritedPropertySheets=".\strict.vsprops">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="NOMINMAX=1"
RuntimeTypeInfo="true"
/>
</VisualStudioPropertySheet>
prjA.vcproj
<VisualStudioProject ...>
<Configurations>
<Configuration ... InheritedPropertySheets=".\sln.vsprops">
</Configuration>
</Configurations>
...
</VisualStudioProject>
prjB.vcproj
<VisualStudioProject ...>
<Configurations>
<Configuration ... InheritedPropertySheets=".\sln.vsprops">
</Configuration>
</Configurations>
...
</VisualStudioProject>
You may also find this question and its answers useful.

Maybe you could add an MSBuild file to your solution in which you define a number of shared properties, and then <Import> that file into all your real projects?
That is, in your "settings" MSBuild file you define a number of properties:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WinUnitIncludeDir>C:\Includes\WinUnit</WinUnitIncludeDir>
<!-- Other shared properties go here -->
</PropertyGroup>
</Project>
From your real projects, you can then refer to this:
<Project ...>
...
<Import Project="path/to/settings.msbuild" />
...
<Configurations>
<Configuration ...>
<Tool Name="VCCLCompilerTool"
...
AdditionalIncludeDirectories="$(WinUnitIncludeDir)"
... />
...
...
...
</Project>

As suggested, you should look at Property Sheets (aka .vsprops files).
I wrote a very short introduction to this feature here.

I searched exactly the same thing some time ago but didn't find exactly what i wanted.
The only thing that might be close to this feature are Property Sheets. That's not exactly global as it's owned by a project and used by others.

Related

How do I replace part of a path in my web.config transform?

I am trying to perform a web.config transform in Visual Studio 2022 by modifying the web.Debug.config file.
Changing attributes on elements, removing elements and attributes, etc. is all very straightforward. But I've a read through this document and I've done some Google searching, and I cannot figure out a way to replace part of a path string in my web.config file.
Given that I have lots of NLog target elements is there an easy way to replace the root path in the fileName and archiveFileName attributes for each?
Here is where I am coming from:
<target xsi:type="File" name="seedDataLogFile"
fileName="C:/ProductionPath/Logs/seedDataCurrent.json"
archiveFileName="C:/ProductionPath/Logs/SeedDataArchive/{#}.json"
archiveEvery="Day" archiveNumbering="Date" archiveDateFormat="yyyy-MM-dd" maxArchiveFiles="60"
concurrentWrites="true" keepFileOpen="false">
And here is where I want to go:
<target xsi:type="File" name="seedDataLogFile"
fileName="D:/DevelopmentPath/Logs/seedDataCurrent.json"
archiveFileName="D:/DevelopmentPath/Logs/SeedDataArchive/{#}.json"
archiveEvery="Day" archiveNumbering="Date" archiveDateFormat="yyyy-MM-dd" maxArchiveFiles="60"
concurrentWrites="true" keepFileOpen="false">
Thanks for your help.

Configuration-specific resw resource string variants

Been trying to set up configuration-specific variants of resource .resw files in my project, so I could have have different resource string values in Debug and in Release (and in other configurations).
There are standard facilities in VS to have files conditionally included or excluded from build depending on selected Configuration. I have set up file properties to be Content=Yes and Excluded From Build=No for a file that must be included in a configuration, and the other way around for the other file.
The variants appear as expected in the IDE - only one matching current configuration is active, and another one is shown with Content=False in the Properties view, and with a red icon in the files list. The vcxproj also contains correct PRIResource nodes for .resw files with DeploymentContent and ExcludedFromBuild set:
<ItemGroup>
<PRIResource Include="Debug\Strings.resw">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
<DeploymentContent...
Building this project however fails with a message
error PRI277: 0xdef00532 - Conflicting values for resource 'resw
name/resource name'
Examining intermediate files reveals that both .resw variants are listed in resources.resfiles that is then fed into MakePri.exe . The ExcludedFromBuild setting appears to be ignored.
How would I get this to work? Is there a special way to control the inclusion of resw files? Maybe a different approach to having string variants altogether?
There are apparently "qualifiers" for organizing resource variants, and a naming scheme (https://learn.microsoft.com/en-us/windows/uwp/app-resources/tailor-resources-lang-scale-contrast). There is even a "Configuration" qualifier, though it is not entirely clear which configuration that is, and where at run time I am supposed to take an identifier to select a resource variant I want.
Adding this as an answer for the sake of completeness, as this is relevant and might even be useful to someone. But I am not happy with project configuration concerns being displaced to runtime, with unneeded and possibly sensitive values being added to the package. So I decided to force-emulate ExcludedFromBuild and am picking and copying the single .resw variant I need into build via a Custom Build Step. Shout out to whoever is responsible for this awkward mess at Microsoft.

why do properties in visual studio reference themselves with macro

For example:
As far as i know what is happening here is that jcapimin.c's AdditionalIncludeDirectories metadata property is being set so that it can be referenced later with the %(AdditionalIncludeDirectories) macro in the compilers command line and wherever else you want.
So what I don't understand is why when something down the line retrieves this information using the %(AdditionalIncludeDirectories) macro the information retrieved needs to have %(AdditionalIncludeDirectories) stuck on the end of it
Values of variables (properties, items, metadata, ...) are not automatically inherited in MsBuild, but instead new declarations of the same name override the previous value. So if the %(AdditionalIncludeDirectories) is not appended the new value of AdditionalIncludeDirectories would be just the ....\jpeg;....\jpeg\simd part and the compiler wouldn't be able to find standard library headers etc.
The property pages like you show are just a user interface on top of msbuild, which is easy to check if you open the project file in a text editor so here's a fictive sample of what happens in MsBuild:
<!--Somewhere in the msbuild files with compiler options-->
<ItemGroup>
<AdditionalIncludeDirectories Include="$(VCInstallPath)\include"/>
</ItemGroup>
The code in the above file is eventually included in your project file, and now you want to add directories to the compiler's include search path. Suppose you'd write
<ItemGroup>
<AdditionalIncludeDirectories Include="..\jpeg"/>
</ItemGroup>
then the new value of AdditionalIncludeDirectories is just ..\jpeg. Which is why we use
<ItemGroup>
<AdditionalIncludeDirectories Include="..\jpeg;%(AdditionalIncludeDirectories)"/>
</ItemGroup>
instead so the value is expanded to ..\jpeg;$(VCInstallPath)\include.
Unrelated remark: usually you shouldn't be declaring include directories per file like that; suppose there's a second file which also needs that jpeg include path, you'd have to repeat yourself and write the same thing again. Repeating yourself in programming is nearly always wrong. Declaring the include path on the project level would be a good start. If you also don't want to repeat the same path across projects, look into using property sheets.

How to apply two different transformations on one web.config element?

From my VS2010 deployment project I would like to apply two different transformations to two different attributes of one element in my web.config. Consider the following web.config snippet:
<exampleElement attr1="false" attr2="false" attr3="true" attr4="~/" attr5="false">
<supportedLanguages>
<!-- Some more elements here -->
</supportedLanguages>
</exampleElement>
Now how can I change attribute 'attr1' and remove attribute 'attr5' in the transformed web.config? I know how to perform the individual transformations:
<exampleElement attr1="true" xdt:Transform="SetAttributes(attr1)"></exampleElement>
and:
<exampleElement xdt:Transform="RemoveAttributes(attr5)"></exampleElement>
But I don't know how to combine these transforms. Anybody?
EDIT:
Can't answer my own question yet, but the solution seems to be:
It seems that it is possible to repeat the same element with different transformations, like so:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<exampleElement attr1="true" xdt:Transform="SetAttributes(attr1)"></exampleElement>
<exampleElement xdt:Transform="RemoveAttributes(attr5)"></exampleElement>
</configuration>
As said, this seems to work, but I'm not sure whether this is the intended use of the web.config transformation syntax.
As Nick Nieslanik confirmed this is done by repeating the same element with different transformations, like so:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<exampleElement attr1="true" xdt:Transform="SetAttributes(attr1)"></exampleElement>
<exampleElement xdt:Transform="RemoveAttributes(attr5)"></exampleElement>
</configuration>
I'm using XmlPreprocess tool for config files transformations & manipulation. It is using one mapping file for multiple environments. You can edit mapping file by Excel. It is very easy to use.
You can update your config files with xmlpreprocess and use configuration (debug, dev, prod,...) as a parameter for the different setup...

How do I sort my code (by method name) in Visual Studio 2008?

Short of cutting and pasting, is there a way to sort the methods in my classes in Visual Studio 2008? I like orderly code.
This is a free plug-in that does what you are asking: http://www.visualstudiogallery.com/ExtensionDetails.aspx?ExtensionID=800978aa-2aac-4440-8bdf-6d1a76a5c23c
Update
Unfortunately the link is outdated. You can download Regionerate at http://www.rauchy.net/regionerate/docs/2007/05/download.html
If you are using Resharper, you can change the Type Members Layout template so that it orders your code however you like. See under Resharper>Options>Languages>C#>Type Members Layout.
alt text http://www.jetbrains.com/resharper/features/screenshots/40/automatic_member_layout_full.png
You can, for example, put methods with particular attributes first in your file... e.g. methods marked with NUnit's [Setup] and [TearDown] could come before methods marked with [Test] by placing a block like:
<!--Fixture Setup/Teardown-->
<Entry>
<Match>
<And>
<Kind Is="method"/>
<Or>
<HasAttribute CLRName="NUnit.Framework.TestFixtureSetUpAttribute" Inherit="true"/>
<HasAttribute CLRName="NUnit.Framework.TestFixtureTearDownAttribute" Inherit="true"/>
</Or>
</And>
</Match>
</Entry>
before:
<!--Test methods-->
<Entry>
<Match>
<And Weight="100">
<Kind Is="method"/>
<HasAttribute CLRName="NUnit.Framework.TestAttribute" Inherit="false"/>
</And>
</Match>
<Sort>
<Name/>
</Sort>
</Entry>
and then have a catch-all for everything else:
<!--All other members-->
<Entry>
<Sort>
<Name/>
</Sort>
</Entry>
The template system is very powerful and should meet your needs.
You may find or be able to make a macro to do this, but there is no built in functionality of VS to sort your methods. Some third party productivity tools like Resharper and CodeRush provide some functionality to reorder your code.
ReSharper has Code Reordering functionality and a File Structure view that lets you do drag and drop reordering.
Resharper will do a good job in a limited way. It depends on how much you want. For example, it wont go and reorder your overrides in an asp.net page based on lifecycle, or anything like that, but it will keep properties, fields, methods and what not clearly grouped
EDIT: By the eway i was refering to auto reordering aka reformatting.

Resources