Compile a dll that always runs its code as if System.Diagnostics.Debugger.IsAttached

Is it possible in Visual Studio to compile a dll  that always runs its code as if System.Diagnostics.Debugger.IsAttached?
I am using C#.
LVL 2
itniflAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
Does code actually run differently when that is attached?  (I doubt it does)
0
itniflAuthor Commented:
Yes, my code is written to check for it and bypass data collector tasks that are not available while debugging. Instead static data is returned so that it may be used for debugging purposes and further development of this code and code that uses the solution.

For now I have added an extra boolean to my if() sentences checking if System.Diagnostics.Debugger.IsAttached, but I would prefer to not mess up my code like that. Would be better to trick the compiler to always answer true on System.Diagnostics.Debugger.IsAttached as if we were always debugging and then turn this off later and recompile for dependent projects when this is not needed any longer.
0
AndyAinscowFreelance programmer / ConsultantCommented:
Ah, I think I understand.
You could use the #if to turn code sections on and off.  There is also a /define compiler option so you can have two compiler options eg. RELEASE and your customised RELEASE_STATIC, the first is the default release version, the second defines your custom flag to turn code blocks on and off.

https://msdn.microsoft.com/en-us/library/4y6tbswk.aspx
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

Jacques Bourgeois (James Burger)PresidentCommented:
Defining compilation constants as explained in Andy's link is useful if you need to do it in only one or two classes and do not have to change things on and off very often.

If however you want to have something that works on the whole project, there is a simpler approach. Here are the steps.

At the top of the code window, in the drop down where you have Debug and Release, select the Configuration Manager.

