Is there a way to conditonally #define a symbol in a dependency? - c#

I am working in a solution where there is a specific library in the solution that turns on or off functionality via #ifdef's.
I have another project in the solution that uses it as a dependency. In my build settings, I want to be able to define the symbols in the dependent library based on build configuration in my project. I cannot find any way to do this within Visual Studio.
Is there any way to accomplish this?
(I realize the ideal solution here would be to change those #ifdef's to something else, but please assume that I cannot edit code in the other project)

Build tab in project options depends on selected value of build configuration dropdown. You can test, when you've selected Debug, Define DEBUG constant is checked, but not in Release mode.
Just choose appropriate configuration (Debug, Release or custom one) and set value of conditional compilation symbols.

I don't think you can do that. There are no "solution level" defines, all defines are scoped to a project.
As #archil points out you may be able to achieve some by selecting correct configuration for the project.
One more option could be to build project with MSBuild directly instead of using normal VS IDE route, this way you will be able to override defines via command line (http://stackoverflow.com/questions/479979/msbuild-defining-conditional-compilation-symbols)

Related

How to share major and minor version of the main application with its DLLs?

I have a large WinForms application (C# , .NET 4.5.2) with several own DLLs (plug-ins for the application), all as different Projects in the same Solution. I use Visual Studio 2015 Community.
The main app and all the DLLs have their version number assigned in their respective AssemblyInfo.cs files like this:
[assembly: AssemblyVersion("1.0.*")]
Now I want to up the version of the application to, say, 2.0.. I also want all the DLLs to be 2.0.. The way I currently have it I would need to go into each DLL and manually change the version to 2.0.*.
Is there a way to inherit the "2.0" part from the application so that, in future, I would only have to change major and minor version number in one place?
I did some searching but was not able to find the answer.
Update:
What I was hoping is that I can replace
[assembly: AssemblyVersion("1.0.*")]
with something like:
[assembly: AssemblyVersion(some_string + ".*")]
where "some_string" is a string containing the major and minor version number. But I wouldn't know where I can define that string, or if this is possible at all.
Add a link to the original AssemblyInfo.cs file to the other project via the project solution explorer:
Right click on the project -> Add -> Existing item -> Add as link (from the dropdown menu)
Now, once you change the original AssemblyInfo.cs, any changes will be applied to all the projects to which the file was added as a link.
Edit:
To avoid duplicating attributes that should be unique per assembly (such as the GUID), make two files, one for the shared attributes like version number, and another for assembly specific attributes. No one forces you to put everything into the same file. It does not even have to be named AssemblyInfo.cs
In Visual Studio of you can set Pre build events.
Right click the project and select properties
Go to Build Events
then in the first box for pre-build event you can launch a simple script like this
if $(ConfigurationName) == Release C:\AssemblyChanger.exe $(ProjectDir)
This sample script above will Launch "AssemblyChanger.exe" located on your c drive and it will pass the current Visual Studio project folder as an argument. from there it is very simple to read the Assembly.cs on the specific project that manage the "version" and edit the one in the path that was pass as argument. Plus this will only be called if you are in Release mode (that "if" can be removed without a problem).
You can create a simple console application to do that.
That script can be set in all DLL pre build event so when they compile they call the script and they will get their assembly edited before the compiler create the DLL.

How can I change Visual Studio's build order for reflection based project dependencies?

I have the need to dynamically load different versions of the same dll's depending on various situations.
The dll's are created as part of the build process for other projects within the same solution.
For example
/MainSolution
/MainProject - Loads dll's using reflection dynamically
/AbstractProject
/DllProject1
/DllProject2
DllProject1 and DllProject2 need to be built before MainProject. MainProject depends on AbstractProject, and through reflection DllProject1/DllProject2. However Visual studio currently forces MainProject to build before DllProject1 and DllProject2. How can I get Visual Studio to build DllProject1/DllProject2 before MainProject?
Visual Studio allows you to set explicit build dependencies in the solution (as opposed to implicity dependencies e.g. from traversing your references). Just right-click on your solution and find the Project Dependencies menu item:
The dialog that opens will allow you to set build dependencies and show you the calculated build order (you can affect the order by changing the dependencies).
The solution I found was to do the following:
Open up the .sln file, and change the order in which they projects are listed. Dropping MainProject down to the bottom. Then when I opened up the solution, it had DllProject1 and DllProject2 listed above MainProject in the build order.
Edit: While this works, there is no rhyme or reason for how it works. Randomly switching the order results in randomly changing the build order for projects that have the same dependents.
I tried a neat trick and it worked - we have a fairly big solution and it was difficult to maintain the dependencies just right to get the solution build order working from build to build -- it happened that one of our little console test apps happened to be first up in the build order - so I faked the dependencies for that little app and it fixed up the build order for the entire solution - KLUDGE - yes

How do I configure a Visual Studio C# unit test solution to accept different runtime configurations?

What I have
I have a unit test Visual Studio C# Solution (which runs webdriver tests, not that that's necessarily relevant). It runs via TeamCity. Currently the environment is hard-coded to "Dev" in one of the .cs files, and I manually change the code locally to run elsewhere when required.
What I want
A way to setup two projects in TeamCity - one to run on "Dev" environment and the other on "Test" environment. Obviously I can't use hard-coded values so I need some sort of set of configuration files that can be chosen at runtime, or possibly some sort of build parameters - but I have no clue how to do this or what will work.
(I didn't mention TeamCity in the question as it is not 100% relevant / just provides context --- as long as I can run the unit tests eg from the command prompt with parameters that can be passed in, that would do the trick.)
What I've tried
From what I've asked around, I don't believe I can use web.config as it's not a web solution but a unit test solution. I believe there is a mechanism to tell Configuration Manager what web.config file to use, so I'm hoping there's a similar mechanism that can be used for Unit Test projects. I've tried hunting down information on "build configurations" on "unit test projects" and a range of other searches, but it's a nightmare finding anything relevant.
Can someone point me in the right direction? I'm good with my basic programming, but if it requires messing around with configurations or build parameters, then I might need a more explicit 'how-to' from you.
Thanks in advance.
Check this extension for Visual Studio
https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859
This allows you to create different config files for different build type. You need to create different build types each with a config file specific to that build type.
Ok as per my comments above, I tried a solution here: https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5
IT WORKED.
I'm now able to create App.Config transforms that automatically link to a Build Configuration. I can then specify the build configuration inside TeamCity.
The only trick was that the "Rebuild" target didn't work if there were no code changes but there was a difference in Configuration. (They use the same directory of the same Agent, and a rebuild is necessary). The workaround for this is to tick the 'Clean all files before build' option in TeamCity Version Control settings.

How do I disable suppressing a warning for one solution in a TFS build

I'm using TFS 2010 and have a TFS build setup to build our software. Everything is working just fine.
But, we are getting the following warning:
CSC: Assembly generation -- Referenced assembly 'mscorlib.dll' targets a different processor
This is because some of our code is marked as x86 only, and it is being built on an x64 platform. We cannot change the target platform because of third party software we link to.
Also we are targeting the 2.0 framework, which also cannot be changed at this point.
So, I want to simply suppress this error. Seems straight forward enough.
I simply edited the Build template, and added /p:NoWarn=1607. That works.
BUT!
We have ONE solution which is written in VB.net, instead of C#. This causes that one solution to fail with the following error:
vbc: warning number '1607' for the option nowarn is either not configurable or not valid
How do I disable suppressing this warning on that one solution in my TFS build?
I tried to use a <customPropertiesForBuild> tag in my TFSBuild.proj file but I'm probably not using it correctly.
I know I could simply add this to my project files, but we have 37 solutions, each with multiple project files, so I really don't want to do that.
I don't think you can control that suppression from TFS since it is MSbuild complaining during build (and TFS simply calls MSBuild and collects the results).
There's a specific property that tells msbuild to ignore this kind of warning. Simply add the following line to your top Propertygroup in the project file for those projects generating the warning:
<PropertyGroup>
...
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
You should be able to use Properties metadata on the VB solution's SolutionToBuild item to set NoWarn to an empty value just for that solution:
<SolutionToBuild Include="$(BuildProjectFolderPath)/../../MyVbSolution.sln">
<Targets></Targets>
<Properties>NoWarn=;</Properties>
</SolutionToBuild>
Try that and see if your VB solution will compile without errors.
You can provide a NoWarn Property to MSbuild in TFS Build. One idea also is to edit the build definition, in the "Process" Tab, explore the Advanced=>MSBuild Arguments, and then you supply this "/p:NoWarn=1607" without the qoutes. When you also queue a build, in Parameters Tab=>Advanced=>MSBuild Arguments, enter/p:NoWarn=1607.

Can I set a C# preprocessor directive from a central file?

I need to add some logging to my app, and it needs to be in release mode, and I need to make sure that the logging code isn't running in production. Therefore I'd like to use a #define and #if to make sure the log statements are removed when I move to production.
Trouble is, I need the logging in multiple files, and it's a pain to put a #define at the top of every file. Is there a way to have a centralized #define? That way I can remove the single #define rather than a #define from all files(which means I'll almost assuredly forget one).
On the command line, use the /define switch. In Visual Studio, choose the "Build" tab from the properties page for the project and fill in the "Conditional Compilation Symbols" section.
Consider also instead of using conditional compilation, to instead make your logging methods conditional methods. That's a more pleasant-looking alternative. That's how Debug.Assert works; it is a conditional method, so if the debug preprocessor symbol is not defined, the compiler simply removes all calls to the method before code generation.
See also my article on the subject:
http://ericlippert.com/2009/09/10/whats-the-difference-between-conditional-compilation-and-the-conditional-attribute/
Are you using Visual Studio? In the project Properties page, on the "Build" tab, there's a "Conditional compilation symbols" text box.
Yes, this is typically done in your build file, or the script you use which creates your build. You specify it as command-line arguments to MSBuild.
To add to Dave's answer, global conditional compilation symbols can also be specified in Visual.
Right-click on your project and go to Properties
Go to the Build tab
You can specify the symbols that you like (DEBUG is already turned on by default for Debug configurations, so this might actually give you what you want already) for the given configuration, or select "All Configurations" at the top to specify certain symbols for all configurations.
Call the logging everywhere you want.
Define the logging api entry methods with
[Conditional ("DEBUG")]
public void WriteDebugMessage(...)
Build your program in debug mode (which, by default, defines 'DEBUG' in VS). These calls will be part of your assembly.
Build your program in release mode (or - remove the DEBUG symbol from the build definition). These calls are now meaningless no-ops and won't run.
Seems like what you want?

Categories