My Get-Things-Done Strategy

§ March 16, 2011 05:42 by beefarino |

Of all the changes I’ve made for self-employment, building up a system for getting and staying organized has had the most impact.  I’m a student of psychology, and I’m well aware of my mental limits for holding information.  I’m also a natural scatterbrain so … oh look a bird...  Anyway, the quicker I can get something out of my head and into a safe place, the more likely it is to get done.  So I’ve globbed several systems into my get-things-done process.

If you’re not familiar with the concept of a tickler file I suggest you watch this short video.  The system is genius, and rather than go into the details I’ll just say that this has saved my hide more times than I care to admit.

Another huge part of my get-things-done routine has been to use a personal wiki as a way to empty my brain and keep track of what I do during the day.  My wiki of choice is tiddlywiki because it requires no server and is highly customizable, and I use Dropbox as a way to share/backup the wiki as I roam the universe.  The pomodoro time management technique keeps me on task during the day, and I’ve integrated a pomodoro timer and task tracker into my wiki’s journal feature:

image

Finally, I tend to carry a hipster PDA on a lanyard around my neck when I’m away from the keyboard.  Anything that I need to remember, that I think is interesting, or that I’m afraid I may forget gets jotted down on a card.  When I’m back at my desk I process the cards.  If the card indicates something date sensitive, I just drop it into the appropriate of the 43 folders; if the card is a project idea, it goes into the wiki.

Not terribly technical or fancy, but it works like a champ and, most importantly, it’s easy to do and doesn’t get in my way.



Marking One Year of Independence

§ March 16, 2011 05:38 by beefarino |

imageToday is the one year anniversary of my move into self-employment. 

The motivation to go out on my own was to improve my perspective on career and life.  For a long time I defined myself by the work I did – to turn a phrase, my living was my life.  One of my goals for this first year was to separate those two things, and I think I’ve done an excellent job of that.  In the past year I’ve been able to earn a decent living while volunteering over 100 hours at my kids’ school, managing several open-source projects, and speaking at eight different technology venues.  I’m spending better quality time with my family, and we are all noticeably more happy and content with our life together.

My focus for this first year was internal, to steer myself to the life I want to live.  Now that I’m feeling comfortable in this skin, this next year will focus on business growth.



StudioShell and the Debugger

§ March 15, 2011 05:12 by beefarino |

creepybugOne of the more tantalizing potentials in StudioShell is using it with the Visual Studio debugger.  This post will describe some of the features that are currently available. 

The debugger features are accessible at the path dte:/debugger.  A quick call to get-childitems shows how the functionality is broken down:

§ DTE:\debugger>ls Container: PSDTE::dte:\debugger Name ---------- ---- d+ < Breakpoints d < DebuggedProcesses d < LocalProcesses

There are two major subcategories of debugger features exposed through StudioShell: breakpoints and processes.

Breakpoints

