Sharing Google Picasa Libraries between users on the same computer

After a few years of using Adobe Photoshop Elements, last year we switched over to using Google’s free Picasa for organising our photo collection. Consecutive versions of Photoshop Elements were just getting slower and slower mainly it seemed due to waiting for the ‘kewl’ interface to redraw itself. Picasa is really slick and fast on our 2.8GHz Pentium 4 home PC. It can also upload our photos for printing to PhotoBox, and share them online using Google’s own Picasa Web Albums.

Photoshop Elements keeps all of your photo tags and collections in a ‘*.psa’ database file (which is actually Microsoft Access database). The useful thing we found about this was that we could share all our photo collection settings and tags between users. Picasa, on the other hand, stores its settings in hidden Picasa.ini files in your photo directories as well as in your local app settings user profile folder (buried in ‘Documents and Settings’ on Windows XP or the ‘Users’ folder on Vista). The problem with this is that you can’t share your Picasa library between users on the same machine as Picasa is hard-coded to look in the currently logged on user’s profile directory, and can’t be coaxed to look elsewhere, such as a shared location.

So to workaround this, you can take advantage of a feature of NTFS called junctions, which allow you to wire up one folder to another (or symbolic links, I’m not sure what the difference is, but the end result is the same). Windows Vista has a command-line tool called MKLINK which will create these. On Windows XP you will need to use the Sysinternals Junction command-line tool. Here’s what I did:

  1. Copy %LocalAppData%GooglePicasa2 and Picasa2Albums to a shared location to which all users will have Modify access. (I chose C:UsersPublicAppDataLocalGoogle on Vista, it’d be something like C:Documents and SettingsPublic on XP)
  2. Rename %LocalAppData%GooglePicasa2 and Picasa2Albums e.g. “Picasa2.old” and “Picasa2Albums.old”
  3. Use MKLINK (Vista) or Junction (XP) to create a junction from
    %LocalAppData%GooglePicasa2 to
    <SharedLocation>GooglePicasa2
    and:
    %LocalAppData%GooglePicasa2Albums to <SharedLocation>GooglePicasa2Albums
  4. Repeat steps 2-3 for each user for whom you want to share the Picasa library

Of course this may break with a future version of Picasa, so proceed with caution and don’t blame me if it all goes horribly wrong.

Shortcut to Switch User in Windows Vista

At home, our PC running Vista is rarely rebooted and is either in a low power state sleeping or being used by either me or my wife. One thing we’ve taken great advantage since the XP days is Fast User Switching which allows someone else to log in to their desktop whilst yours is kept running in the background. My wife and I had got quite used to doing a quick WinKey+L (as you do) before relinquishing control of the PC to one another. In Windows XP WinKey+L is does a “lock workstation” which in non-domain machines takes you back to the Windows logon screen. Unfortunately on Vista it takes you to a “workstation locked” screen, so you then have another mouse click on the Switch User button (followed by monitor re-syncing itself – why does it do this? All users run at the same screen resolution) to take you to the users screen. Of course there is a “Switch User” command tucked away in the little menu next to the lock button on the start menu – but a quick keystroke is what we’re after here.

So – I go off searching for a shortcut key that does a “switch user” rather than “lock workstation”. After a 20 minutes fruitless Googling for some special key combination, I sat back, thought about it logically and came up with this solution:

  1. Create a shortcut on your desktop to TSDISCON (* see below) and call it something like “Switch User”
  2. Go the shortcut Properties page and assign a shortcut key. Note that unfortunately you can’t use the Windows Key in your shortcut – so I went for CTRL + ALT + SHIFT + L
  3. Right click Start button and choose “Open All Users” and move the shortcut into the Programs folder (confirming the UAC prompt as you go).
  4. Log out, and back in again. This is necessary because Explorer hasn’t noticed there’s now a shortcut with a new shortcut key it should be taking notice of.

And that did it. CTRL + ALT + SHIFT + L isn’t quite a neat as WinKey+L but it’s a hell of a lot better than poking around in the Start Menu.

* What is TSDISCON you ask? It’s the Terminal Services Disconnect command. Fast User Switching is all made possible by the core Terminal Services technologies which introduced the concept of multiple Window Stations or “sessions” running concurrently on the one machine. It was of course originally designed to support multiple users connecting concurrently to these sessions over the network using the Remote Desktop Protocol (RDP), but Windows XP took advantage of the multi-session architecture to enable Fast User Switching. (The RDP stuff is still there but hobbled to only allow one user to connect at a a time.)

