Archive for the 'Software' category

Migrate Visual SourceSafe to Git – A short how-to

November 30, 2013 1:35 am

My hobby/learning projects have been residing in a single-person SourceSafe database for a long time (yes, I know you’re laughing; I don’t care – for single-person projects it’s just fine and dandy.) It was time to start using something new. I wanted to migrate everything, including history, to git.

The first step was to install the latest version of git (Git-1.8.4-preview20130916) on the system that currently hosts the SourceSafe database. If you’re long-term-memory-capacity limited like me and can’t remember git command-line arguments to save your life, you’ll also install something like TortoiseGit while you’re at it. One important step is to choose to run git from the Windows Command line during setup. (The next step needs git in the PATH.)

The second step was to install vss2git (http://code.google.com/p/vss2git/). After some trial-and-error with converting my entire database (a mistake, by the way, see step three) and getting error messages about the log file, I changed the permissions of the install folder to allow “read/write” for every user.

The third step was to convert each main project in SourceSafe (well, via a copy of the SourceSafe folder, actually, just to be paranoid) to a git repository by making sure to use $/Path.to.project in the vss2git tool’s Project field.

image

The fourth step was to convert each of these newly created full repositories to “bare” repositories for sharing across my local network. The command line for that is

git clone –bare –no-hardlinks Path.to.project Path.to.project.git

And that’s pretty much it. A fifth, optional step is to remove the original repository folders that served as the source for the bare repositories (so they don’t clutter up the Windows file share).

I am now the proud “owner” of 13 brand-new, independent little git repositories!

[Update 2013-12-01]

Well, I wasn’t too happy with the above solution. It creates too many nested folders (partly because of how Visual Studio creates stuff in VSS in the first place.) Once I clone the resulting repo, I get something like:

CloneRoot/Uncorked.root/Uncorked.root

That’s not what I want. I need it to be CloneRoot/Uncorked.root at most.

This answer on a StackOverflow question provided a good path to take. Based on that answer, I cobbled together a .cmd file to process all my repositories:

@echo off
for /d %%d in (*) do (
  if not exist %%d\config (
    echo %%d
    cd %%d
    attrib -h .git
    move .git %%d/
    cd %%d/
    attrib +h .git
    git init
    git add .
    git commit -am "moved git root"
    cd ..
    git clone --bare --no-hardlinks %%d %%d.git
    move %%d.git ..
    cd ..
    rem pause
  )
)

nVidia nForce 430 (MCP51 / RTL8201CL) and SME Server 8.0: working!

September 1, 2013 8:04 pm

Lately, my home network started showing more and more signs of aging. Accessing websites was erratic, whether via wired computers or wireless devices. WiFi clients (which for some reason have almost exploded in number over time) couldn’t reliably connect, causing shouts of “Daddy, the Internet is down!” with regular occurrence, coming from various bedrooms. Something had to be done. And what better time for that than Labor Day weekend!

The last time I had undertaken a similar venture was at the end of November 2006. Shortly thereafter I started preparing for the next time this would need to happen. Well, here we are… I had set aside a pretty neat “mini” system and found the necessary half-height network card for it (SME Server systems need two network cards to act as server/gateway on a network). I had even installed SME Server 7.5.1 in preparation for the eventual migration (the newest version at the time). Unfortunately I never found a way to make the on-board network card work, so the machine just sat on the shelf for a few years, until now.

 

Transferring data from the old system's drive

The trick to making the on-board NIC work was to grab the RHEL 5 driver from nVidia’s site. Extensive searches (based on the “Onboard LAN” information on the motherboard information page) led me to this thread, pointing me to an older version of the driver. From there it was just a small hop to the most up-to-date driver package. The trickiest part was getting it onto the new system’s hard drive before hooking it up to the network. I found a USB flash drive, FAT formatted it, copied the driver to it, and then got it mounted on the SME system. Quite a refresher on working with Linux command-line programs!

Once I had the driver installed (rpm –ivh nvlan-rhel5-0.62-1.25.i686.rpm) and the system restarted, I was able to run through the SME configuration with dual NICs to make the system a “dedicated server gateway”. I was a little worried that it might not pick up an IP address from my cable provider, but I just needed to restart the cable modem as well, and after one more reboot (I think), everything was back up and running. Luckily I had given the new system a non-colliding internal IP address way back when I set it up the first time. It was a snap to set the range of DHCP addresses to a non-overlapping set.

To complete setup, I had to re-create user accounts, ibays, domains served, VPN access, etc. I also needed to install the latest updates to SME Server 8.0 and the two “contribs” I consider essential to SME Server: AWStats and Sme8admin.

All that was left now was moving the data off the old system. I started out doing that over the network, but it became clear that the old system was truly on its last breath. So I decided to shut it down and hook the old drive up to the new system via the USB bridge you see in the picture above. There were about 20 GB to copy, so it took a while. Once it was done (including historical web server statistics data for AWStats), there was still some work with setting the right permissions on files and directories.

But now it’s all done, and the new machine is humming (quietly) in the spot where the old system used to live!

To round out this tale, here are the traditional “nostalgia” shots of the decommissioned hardware:

Note the power supply off to the side    A look inside the old system    Under the power supply    NICs in the back

One thing I had completely forgotten about is that I had put quite a bit of work into trying to make the old system as silent as possible. As you can see from the first picture, I had taken the power supply out of the system and put it on some pieces of vibration-dampening synthetic foam strips. In addition I had mounted the hard drive using various pieces of professional grade foam strips:

Green and yellow foam    Yellow foam and mounting pads

Luckily the new system was designed for quiet operation, so it didn’t need any extra work. It’s amazing how much quieter it is – I can hardly tell it’s on right now!

A swan song for 2012 and WPF

January 1, 2013 10:08 pm

I intended this to be my fifth and last post of 2012. Life intervened, and it turns out this will be my first post of 2013 instead. Blogging obviously took a back seat to other things last year. Sadly (seen from a certain perspective), I spent a lot of my time this past year reading that incredible time-sink, Twitter. I don’t follow many people, but the ones I follow always have something interesting in their streams. Another thing I spent a lot of time on, it seems, was working on a couple of Windows Phone apps and participating in local events around Windows Phone. But what really took up the bulk of my time at the beginning of the year was a project at work. And that’s what I will spend some time on now.

image

(A screenshot of HP Connected Backup running with a mock UI)

With the launch of Windows 8, HP has developed a more consumer-friendly version of the former Autonomy / Iron Mountain Connected Backup software, called HP Connected Backup. This is just one of the areas where HP is taking advantage of Autonomy’s technology and infrastructure, despite all the acquisition hoopla of late. I was closely involved in the implementation of the UI rewrite. The original Connected Backup software used a Java-based UI and was mostly offered for business and enterprise customers, and the user interface needed to change to be more consumer-friendly. As it happened, someone else made the decision that the UI should be implemented in WPF, still my favorite UI software technology stack. My involvement started when it became clear that the nature of the work was more complicated than the team working on the product had enough experience to pull off.

I had just finished work on another product that ended up only shipping via HP’s support website (called HP Quick Start, a tool for Windows 8 similar to Samsung’s S Launcher, now apparently renamed to Quick Starter; incidentally, there’s a really interesting story about why HP Quick Start didn’t ship, but that needs to be told in 10 years or so, not now). A colleague and I went to Austin, TX to meet with the Interaction/UI design company so I could learn about the amount and kind of work to be done. Their technical team had already started working with the HP development team in the Boston, MA area, and I got set up to work with them remotely as well. Some time after getting my feet wet in the codebase that had already been built (with a great M-V-VM foundation), and working with the Boston team over the phone, another colleague and I visited the team in Boston to start our collaboration for real. We stayed for about a week and got a few things done while we were there, but more importantly, we got to know the people on the team, and they got to know us a bit.

After returning from Boston, the real work began. I participated in daily stand-up meetings via phone. Because of the three hour time difference, I then had a few hours of opportunity to work while the remote team was available for questions and collaboration, and then I would continue working on my own, mostly from home. At the end of my day, I’d have the codebase pretty much to myself, so I didn’t have to worry too much about conflicting code check-ins.

Apart from looking at deliveries from the design house and making sure that everything from them was working as expected, I also built and customized many of the key UI components that were needed for the product. Let me run through just a few.

The tab control for the settings UI

image

The tab control work was mostly a job of cutting apart the Photoshop files from the design firm and fitting them into a styled TabControl/TabItem combo. The trickiest part was adjusting the transparency of the photoshop layers to make the transitions from tab to tab look right.

The UI that indicates file version numbers in the backup set

image

This control is based on heavy customization of the stock WPF DataGrid control with intricate interception of routed events and some complex visual tree trickery to get the interaction with the checkboxes and expansion/collapsing just right. Not to mention the view model construction, mapping the data to the actual backup information from the cloud (the data model).

The “accordion” control for the main UI

image

image

The accordion control is based on the WPF toolkit from February 2010, which contains an experimental implementation of such a beast. It was difficult to customize because it isn’t well documented and has a bunch of built-in behavior that we didn’t want. Not only did this require customizing the toolkit accordion’s styles, I also ended up building custom templates for the way the elements in the headers needed to switch appearance between the expanded vs. collapsed state. This was one of the last things to be finalized on the product. It was a very look-bound control to begin with, and it had a few bugs that were impossible to fix easily by modifying the source code.

The top header with the promotional offer

image

The offer header wasn’t too much work, except in the area of making it appear and disappear under the right circumstances (you don’t want it to show once a customer has subscribed, but you want it to show up again some time before a subscription expires). If I remember correctly (it was a while ago now), I even dug into writing some of the necessary async cloud client code that could retrieve the offer information from HP’s Connected cloud services. Because the final design deviated from what was delivered by the design firm, I actually ended up iterating on the visuals quite a bit with our Product Owner to arrive at something that was acceptable.

The “spinner” control and assets

image

Many parts of the UI are dependent on fetching information from the cloud, which can take a while. In these instances, it’s common to display a form of wait indicator to let the user know that something is happening. We had a control for such a wait indicator from previous products, so I didn’t need to create it from scratch, but the visuals for this control were, of course, new. Since the control uses a “flipbook” animation style (it renders a new image rapidly enough to give the impression of movement), I needed to create all the rotated snapshots for the flipbook to go through. This involved using Image Magick and a bunch of command-line scripting to automatically rotate and crop the original source image. Since we needed three different sizes of the spinner, I actually ended up modifying the existing control somewhat more than I thought, and created multiple sets of flipbook images via the Image Magick scripts I created.

The scrollbar assets

image

During usability studies it became apparent that our design firm had been – let’s say – “optimistic” on the size of the scrollbars that the UI needed. It turned out they were too hard for people to notice and use (i.e. too small). So I had to modify the underlying visual assets (Photoshop files again) without their help and adjust the scrollbar styles to accommodate the new, bigger parts.

Templates for dialog boxes

image

As part of being responsible for the overall translation of the wireframes and visuals from our design partner firm into real code, I needed to make sure our various dialog boxes were presented with a consistent style. Since there were too many dialogs for me to work on directly, I created sketches of guidelines for the team to use when they needed to work out a new dialog.

Quick Tips usability aid

image

image

image

image

I mentioned earlier that we conducted usability studies on the product. By the time we had enough of the product ready for testing, we found that the accordion design of the main UI was not as usable as we had hoped. Even with lots of tweaks to the original visual design cues/clues, people found the two panels of the accordion too difficult to use. I had toyed with the idea to integrate a tutorial of sorts into many of the products I’ve worked on in the past, but never seemed to have an opportunity to do something about it. Well, this time, I decided to take the time. I started implementing the idea and showed prototype screenshots to our usability lead. He liked the concept, and helped me work with our Product Owner to incorporate the idea into the final, shipping code, even though it was close to shipping time. We ended up naming this “Quick Tips”. WPF’s ability to layer UI elements on top of each other made the implementation relatively simple. One part that I’m quite proud of having been able to incorporate into Quick Tips was the ability to operate the UI from code, using WPF’s UI Automation framework. This was something I had wanted to work with ever since I attended the first sessions on this when WPF was unveiled as “Avalon/WinFX” at Microsoft’s PDC 2005. I was quite impressed with the capabilities of the platform in this area. It was relatively straightforward to open and close the accordion as needed to have tips pop up in the right context, etc. The only thing that was a bit tricky was to open up the help context menu and have it stay open with the “Quick Tips” menu item highlighted.

This is just a quick tour of a part of the work that was involved in creating HP Connected Backup. I’ve focused on my work, since that’s what I know best. The larger team worked on many, many more aspects of the product, not the least of which is, of course, readying the backend infrastructure for a consumer-level product and creating a UI for entering subscription and billing information. A part of the product I haven’t touched on at all is the subscription wizard, a standalone app that brought other UI challenges with it, and that walks the customer through the steps of creating an account on HP’s cloud systems and preparing the local system for backup of the customer’s data. This app required quite a bit of tweaking from the original design.

WPF riding into the sunset?

During the work with the accordion control I took a look at the WPF toolkit, since it had such a control in an “experimental” stage. “Experimental” – yeah, no kidding! After much fighting to get it to look the way it needed to look (the WPF toolkit accordion control is not “lookless” like most WPF controls), it became obvious that the version of the control in the “binaries” was different from the version in the source code, so modifying the source code to fix certain bugs was impossible. So I had to resign myself to re-styling much of the control and creating ugly, hacky workarounds for bugs I found.

And this is where my swan song for WPF starts. It seems pretty clear that Microsoft has completely de-invested from carrying WPF forward through their past community efforts. Yes, there’s been a lot of investment in WPF 4.5, but that seems to be about the end of the line. The WPF toolkit was supposed to be a vehicle for taking feedback from the community, developing something in response, refining it, and eventually integrating that into the platform. I think that’s how the calendar control in WPF came about, as well as many other things. The last release of the WPF toolkit was in February of 2010, almost three years ago. Apparently, and I’m guessing here, the work on Windows 8 took a lot of the “steam” out of WPF. The focus was put on developing the XAML platform for Windows 8 “Store Apps”. And it’s been quite detrimental to WPF. From my perspective, WPF’s problem lies in the fact that many of the visionaries behind the original concept are no longer involved in the product. It may very well be that WPF is a mature technology by now (although some people see it as not having fulfilled its promise by a long shot), but leaving it in maintenance mode seems to me to be stopping before you’re really “done done”. Such a pity to see a platform with such incredible potential being wasted for whatever reasons.

Windows 8 XAML

Finally, a small rant on Windows 8 XAML: Compared to WPF, the Windows 8 XAML platform is clearly a “V1” product. It’s almost embarrassing how much of the power of WPF is missing from the Windows 8 XAML platform. I can only point to a few things off the top of my head, but I’m sure you can find many references elsewhere. There’s no tiling Image Brush. No Radial Gradient brush. A lot of the built-in controls are laden with “fast and fluid” behavior, such as built-in transitions, that are very cumbersome to remove or alter. The data binding mechanisms are primitive compared to WPF. Having worked with this new platform for a little while now (a topic for another post, perhaps), I think I can say that I’m disappointed. It’s hard to live up to the power of WPF. I hope Microsoft will get there eventually and I hope WPF will come back “from the dead” now that Windows 8 is here.

Batch download BUILD 2012 videos

November 4, 2012 10:30 am

I didn’t get to go to //build this year (sniff), so I’m going to download a bunch of session recordings for offline viewing.

One way to do this is to use a PowerShell script (I found one here, based on this).

Last year, I just used the script as it was. This time, I’ve modified the  the script code so it also creates a “sidecar” file with the session title and summary:

 1: cd "C:\build2012"

 2: [Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath

 3: $a = ([xml](new-object net.webclient).downloadstring("http://channel9.msdn.com/Events/Build/2012/RSS/mp4"))

 4: $a.rss.channel.item | foreach {

 5:     $url = New-Object System.Uri($_.enclosure.url)

 6:     $file = $url.Segments[-1]

 7:     $file

 8:

 9:     $linkurl = New-Object System.Uri($_.link)

 10:     $session = $linkurl.Segments[-1]

 11:

 12:     $descfile = $session + " - " + $_.title + ".txt"

 13:     $descfile = $descfile.Replace(':', '_')

 14:     $descfile

 15:     $_.summary

 16:     if (!(test-path $descfile))

 17:     {

 18:         New-Item -ItemType file -Name $descfile

 19:         Add-Content -Path $descfile -Value $_.summary

 20:     }

 21:     if (!(test-path $file))

 22:     {

 23:         (New-Object System.Net.WebClient).DownloadFile($url, $file)

 24:     }

 25: }

As before, you may not want all the videos. So you can do this with the string in line 3:

http://channel9.msdn.com/Events/Build/2012/RSS/mp4?t=windows-phone

The available filters (for the t parameter) are:

.NET
Advertising
Analytics
Application-Lifecycle-Management
ASP.NET
C/C++
C++
Cloud
Contracts
Data
Design
Device-apps
DirectX
Gaming
Graphics
Hadoop
HTML5
Internet-Explorer-10
JavaScript
Keynote
Kinect
LightSwitch
Line-of-business
Localization
Media
Microsoft-8
Microsoft-design-language
Networking
Office
Performance
Reading
SharePoint
Shopping
Team-Foundation-Server
Testing
Tiles
Touch
TypeScript
User-Interaction
UX
Visual-Studio
Windows-8
Windows-Azure
Windows-Phone
Windows-Phone-Apps
Windows-Runtime
Windows-Server
Windows-Store
Windows-Store-app
Windows-Store-apps
WinJS
XAML
Xbox

If you’re just interested in the slides, use a query like this:

http://channel9.msdn.com/Events/Build/2012/RSS/slides

In general, the query can be constructed like this:

http://channel9.msdn.com/Events/Build/2012/RSS/
[type]?t=[tag]&term=[free text]

Where [type] can be one of: wmv, wmvhigh, mp4, slides

You can add multiple t arguments.