Martin Hinshelwood's Blog

A Scottish dyslexic software developer: Team System MVP, .NET architect, developer, evangelist, technology enthusiast and multi-dimensional free thinker
posts - 322, comments - 385, trackbacks - 67

My Links

News

Get illustrations like mine

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Get Microsoft Silverlight

Subscribe

Personal

Accreditation

Stats

Twitter












Tag Cloud

Article Categories

Archives

Post Categories

Image Galleries

Blogs I read

Blogs of Friends

Multi-Dimentional Free Thinking Bloggers

Personal

Projects

VSTS

Tuesday, January 06, 2009

Learning more about Visual Studio 2008

Well, that's me well and truly back from my holidays, a nice relaxing couple of weeks spent at home with my family.

As a kind of New Years present, Microsoft has released a free learning initiative for those of you that are or will be using Visual Studio 2008. I am taking it myself as a way to make sure that I have not missed anything :)

Sign Up for the MSDN Ramp Up Program's Visual Studio 2008 Track

posted @ Tuesday, January 06, 2009 8:16 AM | Feedback (0) | Filed Under [ Team System Software Development ]

Monday, December 15, 2008

Microsoft Answer for the end-user

Up until now the only avenue for your average Vista user for support was to trawl the MSDN Forums, Technet Forums and the Support site for some elusive piece of information that is buried among all that technical BS that we teckies like to call help.

All that has now changed with the addition of the Answers forum!

This will be a no nonsense, non technical forum for real users to get real answers. The forum will follow the format that he user sees in the control panel of Vista so here are the topics:

Windows Vista Forums

Tap into the expertise and enthusiasm of Windows Vista customers and Microsoft support professionals.

Windows Updte for Windows Vista
Windows Update

Automatically keep software up-to-date

Windows Vista Hardware and Drivers
Hardware and Drivers

Add hardware, update drivers

Wireless, Internet, and Networking for Windows Vista
Wireless, Internet, and Networking

Connect to a network

Windows Vista Security and Privacy
Security and Privacy

Adjust settings, manage user accounts

Improve Windows Vista Peformance
Improve Peformance

Run Windows Vista better, faster

Install, Upgrade, and Activate Windows Vista
Install, Upgrade, and Activate

Troubleshoot Windows Vista installation

Windows Vista Sound and Media
Sound and Media

Work with music, pictures, video

Windows Vista Programs
Programs

Internet Explorer, Windows Mail & others

Windows Vista Gaming
Gaming

Install, troubleshoot, set parental controls

Windows Vista Appearance and Personalization
Appearance and Personalization

Add gadgets, adjust screen resolution

 

Now, for those Blue badge holders and us MVP’s that have been asked to moderate there are strict rules around making sure that both the Questions and the Answers are non threatening and non technical.

These forums are specifically targeted at Vista, but if they are successful, there may be more forums added in the future. Maybe for things like Sharepoint and Office, and it may include many other products (deliberately vague).

 

Lets get Answering…but remember, no techno-babble!

 

posted @ Monday, December 15, 2008 6:31 PM | Feedback (1) |

Does test-driven development speed up development?

If only I could be as eloquent as Scott. His recent post on “” really gets to the crux of an endemic problem in the Software Development industry, especially in companies for whom Software Development is not their core business.

Test-driven development decreases complexity, improves the incremental adaptability that software product development depends on, astronomically reduces the amount of rework that destabilizes schedules, and reduces the unrecognized design flaws that decrease productivity after the initial implementation phase.

Test-driven development supports flow. The software development industry at large is years away from recognizing that flow rather than efficiency is what creates giant leaps in productivity. Nonetheless, it works, and it's supported by the production physics used by industries that are well ahead of software development in product development and production maturity and optimization.

Scott Bellware on

This is a must read for any Software Professional… unless you are already using TDD :)

posted @ Monday, December 15, 2008 2:55 PM | Feedback (0) |

Managing the “VSTS Developers” LinkedIn group.

n2381079695_7151

After making sending a “Call to Action” to my fellow Team System MVP’s I have added two managers to the VSTS Developers group I started on LinkedIn.