In the upper left drop down of the manager, create a New configuration, give it a name (let's call it Special) and copy the the settings from your Release configuration.

Once this is done, you have 3 ways of compiling your application.

To setup Special, go into the project's Properties Window, go in the Build tab and select the Special configuration at the top. In the Conditional compilation symbols, define one as SPECIAL=true.

Now, in your code, everywhere you where working with System.Diagnostics.Debugger.IsAttached, replaced your condition with something like the following, uppercases being the standard for conditional compilation constants:

#if SPECIAL
            // YourCode
#endif

When you select SPECIAL as the configuration at the top of the code window, the compiler will compile that code.

But if you select any other configuration (Release or Debug) that does not has the SPECIAL compilation constant defined, its value is seen as False, and the piece of code in the #if will not compile. You can see it in the code window because it is grayed out in the configurations in which it won't compile.

Compiling with the Release configuration gives you an application that does not contain your extra code, while compiling with the Special configuration does. 2 Versions of your application, same source code.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AndyAinscowFreelance programmer / ConsultantCommented:
@James
>>If however you want to have something that works on the whole project, there is a simpler approach.

Erm, your 'simpler' approach is what I suggested.  Two configurations for compiling with a flag set at compile time available for the complete set of files.
0
Jacques Bourgeois (James Burger)PresidentCommented:
@Andy

Yes you suggested conditional compilation, but you did it through a compiler option, something that, in my experience, very few programmers use because most of these can be set more easily through the project's properties.

And the link you gave show how to define the options in the code, which is a pain when you need to do it in many files, when you have to change the values often, and/or when you have many configurations with different combinations of values for the same options.

I simply wanted to point to a third way of doing it, the one I almost always see when reviewing code. And add a more complete idea of how to use it in code, with a brief example that is not confusing as the one in your link. It can lead one to think that the thing is always used in combination with DEBUG.
0
AndyAinscowFreelance programmer / ConsultantCommented:
The link I gave also has a remark concerning the /define (mentioned in the comment) which links to :
https://msdn.microsoft.com/en-us/library/0feaad6z.aspx

Having said that I have looked and seen that Microsoft has changed things since the last time I used this functionality, admittedly quite some years ago.  Previously one could see the complete compiler command line on a separate tab on the project properties - now that is hidden, one only sees the option to enter the custom defines in a textbox.
0
käµfm³d 👽Commented:
Rather than littering your code with #if compiler directives, if you can ensure that your method return void, then you can use the Conditional attribute. It functions exactly the same, but it has the benefit that your code is more fluid and "natural". Compiler directives, IMO, are jarring to the typical code layout. The Conditional attribute has the benefit of being removed from the compiled assembly if the symbol given to Conditional is not defined, yet remain a normal construct that is already in your code:  a function call.

Do note:  It is important that your method return void. If your function has a return type other than void, then you must use the #if syntax.

e.g.

[Conditional("DEBUG")]
private void DiagnosticLog(string message)
{
    Console.WriteLine(message);
}

private static void Main(string[] args)
{
    DiagnosticLog("app start");

    Console.WriteLine("1 + 2 = " + (1 + 2).ToString());
}

Open in new window


In the above, you would only see the "app start" message if the application were compiled with a DEBUG compilation symbol. It woks the same as if you did #if DEBUG. The call to DiagnosticLog will be stripped out of the code during compilation if the symbol is not defined. It's a slightly cleaner syntax, IMO.
0
Jacques Bourgeois (James Burger)PresidentCommented:
The Conditional attribute is possibly the best way to go when you need to remove complete methods. But in my experience, it's not often that I had to do that. I use conditional compilation very often, and almost always end up with situations where it is not convenient.

The #if has 3 advantages over it.

The first one is that it can be applied to only part of a method. Often, a #if will deal with only one or two lines. Creating methods for these situations would be overkill.

It also has the possibility of having a #else, which is also something that often happens with conditional compilation. Having to create 2 methods with different attributes to do so would also, in my opinion, be overkill, and make the code less fluid.

The editors gray out code that is not compiled with the configuration that is currently selected. This makes it automatic and thus easier to see what will really be there when the application compiles. With the attribute, you have to be very careful of spotting the attribute in order to see that a method is there in the code but will not compile.
0
käµfm³d 👽Commented:
The first one is that it can be applied to only part of a method.
There's a fine line to this being advantage, I think. Consider the following:

namespace ConsoleApplication67
{
    class Program
    {
        private static decimal _account = 100;

        static void Main(string[] args)
        {
            decimal toDebit = 10;
            decimal balance = Withdraw(toDebit);
        }

        private static decimal Withdraw(decimal amount)
        {
            bool accountHasFunds = CheckThatAccountHasFunds();

            if (accountHasFunds)
            {
#if DEBUG
                DebitAccount(amount);
#endif
            }

            return _account;
        }

        private static bool CheckThatAccountHasFunds()
        {
            return (_account > 0);
        }

        private static void DebitAccount(decimal amount)
        {
            _account -= amount;
        }
    }
}

Open in new window


Oversimplified example, but it should stress the importance of care in using that functionality in such a manner.
0
Jacques Bourgeois (James Burger)PresidentCommented:
Most of the time, code for debugging is just adding a few lines of code that are not there in release, something like logging information that is not logged in normal application use, using a different path or connection string for test data or server, changing the value of a constant.

It is usually not something that apply to a simple call to a method. And as I said sooner, in such a situation, the Conditional attribute is probably the best thing.
0
itniflAuthor Commented:
Thank you gentlemen, all your solution suggestions were highly valued.
0
AndyAinscowFreelance programmer / ConsultantCommented:
@Kaufmed.
I'm having trouble thinking about how to use your suggestion (turning complete functions on/off rather than isolating blocks of code with #if, #else, #endif ) for this case - using static data for development/testing rather than 'real' data.  Can you give a quick air code / logic of how you would do that.
0
käµfm³d 👽Commented:
@Andy

Are you referring to something other than what I posted above?
0
AndyAinscowFreelance programmer / ConsultantCommented:
@kaufmed
The question as I understand it is about how to supply a default/standard set of data under certain conditions, at other times to use 'real' data.  I just can't see an easy way to do that by turning complete functions on/off via compilation - which is what your suggestion refers to.

ps.  Your example above doesn't change the source, it just runs an action automatically on what is provided.

pps.  Having written that a possible but rather ugly way has come to mind.

[Conditional("STATIC_DATA")]
private void ProvideStaticData()
{
    //generate the standard data
}

xxx()
{
  //read data from database
  //fill with actual sales values

//now throw all the above away should the following function exist
  ProvideStaticData();
}
0
käµfm³d 👽Commented:
The question as I understand it is about how to supply a default/standard set of data under certain conditions, at other times to use 'real' data.
OK. I read this as a logging question. But I read things too fast a lot of the time. You could probably do this with some static variables, but that would very hacky, and potentially error prone, I think. The #if in this case is probably both safer and cleaner.

Your example above doesn't change the source,
I agree, but maybe I don't understand what you are saying.
0
AndyAinscowFreelance programmer / ConsultantCommented:
@kaufmed
This is from the follow up comment to the question, providing clarifying information about the task in hand:
Yes, my code is written to check for it and bypass data collector tasks that are not available while debugging. Instead static data is returned so that it may be used for debugging purposes and further development of this code and code that uses the solution.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.