UPDATE: If you don’t have tsdiscon.exe on your system for some reason (maybe it’s only available in Business/Ultimate or something) then you can use the following C# code (compiled into a Windows EXE using C:WindowsMicrosoft.NETFrameworkv2.0.50727csc.exe if you don’t have Visual Studio) to do the same thing. Tsdiscon.exe is just a wrapper around WTSDisconnectSession. I used Dependency Walker (aka depends.exe) to find out what was being used:

UPDATE 2: For your convenience: I’ve compiled the below and packaged it into a ZIP along with the source for download here.

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

class Program
{
  [DllImport(&quot;wtsapi32.dll&quot;, SetLastError = true)]
  static extern bool WTSDisconnectSession(IntPtr hServer, int sessionId, bool bWait);

  const int WTS_CURRENT_SESSION = -1;
  static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;

  static void Main(string[] args)
  {
    if (!WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE,
         WTS_CURRENT_SESSION, false))
      throw new Win32Exception();
  }
}

Microsoft Search Server and FAST

Microsoft have a new server product: Search Server 2008. Well I say “new” but it seems to be based the same technology they’ve been pushing since the days of Site Server, on which I spent most of the late 1990’s travelling the world doing training and consulting. The same technology is used in Index Server, SQL Server Full Text Search, SharePoint, and even Windows Desktop Search.

It’s a workmanlike search technology, but I think people are so used to Google being so effective on the Internet that when they come to search their intranet using these technologies they come up short. You have to do a bit more wading through useless hits before you find what you’re looking for. In fact it’s a bit like going back the bad old days of AltaVista, et al before Google revolutionised search with PageRank.

This begs the question how good any intranet search solution could be (including Google’s own Search Appliance) on a intranet that consists of file shares and SharePoint document libraries containing mostly Word documents, Excel spreadsheets, etc, with nary a hyperlink in sight. How would you get something like PageRank, which relies on incoming links to help rank content, working with a “corpus” (in search parlance) such as this?

So, Microsoft have now pretty much admitted that their search technology needs some work, because they’ve just shelled out $1.2 billion for FAST,a Norwegian search technology company. Or should that be “bailed out” as FAST seem to have had some financial difficulties recently? It’ll be interesting to see if FAST’s technology, when they integrate it, is more effective than Microsoft’s current offerings.

Fixing Vista folder annoyances

I found this gem in Dan Maharry’s RSS feed as part of his del.icio.us bookmarks. It’s a few registry edits to stop Windows Explorer auto-selecting a different folder view based on its content, e.g. normally if a folder happens to have a GIF or JPEG in it, Explorer will “helpfully” switch to thumbnail view.

Keith Miller posted a registry tweaks in the TechNet forums which I’ve rolled up here (mostly for for my own convenience) into a single batch file which also restarts Explorer:

setlocal

set BASE_KEY=HKCUSoftwareClassesLocal SettingsSoftwareMicrosoftWindowsShell

:: Delete cached folder views
reg delete "%BASE_KEY%Bags" /f
reg delete "%BASE_KEY%BagMRU" /f 

:: Set default folder template
reg add "%BASE_KEY%BagsAllFoldersShell" /v FolderType /d NotSpecified

:: Restart Explorer
taskkill /f /im explorer.exe
start explorer.exe

If you don’t know what a batch file is or how to use it then you shouldn’t be using this :-p. Likewise, it works for me but your mileage may vary…

WCF JSON Serialization is flawed

I’m working on a little internal app that involves some AJAX-y callbacks to the server for data. The data is returned in JSON format for easy consumption by the client side code and is being generated with very un-sexy Response.Writes, whose output looks something like this:

{
   "jbloggs" : 
   {
      fullName : "Fred Bloggs",
      title : "Chief Burger Flipper",
      tel : "512"
   },
   "jdoe" : 
   {
      fullName : "Jane Doe",
      title : "Assistant Burger Flipper",
      tel : "587"
   },
   ...
}

This works nicely as a information can be looked up on the client in JavaScript like so:

var person = peopleJson["jbloggs"];
alert(person.fullName);

