Computers, Programming, Technology, Music, Literature

Archive for July 2013

Play a sound when a breakpoint is hit in Visual Studio

with one comment

 

This article was originally published for www.prowareness.com and could be located at http://www.prowareness.com/blog/play-a-sound-when-a-breakpoint-is-hit-in-visual-studio/.

 

Alright, previous post showed you how you could put a Stopwatch while debugging an x64 application in visual studio, now let’s see how you could play a sound when you hit a breakpoint.

This tip is very handy when you are debugging a long running process (say a data import, or third party service call of some sorts), and you just don’t want to stare at the screen like hungry cat. Or you are working on two different workstations and you want a ding or a buzz or a chime when you hit a breakpoint; whatever the reason is, just want to be notified by a sound.

To enable this feature in Windows 7, follow the steps below.

Start –> Type in Change system sounds –> Program Events: –> (scroll down to) Microsoft Visual Studio –> Breakpoint Hit

Select a .wav file under Sounds:

That’s it. Try a sample app for yourself, put a breakpoint and relish.

image

image

image

Written by gmaran23

July 23, 2013 at 9:13 pm

x64 Application Debugging: Edit and Continue not allowed, but you need a Stopwatch

with one comment

 

This article was originally published for www.prowareness.com and could be located at http://www.prowareness.com/blog/x64-application-debugging-edit-and-continue-not-allowed-but-you-need-a-stopwatch/.

Here’s a scenario. You are debugging some 64 bit code to improve performance, say it’s a pretty long running method with a bunch of IO operations and conditional loops, something like shown in Listing 1. You have started a debugging session or attached a running process to your solution, and when you try to Edit the code to insert a Stopwatch, you’d get the error message: Changes to 64-bit applications are not allowed. This feature to Edit the code and continue debugging for a 64 bit application is not supported by CLR (though a recent version supports it). You might try changing the project’s target platform temporarily to Any CPU or x86, but let’s say you are debugging a huge project, and in order to get to the code snippet where you want to put a Stopwatch, it takes half an hour or you just don’t want to re-enter a new debugging session because you have a good retrospective and trace in the current debugging session.

            viewModel.FunctionList = functionManager.ListAll();

            foreach (var item in viewModel.FunctionList)
            {
                item.FunctionName = MultiLingualHelper.GetCustomerText(item.FunctionName, item.FunctionName, "CDT");
            }

            viewModel.TeamList = teamManager.ListAll();

            foreach (var item in viewModel.TeamList)
            {
                item.TeamName = MultiLingualHelper.GetCustomerText(item.TeamName, item.TeamName, "RMOCDT");
            }

            viewModel.DepartmentManagerList = departmentManager.ListAll();

            foreach (var item in viewModel.DepartmentManagerList)
            {
                item.DepartmentName = MultiLingualHelper.GetCustomerOrSystemText(item.DepartmentName, item.DepartmentName, "RPDCDT");
            }

Listing 1

imageFig 1

How would you put a Stopwatch to measure what time a snippet takes in the middle of an x64 debugging session?

Okay it could be done in 2 or 3 very simple steps, I will describe them one by one.

  1. You could set and query properties, fields and methods of an object via the Immediate Window; but you could also create a new object for the current debugging session via the Immediate Window.
  2. You could query a property or a field via a Watch Window; but you could also call some methods via the Watch Window.
  3. You could break at a breakpoint; but you could also access properties or an object field when a breakpoint is hit.

Point 3, might be optional, but you may like to use it. Anyways that’s the gist, let’s see them in action.

Listing 2 shows a typical Stopwatch code when you want to measure the time took to execute the method FooBar(). We will have to separate the initialization to be a part of the Immediate Window, and all other method, property calls to be a part of the Watch window.

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            FooBar();
            sw.Stop();
            MessageBox.Show(string.Format("FooBar() took {0} seconds to run.", sw.ElapsedMilliseconds / 1000));

Listing 2

 

#1. Create a Stopwatch object named stopWatch1 inside Immediate Window. Just one line, and hit Enter.

image

Fig 2

var stopWatch1 = new System.Diagnostics.Stopwatch();

Listing 3

#2. Now, that our stopWatch1 is created, let’s pull up a Watch Window, and try to access the commonly used properties and methods. Couple of lines below, copy and paste or type them in.

image

Fig 3

stopWatch1.Reset();
stopWatch1.Start();
stopWatch1.Stop();
stopWatch1.ElapsedMilliseconds
stopWatch1.ElapsedMilliseconds/1000

Listing 4

You are pretty much done here if you are just stepping through the code via F11 or F10, all you should do is, before entering the code region that you want to profile, call the stopWatch1.Start() via the Watch Window – Hit the green refresh icon, and soon as you have started the stopWatch1, continue stepping through or steping over, or continue execution to another breakpoint; but once the critical code is executed, you should go back to the Watch Window, and call the stopWatch1.Stop() method (i.e. Hit the green refresh Icon next to stopWatch1.Stop()). After you have stopped the stopwatch, the values for ElapsedMilliseconds would be refreshed automatically, if not, hit the green refresh icon next to it.