Thanks guys for giving up a little bit of your valuable time….

Hopefully, this will give members more information and a faster response time to requests…

posted @ Monday, December 15, 2008 11:51 AM | Feedback (0) |

Wednesday, December 10, 2008

Merry Christmas

With many people skipping off early for their holly bags, me included.. I thought I should send this out now…

Send your own ElfYourself eCards

Merry Christmas from the Hinshelwood family.

Technorati Tags: ,,

If you are having problems accessing or see a blank box, try (http://aka.zero.jibjab.com/client/zero/ClientZero_EmbedViewer.swf?external_make_id=cgijAPrn4DOVeeOU&service=sendables.jibjab.com&partnerID=ElfYourself). It is most likely a proxy problem…

posted @ Wednesday, December 10, 2008 4:21 PM | Feedback (0) |

Removing a dead Solution Deployment from MOSS 2007

If, like me, you tried to deploy a solution to Microsoft Office SharePoint Server 2007 and it ether failed or hung you will need to remove it somehow. But once the status has moved to “deploying”, if you receive an error like this:

Error: The web.config is invalid on this IIS Web Site: C:\Inetpub\wwwroot\wss\VirtualDirectories\search.xxx.xxx.biz80\web.config.

You will need to manually remove the job.

To do this, go to the Central Administration portal and under the “Global Configuration” section on the “Operations” tab select “Job Timer definitions”

image

This will take you to a massive list of all the scheduled and on demand jobs. Check down the list to find the job you want to kill, the Deployment operations will have “one-time” in the last column.

image

Click the title to bring up the job definition and status and you should have the kill switch readily available

image

Once killed you can check the deployments page and you will see that there is nothing trying to “deploy”.

 

posted @ Wednesday, December 10, 2008 2:32 PM | Feedback (0) |

Thursday, December 04, 2008

Live Framework

I have been getting very interested in the new Azure Services Platform and how I can use it to facilitate WPF development.

image

Imagine being able to launch a ClickOnce application from anywhere and for it to have exactly the same configuration and settings in all locations, or imagine being able to chat with other users of the application while you are using it.

This things have been relegated to large companies who can afford to support the infrastructure that you would need to run this. In fact, the only industry that I can think of that currently does this with applications is the Gaming industry. If you look at the capabilities of Xbox Live and think of all the cool things your users could achieve if the same communication and collaboration tools were available within even the simplest application.

For example, if I was to think of a couple of simple things that I would like the TFS Sticky Buddy to be able to do:

  • Central storage for configuration (single setup across multiple computers)
  • Chat with members of your team to be identified by linking your Team System login and email with you Live ID.
  • Presence information on those team members, or anyone you might need to interact with.

 

Coool…..

posted @ Thursday, December 04, 2008 2:12 PM | Feedback (0) |

SkyDrive: 25 GB of free online storage

SkyDrive25

Some of the new Windows Live Wave 3 services have gone live over the last couple of days. One of the best IMO is the SkyDrive services, updated to 25GB and with complete integration with other services like Photo Share, Connect to people

image

You can connect to your Facebook and LinkedIn contacts as well :)

image

A nice feature is the ability to link your live accounts so you can easily switch from your clever [yourname]@[yourdomain].com to your nasty [yourname]@live.com address.

image

As you can see from the menu structure, all of your services are all in one place, although some of those other services, OneCare for example, have not yet been updated as you can’t get back into the same bits… I am sure it will come…

The SkyDrive service has had a major overall and has a nice new home page as well as the integration with Live Photo and a whopping 25gb of space…

image

Here is a comprehensive list of all Windows Live services currently available with the exception of the fantastic Live Mesh which is still in beta.

 