Dead easy. JavaScript objects are just dictionaries/hash tables.

Now I was aware that Windows Communication Foundation (WCF) services can now do JSON serialization in .NET 3.5, so I thought I’d swap out my low-tech Response.Writes for a WCF Service that would let me come up with structures in my server-side code that would be serialized automatically to JSON. But I found that the the way WCF (which ultimately uses DataContractJsonSerializer) serializes Dictionaries is a bit lame. This is what it came up with:

[
   {
      "Key":"jbloggs",
      "Value":
      {
         fullName : "Joe Bloggs",
         title : "Chief Burger Flipper",
         tel : "512"
      }
   },
   {
      "Key":"jdoe",
      "Value":
      {
         fullName : "John Doe",
         title : "Assistant Burger Flipper",
         tel : "587"
      }
   },
   ...
]

Odd. Dictionaries are serialised as arrays of objects whose members consist of a Key and Value. So in order to look up an entry I’d have to do a linear search through this array. I mean, you would have thought the fact there is dictionary functionality built-in to the JavaScript Object prototype (in fact, fundamental to JavaScript) – that it would be the sensible format to use rather than the Key/Value format. I just can’t quite see why Microsoft thought that this Key/Value format was necessary as it’s such a pain to consume on the client.

Looks like my low-tech Response.Writes are going to get a stay of execution for the time being.

SQL Server database space usage

Ever wanted to know what the biggest table in your database is, and what the other space hogs are? There is the sp_spaceused system stored procedure that either shows headline stats for the database as a whole, or those for a particular table. Annoyingly it doesn’t tell you which table is taking up all the space relative to all the others. If you have SQL Server SP2 installed then it ups SQL Management Studio

So, here’s a T-SQL batch that shows all the space taken up by tables in the current database. The main column to look at is “Total size”, which is a sum of the Data size, Index size and Unused columns.

SET NOCOUNT ON
DBCC UPDATEUSAGE(0)
CREATE TABLE #spaceused
(
    Name nvarchar(255),
    Rows int,
    [Total size] varchar(50),
    [Data size] varchar(50),
    [Index size] varchar(50),
    Unused varchar(50)
)
DECLARE @table_name nvarchar(255) 

DECLARE tables_cursor CURSOR LOCAL FORWARD_ONLY FOR
    SELECT name FROM sysobjects WHERE type='U'
OPEN tables_cursor
FETCH NEXT FROM tables_cursor INTO @table_name
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO #spaceused EXEC sp_spaceused @table_name
    FETCH NEXT FROM tables_cursor INTO @table_name
END

SELECT * FROM #spaceused
    ORDER BY CONVERT(int, LEFT([Total size],
                     CHARINDEX(' KB', [Total size]))) DESC 

DROP TABLE #spaceused
CLOSE tables_cursor
DEALLOCATE tables_cursor

Of note is the very useful INSERT INTO table EXEC proc technique for capturing the output of a stored proc.

The script works on SQL Server 2000 and 2005 (and possibly later).

Exchange 2007 – Custom IP Block List Provider Error Message

We use Microsoft Exchange 2007 at InfoBasis for email, and for my sins I have to manage it. It seems a little enterprisey unwieldy at times for an organisation as small as ours but the Outlook calendaring integration is a must for us and I’ve mostly worked out how it works and how to keep it running happily (thanks to Brian Reid of C7 Solutions who helped us implement it).

We use the built-in anti-spam filtering – specifically the IP Block Listing, aka “DNS blacklist” (or DNSBL) to block emails from known spam sources. I won’t explain how to set it up here as there are plenty of other resources that cover this. Because occasionally we’d get a false positive (eg. from a legitimate AOL or Yahoo account) I was investigating how to write Transport/Edge providers to provide some sort of dynamic spam white list functionality which didn’t seem to be provided out of the box. In so doing I discovered that most of the Exchange 2007 code base seems to have been re-written in .NET (which may explain why some feel it was released unfinished/too early). So I pointed Lutz Roeder’s .NET Reflector (which reverse-engineers .NET DLLs) at a few of the Exchange Server DLLs in Program FilesMicrosoftExchange ServerBin and had a snoop around. Thankfully, I eventually stumbled on the Update-Safelist PowerShell cmdlet which does white listing based on Outlook’s Safe Senders – so I didn’t have to write any code after all.