image

Fig 4

That’s how I did it first, and then I thought about breakpoint options, came up with Point 3.

#3. Create a break point (we will call this, breakpointX), after the critical region (or the code snippet whose time you want to measure). Right click on breakpointX, and select When Hit…

image

Fig 5

Make sure Print a message: is checked and Continue execution is unchecked.

image

Fig 6

In the Print a message: text box, type in the below code.

Elapsed Seconds: {stopWatch1.ElapsedMilliseconds/1000} Elapsed Milliseconds: {stopWatch1.ElapsedMilliseconds}

Listing 5

Now once this breakpointX is hit, a message will be printed to the Output Window.

imageFig 7


That’s how you do it. Or to say the least, that’s how I figured to do it. If there are better options, please let me know. In my next post, I will show you how to play a sound when a Breakpoint is hit.

Written by gmaran23

July 23, 2013 at 1:38 pm

What happens when you set the Path environment variable – Part 2

with one comment

This article was originally published for www.prowareness.com and could be located at http://www.prowareness.com/blog/what-happens-when-you-set-the-path-environment-variable-part-2/.

 

Part 1 of the article focussed on reviewing, editing the Path via System Properties dialog, via the Registry Editor, via the Command Prompt. Let’s look at how to do the same thing via the .Net APIs, and a couple of workarounds when you want to add a path that is exceeds the 2047 chars limit.

4. Updating Path via the APIs

In the .Net framework Environment.SetEnvironmentVariable method allows you to make changes to the Path environment variable at a Process level, User level, and Machine level. Setting the Path variable at the Machine level is equivalent of using the Edit System Variable dialog box and the SETX command. Setting the Path variable at the Process level is equivalent to using the SET command in a command prompt, where only that cmd.exe has an updated copy of the Path variable.

Code samples at the MSDN are ample enough to get you started.

Also, as an alternative, you could directly read and write to the Path string aforementioned registry location.

We have seen instances above where a process that was spawned before the edit of the Path variable, not reflecting the updated Path till it was restarted. The solution here is: If you want the command processor and other windows processes to have an option to read update the Path variable, you could broadcast a WM_SETTINGCHANGE message, so the command shell and other processes would pick the updates. Broadcasting a WM_SETTINGCHANGE message does not mean all the applications running in the computer would pick up the Path variable changes. It just means that the process or the application that modified the Path variable was gracious enough to notify other processes about the change. If you are building an application that is required to have a copy of the updated Path variable then you should write an event handler to trap the Windows message broadcasted with WM_SETTINGCHANGE and reload the Path variable from the registry key.

Broadcasting a WM_SETTINGCHANGE message with “Environment” parameter:

public enum SendMessageTimeoutFlags : uint
    {
        SMTO_NORMAL = 0x0000
        ,
        SMTO_BLOCK = 0x0001
            ,
        SMTO_ABORTING = 0x0002
            , SMTO_NOTIMEOUTIFNOTHING = 0x0008
    }

    public class SendWindowsSettingChangeMessage
    {
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);

        private static void NotifyWindowsAboutSettingChange()
        {
            IntPtr HWND_BROADCAST = (IntPtr)0xffff;
            const uint WM_SETTINGCHANGE = 0x001A;
            UIntPtr result;
            IntPtr settingResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, (UIntPtr)0, "Environment", SendMessageTimeoutFlags.SMTO_NORMAL, 10000, out result);
        }
    }

 

Trapping a WM_SETTINGCHANGE message:

    public class TrapWindowsSettingChangeMessage : System.Windows.Forms.Form
    {
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            const uint WM_SETTINGCHANGE = 0x001A;
            switch ((uint)m.Msg)
            {
                case WM_SETTINGCHANGE:
                    {
                        //attempt to reload the Path variable from the registry
                        break;
                    }
            }
            base.WndProc(ref m);
        }
    }


Another not so elegant, archaic kind of solution would be to run a background listener every couple of some duration that would directly read the registry value of Path and refresh itself.

string keyName = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment\";
string existingPathVariable = (string)Registry.LocalMachine.OpenSubKey(keyName).GetValue("PATH", "", RegistryValueOptions.DoNotExpandEnvironmentNames);

 

Overcoming the 2047 chars limitation

If you would like to circumvent the 1024 chars limitation, and want to add more directories to your Path variable, you could consider using the 8dot3 naming format for all commonly used windows locations like Program Files, Favorites, etc.

For instance, a Path variable like this

1. C:\Program Files\Common Files\Microsoft Shared\Windows Live;

2. C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;

could be shortened to

1. C:\PROGRA~1\COMMON~1\MICROS~1\WINDOW~2;

2. C:\PROGRA~2\COMMON~1\MICROS~1\WINDOW~2;

You could obtain the 8dot3 naming using the DIR command with the /X and /-N switches.

clip_image002