Windows Live

  • Home
    Get a quick view of your world—e-mail, invitations, and what’s new with your network.

  • Profile
    Share your world online–your activities, your photos, and the people you know.

  • People
    Manage your contacts from Hotmail, Messenger, and Profile, all in one place.

  • Mail
    Get fast, easy, reliable e-mail from Hotmail, with more spam protection and plenty of storage.

  • Photos
    Post your favourite shots online in beautiful slideshows that only the people you choose can see.

  • Calendar
    Check your schedule, share calendars with others, and get reminders when you need them.

  • Events
    Plan your next event with customized invitations, a guest list, RSVPs, and a place to share online.

  • SkyDrive
    Store the files you need online and share them with the people you choose.

  • Groups
    Bring your team, club, or other group together with a webpage, calendar, and more.

  • Spaces
    Express yourself with your own customized webpage—add a blog, photos, videos, and more.

  • Family Safety
    Help protect your kids online, with customizable web filters and contact management.

  • Mobile
    Stay in sync from the road, with Windows Live on your web-enabled mobile device.

  • Downloads
    Download Windows Live Essentials—free programs for your PC, including Messenger, Mail, Photo Gallery, Movie Maker, Writer, Toolbar, and Family Safety.

  • Office Live
    Store and share your business documents online—it’s quick, easy, and free.

 

posted @ Thursday, December 04, 2008 10:18 AM | Feedback (3) |

Tuesday, December 02, 2008

TFS Event Handler v1.3 released

Updated and improved for Team System 2008.

vsts_thumb[2]

http://www.codeplex.com/TFSEventHandler

The TFS Event Handler makes it easier to notify users of changes to Work Items in Team Foundation Server. You will no longer need to add individual alerts to users.

It is developed in .NET 3.5 SP1 for Team Foundation Server 2008 and is deployed as a system service.

I have added support for groups. If you add a TFS group into the Assigned To drop down all members of that group will receive notifications! 

You will need to allow groups in your Assigned to list. Below is a snippet from me Bug work item type as it stands at the moment.

   1: <FIELD reportable="dimension" type="String" name="Assigned To" refname="System.AssignedTo">
   2:     <HELPTEXT>The person assigned to act on the bug, either to fix it or to verify the fix</HELPTEXT>
   3:     <ALLOWEXISTINGVALUE />
   4:     <ALLOWEDVALUES filteritems="excludegroups">
   5:         <LISTITEM value="[project]\Contributors" />
   6:     </ALLOWEDVALUES>
   7: </FIELD>

You can see on line 4 that there is a filter for excluding the groups from the list. If you are using TFS Event Handler v1.0 or v1.1 then you will need this line. If you install the new TFS Event Handler v1.3 then you will be able to remove that and start assigning work items to Groups.

Note: Although they will now get an email, the work item will not appear in their “My Work items” query. You may want to consider creating a Query for each Group.

The Alerts that you no longer need users to individually setup are:

  • A work item is assigned to you, or a group you are a member of.
  • A work item that is assigned to you, or a group you are a member of is, reassigned to someone else.
  • A work item that you created is assigned to someone else, or a group.

There is also a framework for creating and deploying your own event handlers that can do pretty much whatever you want. One of the shipped examples updates “Heat ITSM” whenever a work item that contains a Heat Id is changed.

posted @ Tuesday, December 02, 2008 11:08 AM | Feedback (3) |

Monday, December 01, 2008

Retrieving an identity from Team Foundation Server using only the display name

This is a lot harder than it sounds. At first you think there will be a built in option with the Read Identities method on the IGroupSecurityService Interface, but you would be wrong!

When capturing an event from Team Foundation Server you have access to a lot of information about the change, including the Display Name of the fields for Assigned To and Changed By.

But what if you allow Work Items to be assigned to groups! First, lets achieve that. Create a group called “Program Management” on a project and add it into the “Contributors” list. We have a group for each of the advocacy groups in the CMMI process.

Edit your “Task” work item definition (you can use the power tools process editor or just edit the XML) and alter the Assigned To field to be the following:

   1: <FIELD reportable="dimension" type="String" name="Assigned To" rename="System.AssignedTo">
   2:   <ALLOWEXISTINGVALUE />
   3:   <ALLOWEDVALUES>
   4:     <LISTITEM value="[project]\Contributors" />
   5:   </ALLOWEDVALUES>
   6: </FIELD>