StudioShell lets you add, remove, and modify breakpoints from script using the standard item cmdlets.  Here is a simple example that adds a breakpoint to line 25 of Program.cs (the ` line-continuation is used for readability):

new-item -path dte:/debugger/Breakpoints ` -file program.cs -line 25

There is also a condition parameter that causes a debug break for a specific condition, such as when the local variable “v” is less than 65:

new-item -path dte:/debugger/Breakpoints ` -file program.cs -line 25 ` -condition "v < 65"

That’s really the tip of the iceberg – breakpoints are very dynamic beasts.  In fact, I had no idea the extent to which you can customize breaking into the debugger until I started researching the Debugger node of the dte: drive.  To see all of your options, type:

get-help -path dte:/debugger/breakpoints new-item

You can remove breakpoints using the remove-item cmdlet; this example removes all breakpoints in the Program.cs file:

ls dte:/debugger/breakpoints ` | where{ $_.file -match 'program.cs' } ` | remove-item

You can also disable and enable breakpoints using the clear-item and invoke-item cmdlets, respectively:

$bkpts = ls dte:/debugger/breakpoints; # disable all breakpoints with a hitcount > 1 $bkpts | ?{ $_.currenthitcount -gt 1 } | clear-item; # enable all breakpoints in the Program.Main function $bkpts | ?{ $_.functionName -match 'Program.Main' } ` | invoke-item;

Debugged processes

When you start the debugger, the debuggedprocesses node of the dte: drive springs to life.  This node contains a list of all processes currently hooked by the debugger, so naturally its contents vary depending on what startup projects you have specified in your solution:

§ DTE:\debugger\DebuggedProcesses>ls Location: PSDTE::dte:\debugger\DebuggedProcesses Available Operations: d < ID Name ---------- -- ---- d < 4988 DemoSolution.vshost.exe

The DebuggedProcesses node doesn’t support many operations; it is simply a reflection of the current debugger state.  In fact, the only things you can do at this node is get-item (to fetch a lightweight process object) and set-location to enter a debugged process and start snooping around the threads:

§ DTE:\debugger\DebuggedProcesses>cd .\DemoSolution.vshost.exe § DTE:\debugger\DebuggedProcesses\DemoSolution.vshost.exe>ls Location: PSDTE::dte:\debugger\DebuggedProcesses\DemoSolution.vshost.exe Threads for Process: DemoSolution.vshost.exe Available Operations: d < Frozen Alive Thread ID Name ---------- ------ ----- --------- ---- d < * 3560 3560 d < * 1980 1980 d < * 464 vshost.RunParkingWindow d < * 5464 .NET SystemEvents d < * 5300 5300

Threads

Like processes, thread operations are limited to exploration: get-item will fetch a lightweight thread object for the specified thread, and set-location will drill into the stack for each thread:

§ ...\DemoSolution.vshost.exe>cd 5300 § ...\DemoSolution.vshost.exe\5300>ls Location: PSDTE::dte:\debugger\DebuggedProcesses\DemoSolution.vshost.exe\5300 Frames for Thread: Available Operations: d < Language Location Name ---------- -------- -------- ---- d < C# DemoSolution.Program.Main Current d < [Native to Managed Transition] Frame1 d < [Managed to Native Transition] Frame2 d < System.AppDomain.ExecuteAssembly Frame3 d < Microsoft.VisualStudio.HostingProcess... Frame4 d < System.Threading.ThreadHelper.ThreadS... Frame5 d < System.Threading.ExecutionContext.Run Frame6 d < System.Threading.ExecutionContext.Run Frame7 d < System.Threading.ThreadHelper.ThreadS... Frame8 d < [Native to Managed Transition] Frame9

Stack Frames

Stack frames are named by their current index, with the topmost frame always named “Current”, the next frame named “Frame1”, and so on.  Each frame is a container, so you can set-location again into a specific stack frame to probe further:

§ ...\DemoSolution.vshost.exe\5300>cd current § ...\DemoSolution.vshost.exe\5300\current>ls Container: PSDTE::dte:\debugger\DebuggedProcesses\DemoSolution.vshost.exe\5300\current Name ---------- ---- d < Arguments d < Locals

Which brings us to the meaty part…

Locals and Arguments

Once you navigate into a specific stack frames, you can access the local variables and arguments at that frame:

§ ...\5300\current>ls locals Location: PSDTE::dte:\debugger\DebuggedProcesses\DemoSolution.vshost.exe\5300\current\locals Available Operations: d < Value Type Name ---------- ----- ---- ---- < {string[0]} string[] args < 77 int v < "This is a v... string value

Once you’re this deep in the path hierarchy, you’re able to do some pretty neat things.  These locals values can be modified from the console, just like they can be modified from the locals or immediate window:

§ ...\5300\current>set-itemproperty -path v ` -name value -value 125 § ...\5300\current>ls Location: PSDTE::dte:\debugger\DebuggedProcesses\DemoSolution.vshost.exe\5300\current\locals Available Operations: d < Value Type Name ---------- ----- ---- ---- < {string[0]} string[] args < 125 int v < "This is a v... string value

Of course, being accessible in PowerShell means you gain so much more, such as the ability to search the stack for specific variables and values:

1 § ...\5300>$v = ls | ` #get all stack frames 2 join-path -child 'locals' | ` #create paths to local variables on each stack frame 3 ls | ` #list all locals... 4 where { $_.name -eq 'v' }#.. named "v" 5 § ...\5300>$v | select pspath,value 6 7 PSPath Value 8 ----- ----- 9 ...\Current\locals\v 123 10 ...\Frame1\locals\v 124 11 ...\Frame2\locals\v 125

This looks complex, but it simple when you break it down. 

  1. On line 1 we use get-childitems at the thread node to get a list of all stack frames. 
  2. Line 2 appends the node “locals” to each stack frame path, resulting in a list of StudioShell paths for the local variables at each stack frame. 
  3. Line 3 performs a get-childitems on each of these paths, resulting in a list of all locals across all stack frames. 
  4. Line 4 selects those local variables with a name of “v”. 
  5. Line 5 creates a simple report of the local variable path and its value. 

The result is the history of the values of variables named “v” at every stack location.  This isn’t something you can easily get from the IDE alone.

Looking Ahead

Hopefully this gives you a few ideas.  I’m still exploring this space in StudioShell, but I find myself giddy with ideas. 

One that’s got me drooling is the notion of replacing the breakpoint condition string with a scriptblock, enabling me to break at specific code locations in response to WMI events for instance.  Not sure how I will accomplish this yet – the condition doesn’t appear to be pluggable, but I’m sure there is something that can be done.



StudioShell 1.0.1

§ March 11, 2011 09:32 by beefarino |

imageA maintenance release of StudioShell is now available on codeplex.

This release contains several fixes to the initial release of StudioShell:

  • Tab completion and history walking have been hardened in the console.
  • Solution Folders are now recognized as containers in the console.
  • Solution Modules are now unloaded automatically if the “AutoManageSolutionProfiles" setting is enabled.
  • The PowerShell AllUsersCurrentHost is no longer loaded.  The “LoadPowerShellProfiles" setting now only applies to your Current User profile script located at ~\documents\windowspowershell\profile.ps1.
  • Data panes (visualizations) now reliably appear in VS2010. 
  • The default console window now consumes all available client area of the tool window at startup.
  • Project item properties are now available in the path hierarchy.  For example, the path dte:/solution/projects/MyProject/Program.cs/properties will contain all the item properties for the Program.cs file, such as the Build Action, full path, etc.
  • The locals and arguments nodes under the stack frame tree now add missing quotes to strings when you attempt to set an expression value.  In the 1.0 release, you could set expression values
  • The default PowerShell module path is now added to the process environment when StudioShell is started.

Have fun, and as always please note any issues or feature requests using the Issue Tracker.