Anyway, on my travels I came across ConnectionFilteringAgent.BlockListDnsCallback (in the Microsoft.Exchange.Transport.Agent.ConnectionFiltering namespace) in Microsoft.Exchange.Transport.Agent.Hygiene.dll. This method formats the message that gets returned to the senders mail server should they be listed by a DNSBL. This was of interest because in Exchange 2003 you could use format codes in the error message (e.g. “The IP address %0 was rejected by black list %2”) to help legitimate email senders work out why their email was blocked (as documented in KB 823866). But, I couldn’t find any documentation on how to use similar format codes in Exchange 2007 – but here in BlockListDnsCallback was this line of code:

message = string.Format((string) provider.RejectionResponse,
   this.queryData.hostIP,
   this.queryData.provider.Name,
   this.queryData.provider.LookupDomain);

Which means you can use the following sort of custom error message in Exchange Management Console > Organization Configuration > Hub Transport > Anti-spam > IP Block List Providers > Edit > Error Messages:

Your IP address {0} has been found on '{1}' (looked up on {2})

Hope that helps!

Changing the font in Google Reader

I love Google Reader for reading blogs, but one thing that bugs me is the rather dull choice of font: sans-serif (Arial if you’re on Windows). If you have Vista or Office 2007 installed then you have a much better choice of fonts, one of my favourites being Calibri. If you don’t have Calibri, Microsoft ‘s trusty Verdana font is more readable online. Unfortunately, there’s currently no way to change the font in Reader’s settings pages. But, if you’re using Mozilla Firefox you can take advantage of user CSS and style any website however you choose, as long as you understand CSS.

Firefox’s user CSS lives in a file called userContent.css in the chrome directory within your Firefox profile which on Windows is somewhere like: %APPDATA%MozillaFirefoxProfiles<some alphanumeric id>.defaultchromeuserContent.css.

Create the userContent.css file if it isn’t there already (there will just be a couple of example files there initially) and add the following:

