I have .net C# application. In the application have two set of code for different client.
We were thinking of removing the part of code through preprocessor. Diabling the part with config file parameter is not an option for us.
We want simple setup like:
#define DEBUG
//....
#if DEBUG
Console.WriteLine("Debug version");
#endif
The only issue is, our part of code is distributed into multiple files and multiple projects in the solution.
So we want to define globally the preprocessor “DEBUG” at one place. Preferably in project property or something.
What is the best option for us?
Look for "Conditional Compilation Symbols" on the "Build" page of the project property dialog. You can set it per-build configuration.
Related
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?
Is this possible to check in assembly what client (winforms app or asp.net page) is running it?
I want to add some methods but only for specific client.
I know, there is predefined DEBUG (#if DEBUG). Where can I find full list, what can I check using preprocessor?
To expand on m0sa's answer, preprocessor directives are basically just a string passed to the compiler.
If you are so inclined, you can add new build configurations (example: instead of Debug/AnyCPU and Release/AnyCPU, you could make WebDebug/AnyCPU, WinformsDebug/AnyCPU, WebRelease/AnyCPU, etc).
Then in the properties page of your project, for each configuration you could provide a value in the 'Conditional compilation symbols' field. For example, for WebDebug and WebRelease, you could provide the conditional symbol WEB. Then, you would be able to use:
#if WEB
using MyNamespace.WebStuff;
#endif
You will need multiple build configurations for that and define different a preprocessor directive for each one. You can set the conditional preprocessor directives in the Build tab of the project Properties page.There are no other directives defined, just the DEBUG directive which you can turn on and off (together with the TRACE directive) in the same tab. Note that DEBUG it is not defined for the "release" build configuration. This is kind of what you will need to do to enable different versions of the assembly to be built.
References:
MSDN
www.davidarno.org <-- see this one for a more visual description
#if(DEBUG)
......Code......
#else
......Code......
#endif
I have some code like this. If my application is running in Debug mode it should execute the #if(DEBUG) part, if it is running in Release mode it should execute the #else part. However, it is only executing the #if(DEBUG) part no matter which mode it is running in.
Am using WPF application with VS2010
Can anyone help me?
For Debug Configuration, your project settings should look like
For Release they should look like this
Can you verify that this is the case, and let us know if it is?
If not, what is there for each configuration?
Create a new project using all the default settings and check that you can make that work as expected. If so, your problem project must be "corrupted" in some way, perhaps by defining the DEBUG constant in the release configuration, or by having the debug project configuration selected for the release solution configuration.
It depends on how you create your configurations. For example if you create your configuration and use debug or release as a template DEBUG or RELEASE will be copied to the defined constraints element. It will not change the defined constraints element (in the project file) to the new configuration name.
Open up the project file and look for the configuration sections. Make sure the Platform, the below example it is "PROD" has an entry in the DefineConstants element. If it does the pre-compiler directives will don't work as expected in the code.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PROD|x86'">
<DefineConstants>PROD;TRACE</DefineConstants>
<OutputPath>bin\x86\PROD\</OutputPath>
</PropertyGroup>
Why are you putting DEBUG between parentheses?
#if DEBUG
Code
#else
Code
#endif
I would guess that in your project properties, under Build you have checked off Define DEBUG constant.
Try setting configuration mode to Release and run your application again. Default for Release is that the DEBUG constant is not defined, if you haven't tampered with if of course ;)
If Define DEBUG constant is not checked, that means you have a #define DEBUG lurking somewhere.
So two things to do. Check constant in options under Release mode, and check for any manually defined constant. It should be one of those.
I have a base library to maintain in multiple versions. I do a SVN switch whenever I need to work on another version.
I don't have multiple versions of my test application solution, so I thought that for different versions I could do multiple solution / project configurations that define symbols for the version to be able to have version-specific code in my test.
Currently I have the following build configurations in the test application solution: Debug, Release, DebugV10, ReleaseV10, DebugV15, ReleaseV15. In the *V10 and *V15 configs, I created and selected corresponding *V10 and *V15 PROJECT configurations for the two projects that have version-specific test code (not for all projects, most run normal Debug / Release configuration in the solution -Vx configuration).
In those project configurations I entered the corresponding conditional compilation symbols (VERSION10 and VERSION15).
Now in my code in the project I go like
#if VERSION10
// do v1.0 stuff
#elif VERSION15
// do v1.5 stuff
#else
// do trunk stuff
#endif
But apparently VS doesn't recognize the symbols. Even a simple #if DEBUG does not work anymore, allthoug define DERBUG constant is checked in all Debug* project configurations.
Is this a known thing? What can I do about it?
The concept that you describe sounds fine.
That is, the code uses:
#if VERSION10 ... #endif
and the Project configuration defines VERSION10
and a Solution configuration is set up that is set to use the above Project configuration.
As long as these are all set up correctly, I'd expect it to work.
The fact that you say even #if DEBUG isn't working as expected suggests that something is very broken.
I'd suggest you try the simplest possible case, to ensure you undersatand how to set it up: Create a new minimal "hello world" application that just has simple code that allows you to tell apart the versions:
#if VERSION1
Console.WriteLine("Hello from version 1");
#else
Console.WriteLine("Hello from version 2");
#endif
Then create project configurations ("Debug Version 1", "Debug version 2") and see if you can set them up (one with VERSION1 defined, one without) to get the two outputs when built.
Then add Solution configurations that use the above Project configurations, and build them to check that they print the right things when executed.
Once you've done this you should have a working system (an understanding of how these elements relate to each other) that you can apply back to your more complex project. To apply them back, I suggest deleting most of the project/solution configurations and then rebuilding them from scratch now that you are sure you know what to do - often rebuilding these things from first principles works out better than trying to tweak an existing 'broken' setup back into life.
Conditional compilation in C# is different from C and C++. See here for info on the ConditionalAttribute class.
For example:
doDebugOutput(); // unconditionally call the optional code
Conditional["DEBUG"]
void DoDebugOutput()
{
// do expensive debug-only output here
}
I have several classes in a project which need to only be in certain builds of the application which are currently not ready for release or debug.
To prevent these classes from being used, I want to set around them this:
#if USE_MYCLASS
// Code here...
#endif
Unfortunately, I don't know how to setup a project-wide #define.
Is there functionality in Visual Studio to set project-wide definitions?
If there is, though I don't need it right now, is there a functionality to set solution-wide definitions?
If there is no functionality for such (seeing as C# does not have include files, I suppose it's possible), is there any method or plugin of doing this functionality without using the command line compiler and /D?
You can do that in the project properties, but not in source code.
Project Properties => Build => Conditional compilation symbols
You can specify whichever symbols you need (space delimited, but IIRC is is quite forgiving). Note that DEBUG and TRACE can also be toggled with a checkbox.
I have some projects with multiple "release" build configurations, with different symbols in each (for building 2.0 vs 3.0 vs 3.5 versions - see <DefineConstants> here)