Once you have updated your project you should be able to see all of the users as well as this new group displayed. If you were to assign a task to this group, how would you email everyone in that group so that they know they have been assigned something at all?

Well this needs a wee tweak of the TFS Event Handler  to handle this, I will be releasing the full in place code with the TFS Event Handler v1.3 drop, but you can download my little test app I used to get it all working.

[Download Project]

You can enter a display name of either a user or a group. And here is how it is done:

There is a little but of Active Directory lookup using a little method called GetUsername

   1: '' <summary>
   2: '' Retrieves a user's email address from Active Directory based on their display name
   3: '' </summary>
   4: Public Shared Function GetUsername(ByVal userDisplayName As String) As String
   5:     Dim ds As DirectoryServices.DirectorySearcher = New DirectoryServices.DirectorySearcher()
   6:     ds.PropertiesToLoad.Add("sAMAccountName")
   7:     ds.Filter = String.Format("(&(displayName={0})(objectCategory=person)((objectClass=user)))", userDisplayName)
   8:  
   9:     Dim results As DirectoryServices.SearchResultCollection = ds.FindAll()
  10:     If results.Count = 0 Then
  11:         Return String.Empty
  12:     End If
  13:     Dim values As DirectoryServices.ResultPropertyValueCollection = results(0).Properties("sAMAccountName")
  14:     If values.Count = 0 Then
  15:         Return String.Empty
  16:     End If
  17:     Return values(0).ToString()
  18: End Function

This retrieves the users sAMAccountName (or username) from Active Directory. Easy enough, and I already had it kicking about…

But in order to retrieve an identity that you are not sure is a group or a user, you will need to try to get the Group Identity first. This is because it is faster to wade through a maximum of 20 groups than potentially hundreds of users mentioned on the MSDN Forum answer below.

   1: Try
   2:            '----------------------------------------
   3:            Dim svr As New TeamFoundationServer(Me.uxTeamServer.Text)
   4:            Dim GroupSecurityService As IGroupSecurityService = CType(svr.GetService(GetType(IGroupSecurityService)), IGroupSecurityService)
   5:            '----------------------------------------
   6:            Dim CommonStructureService As ICommonStructureService = CType(svr.GetService(GetType(ICommonStructureService)), ICommonStructureService)
   7:            '----------------------------------------
   8:            ' Return App Group if you can
   9:            Dim pi As ProjectInfo = m_CommonStructureService.GetProjectFromName(Me.uxProject.Text)
  10:            Dim appGroup As Identity = (From i In m_GroupSecurityService.ListApplicationGroups(pi.Uri) Where i.DisplayName = Me.uxDisplayName.Text).SingleOrDefault
  11:            If Not appGroup Is Nothing Then
  12:                appGroup = m_GroupSecurityService.ReadIdentity(SearchFactor.Sid, appGroup.Sid, QueryMembership.Expanded)
  13:                WriteToLog(String.Format("Recieved identity for {0}", Me.uxDisplayName.Text))
  14:                WriteIdentity(appGroup)
  15:                Exit Try
  16:            End If
  17:            ' Not app group. Then return user is you can
  18:            Dim username As String = GetUsername(Me.uxDisplayName.Text)
  19:            Dim usrIdent As Identity = m_GroupSecurityService.ReadIdentity(SearchFactor.AccountName, username, QueryMembership.Expanded)
  20:            If Not usrIdent Is Nothing Then
  21:                WriteToLog(String.Format("Recieved identity for {0}", username))
  22:                WriteIdentity(usrIdent)
  23:                Exit Try
  24:            End If
  25:            '----------------------------------------
  26:            WriteToLog(String.Format("identity for {0} not found", Me.uxDisplayName.Text))
  27:  
  28:            '----------------------------------------
  29:        Catch ex As Exception
  30:            Me.uxResults.Items.Add(ex.ToString)
  31:        End Try