Or you could create all commonly used tools/applications under one folder and add that folder to the Path variable. This is an additional effort, but you get use a lot more shortcuts for your favourite programs. What I do, is create a folder called m.Shortcuts and append the path of m.Shortcuts (in my case, it is – C:\Windows\System32\m.Shortcuts) to the Path variable.

clip_image004

That’s about it. Besides the Path variable and other System Environment Variables displayed in the System Properties dialog, there are a couple of other System wide environment variables that are created for every user – documented here, here and here.

 

Disclaimer: All these facts are explored based on tests ran on a Windows 7 x64 Enterprise. If you find any incorrect content, please let me know.

Written by gmaran23

July 5, 2013 at 4:39 pm

What happens when you set the Path environment variable – Part 1

with one comment

 

This article was originally published for www.prowareness.com and could be located at http://www.prowareness.com/blog/what-happens-when-you-set-the-path-environment-variable-part-1/.

 

PATH

When you want to update the Path environment variable, there are a handful ways to do it: via the System Properties GUI; via the registry; via the command prompt; via the Windows APIs. However you do, whenever you set or update the Path variable, there’s a couple of checks that happen and a couple of background messages that are required to be broadcasted to all processes running on the computer, indicating the change. Let’s review our options one by one.

 

1. The recommended way is to use the System Properties GUI

You could do a Ctrl + Break, or you type sysdm.cpl (Control Panel Applet) on the Run dialog box, or you type Advanced System Settings on the Start Menu’s search box. Finally you open the System Properties dialog box. Then, Advanced –> Environment Variables –> System Variables –> Path

clip_image002

Now, when you try to edit it, the regular way, you wouldn’t have any problems. All the directory paths you put in separated by a semi colon (;) would work just fine.

And whenever you had to execute a program without typing the full path, the operating system or the command shell would search the list of directories specified in the Path environment variable and would invoke that program for you. But let’s say you are someone that has lot of development tools installed on your computer, and you wanted them all to be accessible via the Run dialog box or the command prompt (and do not want to see the message “……” is not recognized as an internal or external command, operable program or batch file) , then you might find yourself running in to a limit of 2047 chars, on the Edit System Variable dialog. Although there is a theoretical limit of 32767 chars, you can’t practically hit that limit with the Path variable because, there are other system environment variables that share this 32767 space – which we call a Environment block. Read more here.

image

There are some workarounds that you could use, that I will discuss later in Part 2 of the article.

Beside the 2047 chars check, the Edit System Variable dialog box does not really do any other fancy checks. It pretty much allows you to type anything from your keyboard and updates the registry key under the HKLM hive. And you are allowed to update the Path variable, just like that.

After updating the Path variable, at this point of time, if you already had a command prompt open (or any other process for that matter), the new Path variable you have just set via the Edit System Variable dialog will not be reflected till you restart the command prompt (or the processes). This is the expected behaviour and it is by design because, when a process is spawned it obtains a copy of all the environment variables from its parent (and hence the Path variables) and accesses them on every Read and Write request.

Sometimes, in order to ensure system integrity i.e. i.e. to have all running processes have the updated Path variable; whenever you change the path variable it is required to log off the user session and log in back again.

2. Updating Path via the registry key

This is a String Value named Path under the registry location

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

 

Open the registry location and edit it accordingly. The limit for this String Value is limited only by the maximum value that the registry editor allows you to enter for a String Value.

Updating the registry directly, requires a log off and log on for that particular user session. Unlike the Edit System Variable dialog, which did not enforce a restart of the user session (log off and log on), updating the registry key directly, does. So when you update the Path variable via the registry directly, and restart all your programs, and command prompt windows, and batch files, you would not see the updated Path value unless you restart the user session by a log off and log on or a machine reboot. The screenshot below shows the Edit System Variable dialog and the registry string showing the same value, however a new instance of command prompt still referring to an old value.

clip_image004

As it is evident from the registry path, there is no separate Path variable (or any other environment variable) for the 64 bit processes and the 32 bit processes (Wow6432Node) on a x64 based Windows.

3. Updating Path via the Command Prompt

Setx command makes permanent changes to any environment variables. The below command updates the Path variable just like the Edit System Variable dialog, but this could be very useful when writing batch files.

SETX PATH "%path%;C:\SomePath"

 

In case, you do not want to make permanent changes to the Path variable, however for a particular instance of the command prompt or for a single batch file you want some values added to the Path variable (only during the command prompt’s lifetime), then you could use the regular SET command as below:

SET Path=%Path%;C:\SomePath

 

This SET only updates the Path variable for the current session, i.e. the current command window. And when you shut down that command prompt window, the changes you made to the Path variable will be lost, as desired.

The follow up article Part 2 will focus on updating the Path variable via the APIs, broadcasting windows settings change message to the operating system, and will discuss a few workarounds to overcome the size limit of 2047.

 

Disclaimer: All these facts are explored based on tests ran on a Windows 7 x64 Enterprise. If you find any incorrect content, please let me know.

Written by gmaran23

July 5, 2013 at 4:35 pm