@-moz-document url-prefix(http://www.google.com/reader/)
{
    body
    {
        font-family:Calibri !important;
        font-size:105% !important;
    }
}

Tweak the font and size to taste.

Internet Explorer also allows user stylesheets, but there’s no ability to target certain styles for specific sites. It’s made possible in Firefox by the “@-moz-document” and “url-prefix” psuedo-selectors.

It turns out there’s quite a community with the same idea: that they can tweak sites to their own tastes. So check out http://userstyles.org/ and the Stylish extension, which makes it even easier to apply user CSS, and a huge repository of ready-prepared CSS for popular sites, which you can use if you’re not CSS-literate. Daniel Cazzulino has a great example of a pimped-out GMail courtesy of Stylish.

Adobe AIR and HTML Applications

My initial impression of Adobe AIR was that it was some sort of “Flash for the desktop” deal. Developing apps in Flash didn’t really appeal to me so I dismissed it (bad memories Flash development using early versions of Macromedia’s tools).

Fast forward to a few weeks ago, I started experimenting with Twitter (basically publicly broadcasted instant messages). In so doing I looked at a number of desktop clients, of which it turns out there are a several that run on the Adobe AIR runtime. One of the first AIR twitter clients I tried was Jonathan Snook’s Snitter. Being a Snook creation it looks great (and of course, lime green by default). It’s even got a little notification area (née systray) icon for when it’s sitting in the background minimised.

There’s nothing that belies the fact that this is really just an AJAX-y web application without the browser. It consists of just a bunch of HTML, CSS and JS files sitting in my Program Files directory (C:Program FilesSnitter to be exact). I had a bit of fun opening them up in a text editor and hack around with them and was pleased to see that Mr Snook is a also a jQuery fan.

So an AIR app is just a client-side web app: HTML and CSS for layout (oh and Flash if you want as well), JavaScript for your logic plus some platform interop library-type stuff provided by the AIR runtime all hosted in an implementation of WebKit, the standards-compliant rendering engine also used by Apple’s Safari. Oh and it’s cross-platform: running on Windows, Mac and Linux (eventually).

None of this is new though: Microsoft had the same idea about 10 years ago that you could develop desktop applications in DHTML, CSS and JavaScript/VBScript by hosting the Internet Explorer rendering engine in a bare window and allowing the script access to the host operating system. This technology was called HTML Applications, or HTAs. Many of the Control Panel applets in Windows XP (e.g. User Accounts, Help and Support Center) are HTAs and I think at some point even some versions of Microsoft Money were too. Interestingly, with HTAs, you can if you choose, package all the HTML, CSS, JS, images etc inside an EXE or DLL as resources (served up using the “res://” protocol) rather than having them lying around loose on the file system. To create an HTA: create a web page, rename it to have an *.hta file extension then double click it. It will be opened up by MSHTA.exe – essentially Internet Explorer without any menus or buttons and with a more relaxed security policy (insert cheap IE security jibe here). HTAs have been standard equipment on all versions of Windows since at least Windows 2000, so are a good choice for creating things like custom setup programs when you can’t be sure if the target system has something like .NET installed on it. Plenty of Microsoft’s product CDs use HTAs for their AutoRun launchers.

It transpires that Mozilla are also now getting in on the act with Prism, which makes sense as Firefox itself is a kind of an HTML application. Go to Program FilesMozilla Firefoxchrome crack open the browser.jar file with a ZIP utility and you’re presented with a bunch of markup (XUL rather than HTML), CSS and JavaScript.

AIR or HTAs give you HTML as your control surface which is so much more flexible than Windows Forms and without the learning curve and heavyweight runtime requirements of WPF. For the application logic: JavaScript is a great, flexible language which when coupled with something like jQuery is incredibly powerful for doing UI manipulation.

It seems that AIR really picks up from where HTAs left off with the added promise of cross-platform compatibility. The Adobe AIR runtime is impressively small (10MB), fast and easy to install. (This highlights a bugbear I have with the .NET Framework these days: it really needs to go on a diet, or become less monolithic. The .NET 3.5 runtime is over 100MB in total, whereas .NET 1.x was about 20MB.)

Anyway I digress. If you want to dig into creating AIR apps in more detail, Jonathan Snook has just written seasonal overview, which goes into topics such as data storage, file system access and application packaging.

Editing and testing scripts in SciTE

SciTE (the Scintilla Text Editor) is my text editor of choice. It’s fast, simple and lightweight. Not only that but it’s based on the Scintilla editor component which can be used in your own apps. There are a couple of versions available for download, my preferred one is Bruce Dodson’s version which amongst other things includes a Windows Explorer shell extension that adds an “Edit with SciTE” command for all file types.

There are plenty of other text editors available that are based upon the Scintilla core, such as Notepad2 and Notepad++, but they seem to lack the main feature that keeps me using SciTE. That is the ability to hit F5 when editing a script and have the console output appear in a separate pane in the editor window. I do plenty of batch file, VBScript, JavaScript scripting and with SciTE I can hit F5 to do a quick test. If any error occurs then the output window will jump to the offending line with a double-click if the error message follows the pattern:

<filename>(<line>, <col>) <error message>

…which is a fairly standard output format for most compilers and script interpreters.

The output window also supports standard input – which means if you have prompts in your scripts for input you can type them right into the output window.

SciTE can be extensively customised, as long as you don’t mind editing (albeit quite straightforward) configuration files. You can edit the core *.properties files in %ProgramFiles%Scintilla Text Editor, but you’d be better off opening your user options file which is stored at %USERPROFILE%SciTEUser.properties. I say this because there’s a better chance you’ll back up this file along with your user profile when you next pave your machine. There’s a shortcut to open or create a new the SciTEUser.properties file on the Options menu: Open User Options File.

Anyway, here’s what’s in my options file to help me develop Windows Scripting Host (*.vbs, *.js) scripts as well as good old batch files (*.cmd, *.bat) in SciTE. The key is to set the subsystem property to 0 so that all console input and output (stdin, stdout, stderr) end up in SciTE’s output window:

# *.vbs files
command.go.$(file.patterns.wscript)=cscript.exe //nologo "$(FilePath)"
command.go.subsystem.$(file.patterns.wscript)=0

# *.js files
command.go.*.js=cscript.exe //nologo "$(FilePath)"
command.go.subsystem.*.js=0

# Run batch files inside SciTE
command.go.$(file.patterns.batch)="$(FilePath)"
command.go.subsystem.$(file.patterns.batch)=0

Hope that’s useful for someone else.