There is a lot going on here, but the first thing you need to do is retrieve the TFS objects that we will need to work with which include a TeamFoundationServer instance as well as an IGroupSecurityService and ICommonStructureService. You could use the WorkItemStore instead of the ICommonStructureService, but the WorkItemStore has a heavy performance hit for retrieving an instance.

   1: Dim svr As New TeamFoundationServer(Me.uxTeamServer.Text)
   2: Dim GroupSecurityService As IGroupSecurityService = CType(svr.GetService(GetType(IGroupSecurityService)), IGroupSecurityService)
   3: Dim CommonStructureService As ICommonStructureService = CType(svr.GetService(GetType(ICommonStructureService)), ICommonStructureService)

Next we need to try and retrieve the Identity of the group, if it is one.  The ICommonStructureService  has a method for listing all of the Groups available within a project, but for that you need the project name which in the demo is just entered.

   1: ' Return App Group if you can
   2: Dim pi As ProjectInfo = m_CommonStructureService.GetProjectFromName(Me.uxProject.Text)
   3: Dim appGroup As Identity = (From i In m_GroupSecurityService.ListApplicationGroups(pi.Uri) Where i.DisplayName = Me.uxDisplayName.Text).SingleOrDefault
   4: If Not appGroup Is Nothing Then
   5:   appGroup = m_GroupSecurityService.ReadIdentity(SearchFactor.Sid, appGroup.Sid, QueryMembership.Expanded)
   6:   WriteToLog(String.Format("Recieved identity for {0}", Me.uxDisplayName.Text))
   7:   WriteIdentity(appGroup)
   8:   Exit Try
   9: End If

What this does is use the project name entered (in the event it is under the element ProtfolioProject (yea, I don’t know why it is called that either) to search a list of Group’s within your project for the one of interest.

Then, as it does not by default load the “Members” and “MemberOf” arrays you need to call ReadIdentity with the Expand option is you want to list the Members, and I do.

image

If this does not return an identity, then we need to look at the display name being a user account.

   1: ' Not app group. Then return user is you can
   2: Dim username As String = GetUsername(Me.uxDisplayName.Text)
   3: Dim usrIdent As Identity = m_GroupSecurityService.ReadIdentity(SearchFactor.AccountName, username, QueryMembership.Expanded)
   4: If Not usrIdent Is Nothing Then
   5:   WriteToLog(String.Format("Recieved identity for {0}", username))
   6:   WriteIdentity(usrIdent)
   7:   Exit Try
   8: End If

 

Actually quite easy, but it could be easier.

 

Example WorkItemChangedEvent:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <WorkItemChangedEvent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   3:   <PortfolioProject>TFS Sticky Buddy</PortfolioProject>
   4:   <ProjectNodeId>614c944e-7799-46a2-a519-30e68eea040b</ProjectNodeId>
   5:   <AreaPath>\TFS Sticky Buddy</AreaPath>
   6:   <Title>TFS Sticky Buddy Work Item Changed: Requirement 1267 - Visual Enhancement</Title>
   7:   <WorkItemTitle>Mobility Continental Exceptions Report</WorkItemTitle>
   8:   <Subscriber>HINSHDOM\svc_tfsservices</Subscriber>
   9:   <ChangerSid>S-1-5-21-1390067357-651377827-682003330-21716</ChangerSid>
  10:   <DisplayUrl>http://tfs01.hinshelwood.com:8080/workitemtracking/workitem.aspx?artifactmoniker=1267</DisplayUrl>
  11:   <TimeZone>GMT Standard Time</TimeZone>
  12:   <TimeZoneOffset>00:00:00</TimeZoneOffset>
  13:   <ChangeType>Change</ChangeType>
  14:   <CoreFields>
  15:     <IntegerFields>
  16:       <Field>
  17:         <Name>ID</Name>
  18:         <ReferenceName>System.Id</ReferenceName>
  19:         <OldValue>1267</OldValue>
  20:         <NewValue>1267</NewValue>
  21:       </Field>
  22:       <Field>
  23:         <Name>Rev</Name>
  24:         <ReferenceName>System.Rev</ReferenceName>
  25:         <OldValue>4</OldValue>
  26:         <NewValue>5</NewValue>
  27:       </Field>
  28:       <Field>
  29:         <Name>AreaID</Name