| |
Yesterday on Leon's Blog, secretGeek, I noticed they had released v3.4 of TimeSnapper. One of the features that caught my eye was the ability to develop/add plugins to it.
I love plugins, I've written plugins for Windows Live Writer, Outlook, dasBlog, and more. Everything should have an SDK or plugin'able architecture. I championed it at work and we were one of the first Archiving Vendors with a 'real' SDK (I've built demo Vista Gadgets, integration scripts, federated search providers and PowerShell commandlets for it).
Anyway, the TimeSnapper plugin model looked really clean and easy to use. Read the one page description and your ready to go (didn't even download the sample code - it was so clear how things worked there was no need).
I wanted a little play around with it, so I though upload a snapshot to TwitPic would be a good idea. Opening a new project in Visual Studio, adding a reference to the ITimeSnapperPlugin.dll, create a new inherited class from ITimeSnapperPlugin and implement the interface :
#region ITimeSnapperPlugin Members
bool ITimeSnapperPlugin.Configurable
{
get { return true; }
}
void ITimeSnapperPlugin.Configure()
{
System.Windows.Forms.Form frm = new TwitPicPluginConfig();
frm.ShowDialog();
}
string ITimeSnapperPlugin.Description
{
get { return "Uploads snapshots to TwitPic"; }
}
string ITimeSnapperPlugin.FriendlyName
{
get { return "TwitPic Plugin"; }
}
object ITimeSnapperPlugin.HandleEvent(TimeSnapperEvent TimeSnapperEvent, EventArgs args)
{
switch (TimeSnapperEvent)
{
case TimeSnapperEvent.SnapshotSaved :
// upload it it to TwitPic
if (IsTimeToUpload())
{
string fileName = ((TimeSnapperPluginAPI.SnapshotSavedEventArgs)(args)).Activity.Filename;
Debug.WriteLine("Uploading " + fileName + " to TwitPic");
XmlDocument xmlDoc = UploadToTwitPic(fileName);
}
break;
default :
Debug.Assert(false, "Should never occur");
break;
}
return null;
}
TimeSnapperMenuItem[] ITimeSnapperPlugin.MenuItems()
{
return null;
}
Guid ITimeSnapperPlugin.PluginID
{
get { return new Guid("50744334-C5A0-44f1-BE64-5BBF32FDA79D"); }
}
TimeSnapperEvent[] ITimeSnapperPlugin.SubscribesTo()
{
return new TimeSnapperEvent[] { TimeSnapperEvent.SnapshotSaved };
}
All that was required was to give it a new Guid and name/description and then subscribe to the 'SnapShotSaved' event and handle the event when it was triggered. To get the image uploaded to TwitPic I used some code from the excellent Yedda Twitter C# Library (just the stuff for posting image data to a url). That all worked a breeze, but it was sending images (and posting to my twitter account) every 10 seconds (and of course it was hard coded to my username/password) - what was needed was a bit of configuration...
Luckily the plugin model provides an excellent and easy way to do this (set the Configurable property to true, and handle the Configure event). A bit more jiggery pokery, one modal dialog and an XML config file later, it was all working (configurable username, password, twitter message and frequency of updates) - although I really should do something better than store the username/password in clear text in an XML file...
If you want the plugin, just drop this dll into your %install%\plugins folder and restart TimeSnapper.
GEO: 51.4043006896973 : -1.28754603862762
After upgrading to Windows 7 on my laptop I found that I could no longer sync with my Sony Ericsson X1 (Windows Mobile 6.1) Phone. It didn’t even seem to be charging (over USB). Looking in the system Device Manager I found a missing driver for the ‘Generic RNDIS’ device. A bit of goggling uncovered that this was something required for syncing mobile devices. Although there are comments around that Windows Mobile devices are not supported on Windows 7 beta, and a number of people seem to be having the same problem, the good news is it does actually work. I simply downloaded the Windows Mobile Device Center 6.1 for Vista (from Microsoft), installed it and everything was rosy. It installed the driver for the ‘Generic RNDIS’, I connected the phone, it was recognised a Microsoft USB Sync device was installed and it all started working as expected. GEO 51.4043694884482: -1.28756761550903
I am loving the Sticky Notes app in Windows 7. The only issue I have with it is the dreadful font it uses – well my issue is not the font, it is the fact that you cannot change it to something more ‘normal’. I mean, I can easily change the font for Outlook Notes. I know, I know, you want it to look like handwritten notes that you would stick on your fridge at home, but hey – this isn’t my fridge at home, it’s my PC at work (and unfortunately there is no cold beer inside it !!). Eileen Brown confirmed for me that there is no way to change it right now (in the beta – build 7000), but there may be a ‘Non UI’ way of changing it in the official release… GEO 51.4043243116043: -1.28760516643523
Apparently I am rapidly becoming 'Geo Guy'. I seem to be adding Geo / Gps support and plug-ins to everything I use...
I just finished adding 'Insert GPS Link' support to PockeTwit (a great little Windows Mobile twitter client - really, go and get a copy now...) Previously I added GeoRSS support to dasBlog for individual blog posts as well as the RSS feed, and I also added geo microformat support to Windows Live Writer with my 'InsertGeoMicroformat' plugin.
So, what's next - have you got an app that needs Geo / GPS support added ?
GEO 51.4043243116043: -1.28760516643523
Twitter is one of those applications / services that I've had trouble getting to grips with. For me it seems it's like shouting about what you are doing right now to a huge audience that is not listening. Who really cares that @kjhughes is heading to the shops to get some Mint sauce ?? Maybe I'm just not that kind of social animal, maybe I don't have enough friends using it, maybe I should 'but in' to other peoples conversations more, maybe I'm just plain boring... I do see a use for it though (for me). It's a pretty neat way to do some remote control stuff - like set up a Media Center recording, reboot my PC, and also it's a neat way of getting updates, like new blog comment received, TV recording completed and the like.... So, right now I need to get my Outlook addin project completed, but right afterwards I'm planning an app that interfaces to twitter and accepts direct tweets as remote control instructions, and also can update me on specific events. I am also thinking about adding twitter alerts to dasBlog (on comments, posts, errors, daily reports etc) I can see myself getting immersed in this twitter thing... GEO 51.4043197631836: -1.28760504722595
I've been toying around with creating an Outlook addin recently that adds a new panel to the main Outlook inspector window. Actually it is going to be a 'folding' or 'collapsing' windows similar to the docked ToolWindows in Visual Studio. Anyway, the stuff around getting the correct window handle for the Outlook inspector window and resizing it to allow some space to insert my new panel was fairly simple, but I also had to hook into the message look of the window so that I could capture any move or resize messages and so resize things again to accommodate my panel. I had started developing it as an Outlook add-in but to speed things up (and prevent me having to register / unregister the addin between tests etc I decided to develop it as a separate app- I could still hook into Outlook and move things around. The problem came when I was trying to hook the inspector window message loop - it didn't seem to work. I fired up Spy++ and check that the inspector window was getting the messages - which it was - but they were never getting delivered to my hook code. I was using System.Windows.Form.NativeWindow and overriding the WndProc function (see my NativeWindowListener class below). To get the hook in place I was creating a new NativeWindowListener class with the inspector window handle as the parameter. Checking the handles and the delegates etc it all seemed to be correct, I just couldn't fathom why it wasn't getting any of the messages. Then the penny dropped. Outlook is in a separate process... (NativeWindow only works across the current process and window handles that are contained in it). What would be needed in this case is a system wide hook, that requires use of the Win32API and interop. I reckon this is overkill just to save a bit of development pain, so will probably move to something where the Outlook addin dynamically loads the panel in and make something available to have the add-in reload the panel - this should allow me to develop the panel code (the majority of the app) without worrying to much about the Outlook addin side of things. using System;
using System.Windows.Forms;
using System.Text;
namespace Outlook_Subclasser
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
internal class NativeWindowListener : NativeWindow
{
// Constant value was found in the "windows.h" header file.
private const int WM_SIZE = 0x0005;
public NativeWindowListener(IntPtr handle)
{
AssignHandle(handle);
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case WM_SIZE:
// do your processing in here
break;
default:
break;
}
base.WndProc(ref msg);
}
}
}
and then to use the class you would find the handle of the window you want to subclass and create a new NativeWindowsListener passing in that handle to the constructor. Note - this does not cover a number of aspects around releasing handles etc - you will want to make sure these are covered off... MyForm myForm = new MyForm(); NativeWindowListener nwl = new NativeWindowListener(myForm.Handle);
GEO 51.4043197631836:-1.28760504722595
I've had a lot of interest in my SMS Gateway app since this post. SMS gateway consist of two components :
SMS Gateway Addin This is an Outlook addin that adds a new toolbar to your Outlook instance. The toolbar allow the user to choose a mobile / cellphone number (from their contacts) and enter a message. When they hit the enter key after the message (or click 'Send') a new Task is created when has a subject of 'SECRETCODE' and the mobile / cellphone number and the details being the text of the message.
At some stage this Outlook Task is synchronized (over ActiveSync / Direct Push) to a Windows mobile device...
SMSGateway This is a small app running on a Windows Mobile device that every 15 seconds checks through the tasks. If it finds any tasks that have a subject beginning with SECRETCODE then it parses out the mobile / cellphone number and sends the message text (from the Task details) to that mobile / cellphone number via SMS. Note: the SECRETCODE word is configurable.
Why develop this ? The purpose of this app was really to allow me to send SMS messages easily from Outlook without having to sign up for (and pay for) a web to SMS service (I already get 100's of free SMS messages with my mobile / cellphone package).
The application is free for anyone to use (drop me a line - in the comments - if you do use it...)
Windows Mobile CAB file (copy the file to your Windows Mobile device and click on it) : SMSGatewayMobile.CAB Setup file for the Outlook 2003 Add-in (Outlook 2007 coming soon) : SMSGatewayAddin2003.msi Source for both the applications : SMSGateway.zip (includes test Outlook 2007 addin code)
I'd be really interested to hear from anyone using this.... post in the comments...
GEO 51.4043197631836: -1.28760504722595
Programmatically sending an SMS message from your Windows Mobile is fairly simple these days.
You'll need the WM6 SDK. Start a new Visual Studio 'Smart Device Project', add a reference to Microsoft.Windows.PocketOutlook, then use the following code... using Microsoft.WindowsMobile.PocketOutlook; ..and.. public void Send(string to, string msg)
{
if ((to != string.Empty) && (msg != string.Empty))
{
SmsMessage message = new SmsMessage(to, msg);
try
{
message.Send();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
Job done...
GEO 51.4043197631836: -1.28760504722595
A couple of problems I've come across at work with implementing MSCRM. These could be bugs, or may not be, who knows (I don't have the time for a detailed analysis...) I have a MSCRM 4.0 multi tenant implementation - I 'disabled' the first (and default) tenant and suddenly all reports (for all tenants started working intermittently - often just hanging time after time). The workaround I found was to re-enable the first tenant. This same action (disabling the first tenant) also seemed to screw around with the default tenant (the tenant it chooses when you just browse to http://crmserver/) - just choosing one at random - this is not something I have resolved yet. Hope this helps someone.. GEO 51.4043197631836: -1.28760504722595
Last week I attended the 'Business of Software 2008' conference in Boston, MA. I cannot rave enough about this conference - the quality of the speakers, the content, the organization - everything, was fantastic. It was organized by Neil Davidson (CEO and Founder of Red-Gate Software) and Joel Spolsky (FogCreek and JoelOnSoftware). They did a fab job !! Some of the speakers included :- As well as many, many others. It covered all the key components of building and running a software business, even as far as raising Venture Capital - and eventually selling (via an excellent Pecha Kucha presentation from Alexis Ohanian, founder of reddit.com) Seriously, if you are at all involved in the software business then come next year (no dates or location yet), if for nothing else but the networking opportunities... GEO 51.4043197631836: -1.28760504722595
I just found this Microsoft KB article which is a very comprehensive list of what services use what ports. Anyone working with enterprise software solutions or Microsoft back end infrastructure should find it useful. GEO 51.4043197631836: -1.28760504722595
So a while back (31st Dec 2007), my beta license for Windows Home Server (WHS) expired and I hacked together an alternative solution.
I have been updating my (almost) free/opensource alternative (it still needs a Windows OS) over the past couple of days and now have a pretty viable solution.
I have a machine (the Home Server) running Windows (any version would do) with two large additional drives in it (Data1 and Data2). Data1 is the primary data drive and on there I created a number of folders / shares:
- Photos
- Documents
- Music
- Videos
- Software
- Backups
- Downloads
I re-homed each of my 'special' folders in Vista (Docs, Music, Video, Photos) to these shares, so all data is stored on the Home Server. You could create a separate shared folder for each user with the correct permissions, but I share all the docs/photos etc between all machines so no need for me.
Next I wanted the WHS feature of duplicating the stored data across more than drive, so I grabbed a copy of the Robocopy and created a batch file with the following commands :
- robocopy d:\documents e:\documents /MIR /SEC /LOG:c:\robocopy.txt /NDL /NFL
- robocopy d:\music e:\music /MIR /SEC /LOG+:c:\robocopy.txt /NDL /NFL
- robocopy d:\videos e:\videos /MIR /SEC /LOG+:c:\robocopy.txt /NDL /NFL
- robocopy d:\software e:\software /MIR /SEC /LOG+:c:\robocopy.txt /NDL /NFL
- robocopy d:\photos e:\photos /MIR /SEC /LOG+:c:\robocopy.txt /NDL /NFL
- robocopy d:\backups e:\backups /MIR /SEC /LOG+:c:\robocopy.txt /NDL /NFL
- robocopy d:\downloads e:\downloads /MIR /SEC /LOG+:c:\robocopy.txt /NDL /NFL
This replicates all the folders across to the other data drive (Data2) thereby mitigating against a single drive failure. All the replication results / logs are stored in a file (c:\robocopy.txt) and I wanted that emailed to me so I grabbed a copy of Blat and added the following command line to the batch file :
- c:\tools\blat262\full\blat.exe c:\robocopy.txt -to YOUREMAILADDRESS -subject "RoboCopy Results" -server mail.YOURMAILSERVER.com-f "RoboCopy on Home Server" -u YOURUSERNAME -pw YOURPASSWORD
I named the batch file 'replicate.bat', put it in the c:\tools folder and then scheduled the batch file to run every night at 2am with this command line :
- SCHTASKS /Create /SC DAILY /TN Replicate /TR c:\tools\replicate.bat /ST 02:00
Excellent - now the data is replicated across two drives, and I get an email every day with the results of the replication process (in case anything goes wrong).
Next I wanted to ensure I have remote access to my files from anywhere. I grabbed a copy of the excellent HTTP File System and put that on the Home Server.
I set the root to the Data1 drive, created a user account for myself and gave it 'upload' ability and that gives me fully web based access to upload and/or download any file.
The next piece in the puzzle is to get full backups of the machines. For this I had planned to use VMware Server and the excellent VMware Converter tool, however it seems the command line options for the tool they provide p2vtool only works with a licensed version.
It's a great tool and pulls a whole physical machine image into a VMware virtual machine - and is a great way to get the failed machine back to life - what it doesn't do is restore a machine, but I'm most likely to rebuild any failed machine anyway - I simply need access to any files / data on there that might not have made it to the shared server folders...
GEO 51.4043197631836: -1.28760504722595
I am totally blown away by this. This is (IMHO) exactly what Windows mobile has been waiting for.

I have downloaded and am using this on my HTC TyTN II (Kaiser) - works like a dream, very easy to use and responsive to finger touch / navigation. There are a number of known issues with it and some reports of it not being great on devices without touch screens, but run (seriously, run very quickly) over there and grab a copy.
It is still in beta and the guys at Pointui have made it free (paypal donation optional). Unfortunately it does not cover all apps and aspects of the Windows Mobile UI, but the parts they have covered off are stunning - when these folks get all the common apps covered (Contacts, Dialer, Mail etc) then it will be incredible!
I love the list of known issues they have on the release announcement on their forums - it includes : Not enough time in the day and Red Bull wearing off - classy.
GEO 51.4043197631836: -1.28760504722595
The king is dead, long live the king.
Over the Christmas break the license for my beta of Windows Home Server ran out, so I needed an alternative backup / storage solution. I briefly considered Linux with some iSCSI software, Windows with DFS or FRS, or indeed forking out some of my scheckles for a folder sync application.
The requirements were as follows:-
- NTFS, for large file support (12 Gb in some cases).
- Easy duplication of the data (including hierarchy) across multiple drives.
- UNC pathname support, so I could 'rehome' my docs, music, photos etc to it.

In the end I opted for a fairly simple solution :-
- A windows machine with a drive for the OS and two additional data drives.
- One of the additional drives would be the primary where folders are 'rehomed' to and all data is stored.
- A batch file would fire off 'Robocopy' (free in the Windows Resource Kit) to mirror this primary data drive to the secondary data drive.
- Another batch file would fire off 'Robocopy' for copying to external USB drives.
- Batch files would be scheduled using AT command line tool and would email results files using the free Blat! command line tool.
- The primary data drive would also be backed up to my 'iDrive Pro' account (online 150 Gb storage facility for $50 / year).
- Of course, photos are also backed up to my Flickr Pro account (unlimited online storage of images for $25 / year).
GEO 51.4043197631836: -1.28760504722595
One of my colleagues switched me on to PowerShell Plus and I'm loving it.
Code editor, snippets, values of variables, logging tools and much more, including a really neat feature called 'MiniMode' (see the toolbar icon at the extreme right in the image.
This 'MiniMode' closes all toolbars/toolwindows except the main console but also makes the console window transparent (user configurable level of transparency). This mode is real easy to work with...
There is a free single user license for non commercial use.
I encourage you to try it out.
GEO 51.4043197631836: -1.28760504722595
Sarah wanted 'Ruby Ruby Ruby' by the Kaiser Chiefs as her ringtone. Her mobile doesn't have any easy way of connecting to a PC, so she joined one of the rip-off 'Ringtones R Us' services that force you into paying £4.50 / week for as many ringtone downloads as you want (aside: I must be getting old - why would anyone want to change their ringtone that often ??).
Anyway, after downloading the mp3 she found it start relatively quietly and she was missing some calls. What she had actually wanted was the chorus....
So cue Kens Do It Yourself Ringtone Creater and Transferer... 
Step by step instructions :-
- Rip the song to an MP3 (from the CD which we do own - no copyright issues)
- Download Audacity.
- Cut the chorus out of the original track (loaded MP3 file)
- Create a new stereo track and paste the chorus into the new track.
- Mute the original tracks
- Play / listen to the new track, make sure you are happy with it.
- Download lame_enc.dll to allow Audacity to export as MP3 (see this Audacity FAQ)
- Export the new track from Audacity as an MP3.
- FTP the MP3 file to your website
- Using 3G / GPRS etc on the mobile phone connect to the internet
- Browse to the MP3 file and download it to the mobile
- Set the MP3 as the ringtone.
- Cancel the expensive MP3 ringtone service (if applicable).
GEO 51.4043197631836: -1.28760504722595
Ok, so maybe this is a rant, and maybe it is due to the fact I forgot my annual Pay As You Earn (PAYE) employers return and was fined £400...
But seriously...
This is the government! This is the part of the government that calculates how much our taxes are!! This is intelligent automated software that they've had designed that should be 200% idiot proof.
I've had no employees for the past 12 months and I'm trying to submit (basically) an empty / null return.
Apparently I have employees on the list for whom I have not completed a P14 - note the list displays no employees, there's another summary page later on that tells me I'm submitting for 0 employees, so they know !!!!

GEO 51.4043243116043: -1.28760516643523
I have completed stage one of GeoRss enabling dasBlog.
In the config page I added some options for enabling GeoRss, specifying a default lat/long and enabling ‘integration’ with Google maps. There is also an option to use the default lat/long for any non geocoded posts.
If GeoRss is enabled then the edit entry screen provides textboxes to allow specifying lat/long (populated with defaults from config page).
If the google maps integration is enabled then you’ll get the ‘Show Map’ button and clicking it will display a map which you can move around until you find the location and then click on the location to get the lat/long texboxes populated.
If you have existing non geocoded posts then you can have the default lat/long added to those if you wish.
I puzzled around for ages when trying to display the georss in google (http://maps.google.com/maps?q=yourfeedaddress) – it kept telling me that the feed was invalid. I eventually found that feedburner was adding <atom10:link blah blah /> to the xml which for some reason google maps thinks is invalid. The only way I could find to prevent feedburner adding the atom link was to turn OFF the ‘Browser Friendly’ feature in feedburner.
So – stage 2...
The work I still want to do with this is basically to add macros to get lat/long - fairly easy I guess, and then some way to specify lat/long from Windows Live Writer (and other offline blog clients) – a little more complex. Scott mentioned a geo microformat and from my initial looks seems to be a good route to take - watch this space...
Now it is simply a case of retrofitting the geo info into all my old posts...
I was spending far too much time installing OS's - virtual machines, lab machines etc.
In order to automate / streamline this I wanted to look at not just the Windows tools as well as other options. Remote Installation Service (RIS) and unattended.txt files go so far, but during my investigations I came across 'Unattended'. This open source tool takes unattended.txt, mixes in silent installs for hundreds of other common applications and supercharges the whole lot...
So the deal is, you extract some files from 4 zip archives, configure a DNS alias, share the folder, copy over the i386 folder from your OS CD/DVD, burn an ISO (or create a boot disk) image and your done - 25 minutes end to end.
The boot CD/Disk loads some network drivers, maps a Z drive to '\\ntinstall\install' (the machine and share with the files and OS on it) and passes control to a bunch of Perl scripts, these ask some questions from which it creates an unattended.txt file and executes the OS install (reboots and all). When the install completes it can also (optionally) run silent installers for other applications (Office, Open Office, Acrobat Reader, PDF Creator, Visual Studio, Perl etc..) as well as Windows Updates and critical fixes (they keep an up-to-date list on the homepage).
So, in summary, after booting from the install CD then 2 minutes of console based questions I can leave things for an hour or two and come back to a fully installed Windows OS, office applications, sales tools, developer tools - whatever. The scripts that install the additional apps are customizable (you can even enter your product keys) and you can build up suites from individual scripts (so I can have a script to install Visual Studio, another for the MSDN library, another for each of the various developer tools and then I can combine them all into a 'developer_machine' script...
Have a look - if you are doing more than one install (even just two) then this can save you time...
Some of the code I have for importing data (from ACT! 2000) to MS CRM creates new 'PhoneCall' activities / objects. The problem is, that it seems MSCRM does not allow you to programmatically modify the 'create date'.
Here is the code I use...
CrmDateTime start = new CrmDateTime();
start.Value = DateTime.Parse("10/08/2005 12:30");
pc.actualstart = start;
pc.scheduledstart = start;
CrmDateTime end = new CrmDateTime();
end.Value = DateTime.Parse("10/08/2005 14:30");
pc.actualend = end;
pc.scheduledend = end;
pc.subject = "Phone call regarding sales of Widgets Q2/2005"); ***
string desc = "Start : " + pc.actualstart.Value + "\n";
desc += "End : " + pc.actualstart.Value + "\n\n"; ***
desc += "The details of the phone call go in here");
pc.description = desc;
pc.regardingobjectid = new Lookup();
pc.regardingobjectid.type = EntityName.contact.ToString();
Guid contactGuid = new Guid(guidOfContactWeTelephoned);
pc.regardingobjectid.Value = contactGuid;
The actualstart and scheduledstart (and ends) get populated with the current datetime (this seems to happen if the time they are set to is in the past).
Note the two lines between the ***'s - this is my solution / workaround and simply include the start/end times as text in the body/description of the phone call object.
So after some poor experiences with the MSCRM Data Migration framework I decided to get pragmatic and write a C# app to do the migration. The CDF is poorly documented at best, it seems they (Microsoft) give you a bunch of database tables, an Excel spreadsheet outlining the schema and a 'Good Luck'. There is little 'googleable' (is that a word) knowledge about it either. The good news was that the MSCRM SDK is much better documented (on MSDN). There is not a lot of googleable info around but there is enough (Stunnware proved pretty helpful for me). There were other challenges also - the software we purchased for exporting the ACT! 2000 data to Access (Exporter Pro) did a good job of getting the data out of ACT but the Unique ID left a bit to be desired, they are basically a munge of punctuation characters and alphanumerics - what's wrong with a GUID or a int ?? So, anyway, I got there in the end... The connecting to the CrmService was pretty easy, as was the population and addition of an account. crmSvc = new CrmService(); crmSvc.Url = MsCrmUrl; crmSvc.Credentials = new System.Net.NetworkCredential(CrmUsername, CrmPassword, CrmDomain); account acct = new account(); acct.name = "company name"; acct.address1_line1 = "address line one"; acct.address1_line2 = "address line two"; acct.address1_line3 = "address line three"; // etc Guid acctGuid = crmSvc.Create(acctGuid); Simple as that - do it for each account... Next installment will outline adding Contacts an then linking them to an account.
I'm in Western Mass (Westboro, MA) again this week and while that normally means 16 hour days (there is nothing much else to do but sit around a hotel room so why not...), this week I decided to work on a personal project for a bit.
Part of it was some code to check a machines public IP address and update it to DynDNS. Luckily they have an excellent developers / API section that explains everything you need to do this. There are two sections to it, detecting the machines public IP address and updating the hostnames associated with your account, both of which they provide a service for.
It's pretty easy to follow and within an hour or so I had come up with a class to do both tasks. Here is a snippet for the 'CheckIP' function:
public static string CheckIP()
{
// check the current public IP address
string ipString = string.Empty;
WebClient wc = new WebClient();
try
{
string result = wc.DownloadString("http://checkip.dyndns.com");
return ParseCheckResult(result);
}
catch (WebException)
{
ipString = string.Empty;
}
return ipString;
}
Just call a URL (http://checkip.dyndns.com) and it returns your public IP address, there was some parsing of the return text but it is pretty simple. Click the link and see for yourself.
Next was the 'UpdateIP' function, here's the snippet:
public static string UpdateIP(string username, string password, string ipaddr, string hosts)
{
// check the current public IP address against what we want to update to
string updateurl = "http://members.dyndns.org/nic/update?hostname";
string result = string.Empty;
WebClient wc = new WebClient();
string url = string.Format(@"{0}={1}&myip={2}&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG", updateurl, hosts, ipaddr);
try
{
wc.Credentials = new NetworkCredential(username, password);
wc.Headers.Add("User-Agent", "KSL - WHS Updater - 1.0");
It is basically just a case of passing a querystring with all the details to http://members.dyndns.org/nic/update , ensuring you set the credentials to your DynDNS account username and password and specifying a unique User-Agent.
The complete project files (including a small 'user' application to test it) can be found here (61K).
So, this is something I learned on the Certified ScrumMaster course by Danube Technologies.
It really clarified for me that any sense of control over software deadlines is, pretty much, only a 'perceived' sense of control.
Yes, we can strongarm, use peer pressure or rigid authority to make developers work longer hours, but then they spent more time idling during the day. Someone, somewhere has written a great article on it (Note, after spending an hour looking at Joel On Software thinking the link I wanted was there: Link it here when found)
Anyway, the graph - let me explain....
A development team has a normal work rate (given all things are equal, interruptions, bug fix workload, training , yadda yadda...) in this case the work rate is 30 'units' in a 15 day period (the red line). Supposing we 'force' them to up their productivity to 40 units in a 15 day period (dotted green line). They will work at their normal rate initially and then soon recognise that this will not meet the deadline - at that point they 'speed up' (this is the change in the solid green line at the 7 day point).
What you have actually done (most likely) is generated a 'technical debt' - because the way the developers 'sped up' (wrote more code) was by sacrificing some other aspect of the development (quality, test coverage, peer reviews etc).
So you have a 'technical debt' that needs to be made up during the next period. Even if we go back to the normal rate of work we are not going to get 30 units done in the 15 days, oh no, first we have to make up the debt, then start on the 30 units - which will likely need 'speeding up' to meet deadline.
What is worse though, is that now you have set the expectation that the team can deliver 40 units in the 15 day period, so your next schedule had 40 units factored in, and the next, and the next until ..... well, it's like spending more on your credit card every month than you are paying off, at some point you can go no further .
The moral of all of this ? Who knows... get a card with a long 0% balance transfer rate ??
So I just spent two days in London on a 'Certified ScrumMaster' training course run by Danube Technologies.
The instructor was a Dan Rawsthorne and although he liked to reference things to the military, he covered a great deal of topics and had an incredible wealth of experience - some of the real world example really struck home with me.
It seems that a common trait is people just not grasping the whole concept of (basically) handing over control to the development team. There were many questions about where the project manager fitted in, who really managed the team etc etc.
It is tough to grasp if you currently have the perception of 'having control of the process at the moment'. It suddenly hit home for me as I was traveling into London on the train for the second day and thinking about why this current round of QA release testing was taking so long.
According to the QA guys, the build they had been given originally for this release was pretty poor quality (thankfully sorted out now). I was wondering why and thinking back to when this release was being coded and realized that at the time I was pressuring he developers because we were 100 odd hours behind schedule. We managed to get back on track and I 'thought' the reason was because I had beaten/pushed/cajoled/whatever the guys into increasing their work rate.
In reality, what had happened was that I had forced them to deliver early and the way this was done was by sacrificing quality (you cannot change the laws of dynamics - right). The fact was we did not get visibility of that until further down the line in the testing stage.
So, have a think about whether you do actually have control, or are you just exerting force on one particular aspect of the 'whole' that is squeezing/reducing another aspect of the same 'whole'.
When this clicked in my head, it all made sense - the SCRUM methodology became clearer, what needing doing to get it working, why it worked (especially, why it isn't a bad thing to hand 'control' over to the team).
One of the slide deck was about 'technical debt' and it really drives this point (sacrificing something for earlier delivery) home - I'll blog about that later..
Just didn't work for me. I had it all set up as per the docs, imported the data into the CDF database, tried to 'Migrate' and it completed but migrated no records (even though I had 8000+ in the CDF tables). I tried both the snippets I gleaned from googling : - Make user the user does not have 'Restricted Access'
- Turn off 'Fast Load' mode.
Still no joy. All the 'required' fields are populated, the mapping wizard works correctly, but no 'migration'. It is a real pain as there is nowhere to go next, the documentation about CDF is really poor as is the logging/trace/error output from the Migration Wizard. Ever the pragmatist, I cracked open VS and and have started on an app which uses the CrmService webservice to import the data. Watch this space for the source when I'm done...
The company I work for (C2C) are hiring. We are looking for Technical Support Engineers to work in our Reading, UK office. We'll consider any experience level as long as the individuals show commitment, determination to learn / succeed and have a passion for technology. You might be right out of school / college, looking for your first step into an IT career, you might be an Exchange expert with many years of experience. We can promise variety, leading edge technology, in depth technical problems to investigate and input into the product direction. Want to apply ?, email us at hr@c2c.com
This week (so far) has been good - in terms of completing things, productivity and new products. First off, Microsoft finally released PowerShell for Vista. No more having to 'play' on my old lab machine to get to grips with this stuff. There seem to be a number of people reporting failed installs(due to EFS encryption being disabled), just read the comments of the PowerShell blog announcement. Next, we're just coming to the final couple of days of a 'Supporting Exchange 2007, Office 2007 and Vista SPRINT' at work (we use a form of SCRUM as our development process) - all is looking good and we have beta sites lined up. Then, I noticed Eileen's (the most communicative Microsoft employee on the planet) post about Office 2003 to Office 2007 command references. An interactive demo from Microsoft when you can click the toolbars and menus of an Office 2003 application and it tells you how to find the equivalent command/function in Office 2007. I spent some time finding the 10 or so commands I'd been having difficulty with and increased my productivity. Here's her post : http://blogs.technet.com/eileen_brown/archive/2007/01/31/old-to-new-reference-guides.aspx Then late last night (again at work) we just completed our internal testing before sending our Archive One product for Microsoft Platform testing. We are testing against 5 of the 6 platform tests (we don't fit into the 'Managed Code' test category as we make extensive use of MAPI which basically requires C++ / Unmanaged code)
I've been on Vista (on my work laptop) for a couple of months now and finding it really difficult to get some stuff done. I'm (directly) working on some training modules for our Archive One products and managing / assisting a couple of people who are working on Sales Video Demos of these products. The Sales Video Demo are making extensive use of Camtasia and my training modules are making some use of it. Their version 4.0.0 of Camtasia Studio is not supported on Vista and I can verify that it DOES NOT work on it (although you CAN install it, expect to get lots of application errors / crashes). TechSmith (the makers Camtasia) say that there is limited functionality available under Vista (you can record your screen to AVI format, but that's it). There is a beta version of Camtasia available from here that works with Vista (pretty well actually) and the TechSmith guys plan to release full support for Vista by the end of this month. As we're heavily into Exchange Server and the 2007 version is now released (and makes extensive use of Powershell of management), I've been meaning to get to grips with Powershell. Powershell is NOT supported under Vista yet either. They do have a Powershell RC2 available that works under Vista RC1 (build 5600). The details are available from their download page. Vista support is also planned for the end of this month. I guess I should have probably waited a bit longer before migrating to Vista. Anyway in the meantime I have a test Win2003 Server set up that I'm using for Powershell.
One of the difficulties I have encountered whilst trying to change the mindset of our development team is getting buy in for the concept of 'Committing to backlog items'. This is where the development team get together with the Product Manager(s) in a time boxed (8 hour) meeting (split into 2 sets of 4 hours, the first one to discuss requirements and the second one to discuss / agree what they will commit to doing in the 30 day Sprint). I've been thinking about this a lot recently - I really want the guys to fully embrace SCRUM (and they want to also) but this particular concept is proving a difficult hurdle to overcome. I think that the root of this is that the team had been working in a classic Waterfall methodology (and had been burnt a number of times on late delivery of features / releases). The word commit seems to be the problem. - Their current understanding / interpretation of commit is : "it must be done or we're going to take heat over late delivery".
- Whereas the agile understanding / interpretation of commit is : "we will do everything we reasonably can to deliver the feature / release"
It's actually quite a big step / leap of faith if you have only been used to "it must be done by dd/mm/yy". I like it's going to require me forcing the issue so that we do one Sprint in this manner and then demonstrates to everyone that there is no blamestorming if we're late or drop features The reason (I suspect) that it works is that with SCRUM you get continual and accurate feedback from the daily Sprint meetings, so if things do go off track then it's visible and corrective action can be taken earlier.
We had a customer issue yesterday that manifested itself as the user getting a HTTP 401 error when trying to connect to a Website (that is part of our Product). The user was logged into the domain, the virtual directory was set for 'Windows Integrated Authentication' so they should have been able to connect no problem. After so investigation we opened the IIS logs and found that the substatus code was 2 (HTTP Error 401.2 - Access denied by server configuration). A bit of searching around the Microsoft KB unearthed this article: Troubleshooting HTTP 401 errors in IIS Common reasons • No authentication protocol (including anonymous) is selected in IIS. At least one authentication type must be selected. For more information, click the following article number to view the article in the Microsoft Knowledge Base: 253667 (http://support.microsoft.com/kb/253667/) Error message: HTTP 401.2 - Unauthorized: Logon failed due to server configuration with no authentication • Only Integrated authentication is enabled, and an older, non-Internet Explorer client browser tries to access the site. This happens because the client browser cannot perform Integrated authentication. To resolve this problem, use one of the following methods: • Configure IIS to accept Basic authentication. This should only occur over SSL for security purposes. • Use a client browser that can perform Integrated authentication. Internet Explorer and new versions of Netscape Navigator and Mozilla Firefox can perform Integrated authentication. • Integrated authentication is through a proxy. This happens because the proxy doesn't maintain the NTLM-authenticated connection and thus sends an anonymous request from the client to the server. Options to resolve this problem are as follows: • Configure IIS to accept Basic authentication. This should only occur over SSL for security purposes. • Don't use a proxy. Turns out our customer was using a Proxy Server - adding the FQDN of our Website component to the proxy exclusions list solved the problem.
With the move to Office 2007, I am relearning a lot of the UI - where things are etc. which is a real pain - not that I'm against change, just that it's lowering my productivity whilst I push all the Office 2007 into my head and let the Office 2003 stuff fall out... After using a suite of application that have not really changed the layout / structure of how to enable / start / engage specific features for 11 years (at least - going back to Off 95), you get really used to where things are.... Today I found myself wanting to 'Apply Conditional Formatting' to some cells in Excel. My immediate action (drilled into me from 11 years of using the Office suite) was to go to the 'Format' menu - ah no menu's in Office 2007... Lets look at the ribbon bar - not on the 'Home' tab - browse through the others - nope still cannot find it (and browsing through the ribbon bar icons/button is not an easy process - you really have to LOOK and digest what you are seeing). Was there a shortcut key for it in Office 2003 - can't remember (since verified there is not), so at this point I started on the route of 'ok lets add it as a button to the 'Quick Access' bar' - but, come on, that's not good.... I'm a great advocate of many of the things Joel says in terms of 'software usability and discoverability' (covered well in his book 'User Interface Design of Programmers' ) and am feeling the pain of 'Learned Helplessness' - here is Joel's great post on this whole area. I was thinking about the impact of such a radical change on a smaller organization (like the place I work - C2C). I have gone to great lengths to get the development team to read the aforementioned book and understand that our software must be easy to use and discoverable (because no one reads manuals). If we made such a radical change then the support guys would be swamped - it would be unmanageable. Doesn't happen that way with Microsoft, the average Joe doesn't have a support contract for Office.... I guess it's time I did some research and found if others are having this pain, what the options are and maybe even read the manual (buy a book).
I was really excited by the Blogging feature Word 2007 - It looked really good, easy to use and some of the formats you can do to a picture are pretty cool. As soon as I found it I tried to set it up with this dasBlog account - Word 2007 is supposed to support the metaWebLog API (which dasBlog supports from v1.9), so in theory it should have worked - however it didn't work fully. I could upload new blog posts but it didn't like the posting of images - in returned a message saying it was not supported and I should use FTP upload instead. I wasn't happy with this as the metaWebLog API has a newMediaObject method which allows for uploading of images etc and I know it is implemented in dasBlog (I think Omar Shahine added it).  Anyway, I emailed Joe Friend (the MS guy who originally posted about this feature of Word) - he has since moved on so couldn't help (in fact I think my email to him was the catalyst for his Email is now off post - oops)... The annoying thing is that Windows Live Writer supports the metaWebLog API implemented by dasBlog and can upload images fine.... Mmmmm, something not right here - taking things into my own hands, I cracked open Fiddler and compared the HTTP request / responses between a Writer posting and a Word posting. The Word postings always fail on the newMediaObject calls - here is a screenshot of the request / response from Word. Looks like Word is trying to pass the blogid parameter as an int and not as a string as the spec dictates... As far as I know, Word works correctly with MySpaces, Blogger and a few other blogging engines - maybe they are not as strict as dasBlog when checking the parameter types passed ?? I suppose I could write an HTTPHandler or something to convert that type description from an 'int' to a 'string'.
I'm not 100% sure about this but, from this status bar text, captured whilst Word 2007 was opening (slowly) it looks as though it is trying to check / connect to a printer when the application opens.
Not what I want when I'm working in a remote office and haven't yet changed my default printer.
Did previous version do the same ?
I've had Vista Ultimate on my Acer TravelMate 3012 laptop for about a week now. The experience is OK, but I'm not wowed.
I'm not really getting any benefits from Vista :-
- I had to turn off User Account Control (UAC) as it was just too annoying.
- My built in Logitech OrbiCam works intermittently (I have to disable it then re-enable it via the Device Manager).
- My HD Audio is no longer working (no audio at all from the laptop)
- I had to turn off the new Start Menu and go back to the old one (just couldn't get on with it)
- The new Aero UI is neat and fancy - but a tangible benefit ? not really.
- Windows Sidebar, handy, but I had it with Google Desktop Search a year ago and from other apps before then.
- Visual Studio 2005 has a number of known issues when running on Vista.
- I can't run Powershell on Vista (other than Vista RC1)
In general the system feels slower than WinXP, even though I have a Windows Experience Index of 3.0.
Having to wait for FileSave dialogs seems to be common to many apps now. I regularly get black screens for a few seconds while a window closes.
As a power user it worries me greatly that I not 100% sure where files are in the hierarchy - there is a lot of diverting / soft linking of directories going on and files seem to be ending up in places they just shouldn't be (even although it work correctly)
On the Up Side, I am loving the Snipping Tool - I think comes from the Tablet PC tools section of Vista Ultimate, but it really is great.
I used to use Cropper from Brian Scott, but the Snipping Tool is streets ahead. It allows me to take a snip of the whole screen, of just a window, of a (mouse or stylus) selected rectangular area or of a freeform selected area. As soon as I have the snip I can do some basic editing - just the job for graying out / overwriting of usernames / passwords etc.
All in all, I don't see any real benefit over WinXP. I think the benefits of a move to Vista will be a tough message for Microsoft to get across.
Even though I don't feel as productive with Vista (in comparison to XP) I'm going to stick with it and see how things are when I have been completely immersed for a few weeks and am used to it - watch this space for a further update...
Windows Live Writer is currently being a real pain for me. I have my 'My Documents' redirected to a network drive in our UK office (where I usually work), but I am currently in our Westboro, MA office so my 'My Documents' is now effectively on the end of an interoffice VPN.
This seems to be causing all manner of issues with Windows Live Writer (using Process Monitor I can see it doing file reads / updates every second or so for all the recent posts and draft posts – horrible). It hangs for minutes at a time (and causes Outlook to hang during this period also) – in summary it's unusable (when I'm connected to our corporate network, when I'm disconnected it's fine)...
So, I've been looking at blogging from Word 2007 – I've actually only just found that it can do it (whilst looking for the Save As menu). Just set up my account details – very simple...
The insert picture options and other formatting options are excellent (at least in Word they are, let's see how it turns out on the website). The picture to the left (there should be one) should have a kind of 3D perspective (similar to the new Aero Tab Switching in Vista)
Category insertion is a bit long-winded, I need to click 'Insert Category' and then choose from a drop down – so multiple categories takes a bit of time... Still, it does find all my existing categories and allows me to define others.
OK, fingers crossed, let's see how things when published...
UPDATED:
Unfortunately it didn't work !! Word could not handle uploading images to the metaWebLog API implemented in dasBlog - strange because Windows Live Writer handles it just fine. That's a real pain as the image formating options in Word 2007 are stunning. Here is the that should have gotten posted first time (and inline) above (added manually).
I am/was a big fan of RSS Popper - when using Outlook 2003 it allowed me to pull blog posts into a selected folder in my mailbox (I used cached mode, so it was also available offline). It is currently at version 0.36 and has support for downloading enclosures (great for grabbing podcasts) and a neat feature where you can subscribe to blogs containing iCal's (and RSS Popper automagically creates meetings in your calendar for the iCal events - sounds really cool, nothing that I've ever used though). Anyway, I've migrated my work laptop to Vista and Office 2007 and as Outlook 2007 has built in support for RSS feeds I've not installed RSS Popper. The RSS support in Outlook (apparently) based around the new Common Feed Store of Vista - this allows multiple apps to access / store your chosen RSS feeds, for example if I mark the post as 'Read' in IE7 then that fact is reflected when I look at it in Outlook RSS. It's pretty simple to define new feeds - it's accessed from 'Tools -> Account Settings...' and is configured in much the same way as you configure an email account. Items are added to the defined folder as posts with any enclosures added as attachments to the post.
One of the first apps I loaded onto my laptop (after paving it and installing Vista Ultimate) was Windows Live Writer (which I'm using to compose this post - on a plane at 38,000 ft on my way to Boston).
So it all installed OK, I ran it and it launches straight into the config wizard (setting up your blogs) - I entered my site, username and password and hit next... Bang it fails - apparently it timed out.
OK, maybe the wrong password or something - reenter it - same thing...
Check the website is working - Yes.
Run this same config on my WinXp machine - Works OK ???
Lets look at the logging - seems to be found at :
C:\Users\%USERNAME%\AppData\Local\Windows Live Writer\Windows Live Writer.log
This gives me an error message as follows :-
WindowsLiveWriter,1.2012,None,00001,27-Nov-2006 11:32:13.063,"Unexpected exception occurred while processing resource Providers.BlogProvidersB2.xml: System.Xml.XmlException: '--' is an unexpected token. The expected token is '>'. Line 31, position 3. at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.DtdParserProxy.System.Xml.IDtdParserAdapter.Throw(Exception e) at System.Xml.DtdParser.Throw(Int32 curPos, String res, String[] args) at System.Xml.DtdParser.ThrowUnexpectedToken(Int32 pos, String expectedToken1, String expectedToken2) at System.Xml.DtdParser.ScanClosingTag() at System.Xml.DtdParser.GetToken(Boolean needWhiteSpace) at System.Xml.DtdParser.ParseEntityDecl() at System.Xml.DtdParser.ParseSubset() at System.Xml.DtdParser.ParseExternalSubset() at System.Xml.DtdParser.ParseInDocumentDtd(Boolean saveInternalSubset) at System.Xml.DtdParser.Parse(Boolean saveInternalSubset) at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl() at System.Xml.XmlTextReaderImpl.ParseDocumentContent() at System.Xml.XmlTextReaderImpl.Read() at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace) at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc) at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) at System.Xml.XmlDocument.Load(XmlReader reader) at System.Xml.XmlDocument.Load(Stream inStream) at WindowsLive.Writer.BlogClient.Providers.BlogProviderManager.ReadXmlBlogProviders(Stream blogProviders) at WindowsLive.Writer.CoreServices.ResourceFileDownloader.ProcessResourceSafely(String name, String resourceUrl, Int32 requiredFreshnessDays, Int32 timeoutMs, ResourceFileProcessor processor)",""
Looks like there is a error in the XML somewhere, so I pull my feed and validate it - looks like valid RSS2.0.
Turn OFF Vista's crazy (and plain annoying) Use Account Control (UAC) - the source for all the 'grey screens of iritation' I get when trying to do ANYTHING - No change.
OK, it's trying to get config data from/for me right ? - I have that config data on my desktop (WinXP) already so lets just copy it over. Examine the WinXP desktop for the config data - find it in the registry under : HKEY_CURRENT_USER\Software\Windows Live Writer : a whole raft of reg keys.
Export the whole shebang - merge it into the Vists machines registry - rerun Writer - all the config data is in there (excellent I can now post) !!
Copy the reg setings away to another drive in case I have to pave the machine again.
 |
I'm very impressed with the improvements in Outlook 2007.
The ToDo bar is proving a real godsend - it can (optionally) display a calendar (one or more months), appointments (fill the remaining space in the ToDo Bar or a only a fixed number of appointments, and Tasks.
Left is a screen shot of mine with one calendar month and the rest filling up with appointments.
It can get to be a bit too much data, especially if you have a couple of days with just one or two appointments then the eight or ten it displays (on my 1280 * 800 12.1" laptop screen) can cover a whole week and it';s not easy to see how it splits down into days - be nice to see this somehow color coded so that each day is a different color...
I am also loving the category features - tagging a mail with a articular category is now a simply right click in the 'category' field (if you have it displayed) or a single left click to tag it with the 'default category'
I use categories to do all my filing (in a Frankenstienish Getting Things Done kind of personal prductivity scheme) so this really speeds me up. I used to have about 12 common categories as macro buttons to allow me to do this, thats all superceded now... My whole custom filing/ GTD scheme is a single macro to explore the categories of an item and move the item into a folder of that (category) name - much easier.
You do lose a lot of real estate to the ribbon bar when composing messages though..

Do people really need that level of document editing / markup when composing messages ??
|
Last weekend I upgraded my work laptop to Windows Vista (Ultimate edition) and Office 2007 Professional (I believe these are actually released 'officially' to business customers tomorrow (30th Nov), but I got the RTM copy fro MSDN Subscriber Downloads.
Anyway, the Vista install went very well - nice and easy, no issues with drivers etc, so I was pretty pleased with that. The Office 2007 install was as easy as you would expect,pop the DVD in, select some options and wait 20 minutes while it coies all the files over.
After a couple of hours playing around ith the OS (getting dasBlog working, installing all my usual apps and what have you) there were a few annoyances (OK, I'm just not used to the 'new way' yet so I get annoyed that it takes me longer to do things - I'm an impatient git)...
I didn't spend lot of time with Office 2007 until getting back into the office on Monday. I have now been using it in anger for 3 days and I'm not really impressed at all. Trying to be objective - I don't think it's just because of the UI changes (ribbon bar etc) meaning that I don't know where to find it (off the top of my head) - I really think that the ribbon bar is going to be a flop...
I'm a power user, I usually find software easily 'discoverable', but I find myself 'lost' in the ribbon bar. It is supposed to give easy and quick access to the commonly used features of the application - take Word for example, if I'm typing a document then one of the most likely things I'm going to do is print it, yet there is no print button, initially I could not find it at all - at a guess I clicked the orb and horrah it brought up a menu (where I then found Print, Send To, Save As - all my commonly used functions).
Maybe my complaint is not that the ribbon bar is bad, just that the items they have decided to place on he ribbon bar and the buttonns they decide to display based on context are wrong (or at least wrong for me).
Here is a screenshot of my ribbon bar - it covers three lines / rows and also looks like double spacing between the lines / rows (so I lose four lines / rows to button now - Word 2003 took two) but look at the style section - it takes up about 40% of the available ribbon bar for something rarely used (by me at least).

I do like the context toolbar that appears beside text or other objects in the document as you work on it. So, your typing text, you select a word, line, paragraph or whatever and a little opaque toolbar appears with some 'common' options on it. Mine appeared with Bold, Center, Italic, Font Name, Font Size, Font Increase, Font Decrease, Text Color, Highlight Color, Block Indent and Block Unindent. The one thing I was looking for, Underline, was not in there....
I think (??) that it is supposed to be self learning, so we'll see how it goes, but from the last three days my productivity is down about 20%.
At work I have been the champion of an Integration Framework for our Archive One product. This is a set of API's, events and open file formats embedded into the Archive One products that allow customization 'around the edge'. The kind of thing that can be done with the Integration Framework is running searches, interworking with the AD schema, running archive policies, integration into Network Management Systems or Document Management Systems and the like - it really opens the product to other business systems as either the slave (other systems controlling Archive One) or the master (other systems being controlled by Archive One). We have been writing up the API documentation recently and had initially started this as a (Word) document we would publish to customers and developers. I looked into NDoc which now seems dead (at least for VS2005 and .NET2.0) and then came across Sandcastle. Sandcastle is Microsoft's answer to NDoc, it allows the collation and generation of documentation from the XML comments embedded in your code Right now it is at CTP stage and is command line driven - a few projects have sprung up which provide a UI for it (backing on to the CLI). One is a VS2005 add in (which I installed but it wasn't immediately obvious how to use it, so I didn't really pursue) and other is SandcastleGUI - this provides a single form where you choose the options, point it to the folders containing the Sandcastle app, the code DLLs and where you want the docs to end up and then simply kick it off. When you hit 'Start Documenting' it closes the form and fires off a command prompt window (batch files) which in turn fires off other command prompt windows until it's collated everything and built the documentation. It allows you to generate html documents - a whole website, multiple pages, images etc or a compiled help file (.chm) or even both if you wish. Another of the options is 'Online MSDN Links' this provides a MSDN link for every object type it can find in the base class library. Be warned enabling this option means it has to reflect through about 14500 classes / objects in the framework so that they can be indexed and used if found in your app / library. Enabling this option increases the time to generate from about 1 minute (on my Dual Core laptop) to about 15 minutes - I'd recommend disabling this option whilst developing the app / library and only enable it when you are doing the final or release build. The resulting documentation is really good quality - pretty much the same format as MSDN documentation. For the effort of a few extra XML comment lines in your code this provides great value and a very comprehensive resulting document. The easiest way I have found to integrate this into VS2005 is to set it up as an External Tool. I create a folder under the solution folder named 'Documentation', I run SandcastleGUI manually the first time around, do all the required configuration and then save the settings to a file in the solution directory (don't save it in the 'Documentation' folder as that is cleared out with each Sandcastle run. I have an 'External Tool' configured which points to SandcastleGUI with parameters of : /document $(ProjectDir)\settings.SandcastleGUI (I called the settings file 'settings.SandcastleGUI') and called the tool : Sandcastle This Project This allows me to simply click this tool and it will go away and create all the documentation (with my chosen parameters) for the project. As I mentioned this is CTP at the moment - I look forward to the release version, hopefully fully integrated into Visual Studio and stylesheets that exactly mimic MSDN.
At work, we use SupportSuite for support case tracking. This is a real neat product but the support is dreadful. I was running version 3.0.0.80 and there are a few problems with it, they recently announced version 3.1.40. I set up a testing copy and tried an upgrade - no joy, 404 page after about 0.00065353 nanoseconds, spent ages trying to resolve and / or get an answer out of Kayako but nothing. I did like the look of the new version and it solved a number of small but annoying issues we were seeing, so I implemented it in parallel (on port 81) to our current system, we had it all configured, ported across all the Knowledgebase data (Import / Export from the app), ported across all the user accounts (manual DB table hacking) and basically got everything ready for the 'big bang' migration. Anyway I decided the big bang migration should happen this morning (Friday is typically a quiet day) - I had everyone port their own cases across, put links from the old case to the new case and links from the new case to the old case. Next step was to move the old system to port 8080 and the new system from port 81 to port 80. Here's what happened :- - Changed the website ports (in IIS) so that the old system uses port 8080 and the new system uses port 80
- Modified the settings (stored in the mySQL database) to ensure the URL was correct (i.e. removed :81 from the end of the URL)
- Cleared the SupportSuite cache
- IISRESET
- Closed all the browser sessions.
- Opened a browser and browsed to the new site - horrible page with no images and bad formatting.
- Ctrl F5 to refresh the browser again - same detail
- Delete all the temporary files from IE followed by another Ctrl F5 - same detail
- Examine the properties of the images that were not loading - they are still pointing to port 81
- Ramp up my sense of urgency as we have now been off air for about 30 minutes.
- Browse the mySQL database and spot a settingcache table - run a SELECT * FROM settingscache WHERE data LIKE '%:81%'
- AH !! find the row with the cached URL - change the URL and UPDATE, on to a winner here...
- Ctrl F5 - gets a message stating that SupportSuite is not found and I should run setup again - !!WHAT!!
- Look at the settingscache table again - AH !! there is a 'hash' field - Stumped !!
- Change the new system back to port 81
- Added a new website on port 80 with a permanent redirect to port 81…
- Opened port 81 through our firewall...
- Fixed !! At last !!!
It seems the settingscache table is built the very first time the web app runs and then is NEVER updated EVER. It's working now but I hate leaving niggly issues like this (needing both port 80 and 81 to function correctly) - further investigation on Monday, but if this is a real bug then given my experience with Kayako to date I expect the easiest route will be to configure it on another server (ON PORT 80 !!) and then move it across...
One of my gripes with dasBlog is the reporting. To get to reports I have to browse to my blog, login and then view the reports online - bit of a pain doing this every day (yes I am so vain that I like to see my stats on a daily basis). So I spent a few hours recently adding an 'Daily Activity Report' feature. It was surprising easy - checkout (get a working copy) of the source from sourceforge (browse it here https://svn.sourceforge.net:443/svnroot/dasblogce/trunk), familiarize yourself with it, add your changes and create a patch. Send the patch to someone with admin rights (so it can be checked in) and that's it... I'd recommend to anyone to try it out... Anyway the 'Daily Activity Report' feature - basically starts a background thread which caches the current date and then ticks every hour. Each tick it will check the current date against the cached date and if they do not match then it will send an email to either the Notification list or the Site Owner / Administrator. It is configured by simply checking a box in the configuration page (in the SMTP Server section) The email contains similar detail to that of the 'Activity... Referrers' page. I also made the method / class that implements the creating / sending the report public so that it can be extended - I was thinking along the lines of a 'Send Daily Activity Report Now' button or enhancing the Mail-To-Weblog to monitor for a specific phrase in the subject and if found to send the report (maybe also specify the date)... Watch this space for updates...
This is the forth (and last for the moment) article on Writing Supportable Software, helping all those customers and support engineers work with our software products and troubleshoot them themselves (i.e. going as far as possible down the troubleshoot path before referring it back to you). You can the first article here... and the second article here... and the third article here... This final article is all about paranoia and the fact that customers (as much as we love them, and need them to pay our salaries) are not to be trusted one little bit... We've all been there, troubleshooting a problem, ask the customer what parameter X is set to, go off down a whole path of investigation, find nothing, scratch our head, check parameter X for ourselves and find it's set to something different (and the whole problem resolution falls into place). It's not that customer purposely try to be difficult, simply that they don't know the system / software as well as you do - quickfire questions about the Primary Master Lookup Port and the Lookup Master Access Port get them all confused - they're probably under pressure for their boss to get it fixed, they've tried a whole load of things, the last time they looked it was set to 5465ABBG_Master but in the confusion they forgot they changed it to Lets_Just_Try_This_Option. They best way to determine what variable / options / configuration your system is using, is to write it out to a trace file, on start up, before a processing run, before you use it (whenever is appropriate - and that means, if it could have been changed between now and last time we wrote it to the log then write it again) If ever there has been a thing that wastes the time of support people it is working on the assumption that, the value the customer told them it was set to was the actual value that it was set to.
This is the third article on Writing Supportable Software, helping all those customers and support engineers work with our software products and troubleshoot them themselves (i.e. going as far as possible down the troubleshoot path before referring it back to you). You can the first article here... and the second article here... This article is all about identifying when and how you are using external systems and services. Most enterprise application work with external technologies or services, for example the company I work for (C2C) build applications that work with Microsoft Exchange Server, maybe you consume a particular web service or make LDAP calls. Whilst you can reasonably expect the customer to provide a stable working environment for your system / software, life is not always that rosy. I've worked with Enterprise systems that have been dependant on SQL Server, Exchange, LDAP, Web Services, VoIP gateways and many other systems... For experience, there is nothing that irks a customer more than a vendor who points the finger blindly at some part of the environment or system infrastructure. As a support guy for a vendor you have to take the pain and go that extra mile to hold the customers hand and demonstrate how / why / where the environment is going wrong. Developers can make this considerably easier by identifying (in a log file or the like) exactly what services your calling out to - and how long it's taking. I can't tell you how many times I've been troubleshooting an issue only to eventually end up some service the software was expecting to just work was not just working - but that's only half the battle, when you've found that you then need to demonstrate to the customer that it's the service that is not working (and if it was working then your system would be working also) A great example of this is customers have some kind of screwed up AD implementation, so we'll make a LDAP call thinking it's going to the local DC but in reality it finding some old dusty DC in Alaska on the end of a Dial Up connection and it will time out. Another would be a system making calls to a SQL server but the machine making the calls cannot connect to the SQL Server, maybe because there is a firewall inbetween (and the SQL network port 1433 ?? is locked down) So, when writing your code, identify these external service and provide the verbosity in your log files or your application status screen that allow the support engineers to determine which services are failing (and to demonstrate the fact to the customer) I haven't even touched on how often we find that our systems / software stops working, customer calls and you spend hours troubleshooting only to find that the customer took a service offline, or decommissioned a server, or added a firewall - you get the idea...
This is the second article on Writing Supportable Software, helping all those customers and support engineers work with our software products and troubleshoot them themselves (i.e. going as far as possible down the troubleshoot path before referring it back to you).
You can the first article here...
This article is all about what you do (what you make your software do) when it fails. So, we all know that software has bugs from time to time, one of the keys to making it Supportable is providing a clean option of recovery from any error / bug / crash...
This is all about thinking in manner of two stage commits. So for a two stage commit system you fire off all the individual components of a transaction, they all report back that they completed successfully and then you do the final commit of the whole thing...
Using two stage commits for all the data moving, updating of entities is essential in building supportable software and for general customer satisfaction.
I worked with an application once that wrote (a lot of) data to the file system (tens of gigabytes per process run). The original design was to stage files in the same folder that we stored the data long term and we had no effective way of doing two stage commits - the result was that when a process run failed we left the part processed data files in the long term storage folder along with all the correctly processed data - all the filenames were of a similar format so it was hugely difficult for the customer or support guys to filter out that part processed data and remove it - what's worse is that we would reprocess the unfinished process run, if it failed again then there would be another set of part processed files with the same data in it - etc etc...
The end result of this was lots of spurious, part processed data files on the customers system, taking up hundreds of gigabytes of disk space and we couldn't clear it out.
When I noticed this, I had the dev team change it to a two stage commit process (preventing it happening again) and had to write a trawler application to go back in and clean up the part processed files.
That is just one example, the general idea is to make sure that any failures / back outs / crashes clean up in an intelligent way or that the part processed data is stored / tagged in such a way as to be easily identifiable and 'cleanable' by your support guys or the customer themselves.
At work (C2C) I'm responsible for the development team and the technical support team and it proves to be a surprisingly difficult task maintaining a balance between their respective objectives - the two extremes are : - Support has little or no contact with development, bug escalations are done in a very formal way and the overall drive is to ensure development are not distracted by support work.
- Support has unhindered access to development, can draw on their expertise / knowledge whenever they like, the overall drive being to have happy customers (via quick and accurate resolutions)
Neither of these work well in a business - with the first you sacrifice customer satisfaction for development productivity and in the second it's the other way around... The key is finding the balance, but it's tough finding that balance, and there is no one answer or simple formula - it depends on many factors where (between the two extremes) you find the balance (product quality, support team knowledge, customer expectations etc) One thing that helps is getting the development team is to write Supportable Software - this means developing it in such a way that we maximize the troubleshooting efforts that can be carried out before it has to be escalated to the development team. There are a number of facets to this, I had initially planned to cover them in one article but when I started, it became apparent that there was too much for one article and it should probably be split into each key area in it's own article. The first area (topic for this article) is Tracing / Logging for Maximum Effect Let's kick right off with an example - consider the following trace file output : 10/10/2006 12:34:56.987 LDAP lookup failed with result = -214756544 Yes it tells you exactly what went wrong. A support engineer reading that can clearly see there is a problem with LDAP but nothing else. So what's his next step ? - escalate the case to the development team. Compare that to : 10/10/2006 12:34:56.987 LDAP lookup (' CN=Ken Hughes,DC=c2c,DC=com') to uk.c2c.com failed result = -214756544 A support engineer reading that line can now check : - The server uk.c2c.com is up and working
- Using LDP run the same query and check the results
Maybe the server was down, maybe the query works if the user is logged as an Administrator but not as the account running the software - there is a whole avenue of additional troubleshooting that the support engineer can investigate simply because the trace file was a little more verbose... This is true many different areas :- - Web Services - don't just say it failed, tell the user what URL was being used - support guy can check out the web server and DNS resolution
- SQL stuff - it's probably apparent which server your going to, but what about tracing out the SPROC your using or the SQL query string itself (especially if it's dynamically generated in code)
- Remoting / DCOM - Why settle for CoCreateInstance failed when you could specify the destination server and the class your trying to create
We could all think of more, but the general idea is - make the tracing sufficiently verbose as to allow engineers to investigate why the error occurred. If your using external or third party services (DNS lookups, LDAP, SQL, Exchange, WebServices, DCOM etc etc) then give the details of where your going to and the parameters your using. Bear in mind that as a developer, if your tracing out magic numbers or sparse data that only really make sense to you, then when someone sees it in a trace file it's coming straight back to you....
The company I work for (C2C Systems) are a Microsoft Gold Partner this is great in that it gives us a whole bunch of licenses for internal use, it also gives us (almost ??) unlimited access to software for test, development and demonstration. The problem is :- Demonstration licences are provided for customer demonstration purposes only – that is, licences to be used only by employees of the company with customer contacts. [extracted from the Microsoft Partner Programme document (v7.1)] When you think about it, this is incredibly limiting - it means that someone from the company has to be present at the demonstration (in person or remotely)... Now, our solution (Archive One, email archiving) works with Exchange Server, our normal demos are on a system with Exchange 2003 (aside: although we do work with Exchange 2007 already) meaning we need Windows 2003 and all the Active Directory baggage. Virtual Server technology (in fact any virtualization technology) allows me to generate a number of Virtual Machine images and run them on one machine and hey presto I have a full demo / evaluation environment - the limiting factor is licensing - If I want to just give people (resellers and / or customers) copies of those images so that they can easily test / evaluate our solution then I have to license it (Win2003, Exchange 2003, WinXP etc) I think Microsoft really missed a trick here - some kind of (slightly) crippled or trial version of the OS and apps, that partners can redistribute, would have been great - BANG - you have a easy way for everyone to roll out full demo environments of there software / systems. As a customer I can grab the DVD (or download the images) and evaluate without having to go through the pain of putting together a bunch of servers, setting up a test environment yadda yadda... As a partner I can grab the DVD (or download the images) and immediately go out and start demo'ing it to my customers (the same way that vendor does)... Anyway, I'm trying to beat up the Virtual Server / Licensing team over this...
Singleton Design Pattern, is a solution to a common problem in the software domain where you want to create ONE AND ONLY ONE instance of an object/class. Put simply, it stops client applications creating their own instances of an object and routes all creation of the object through one method. If an instance of the class already exists then that instance is returned, if an instance of the class does not exist then a new instance is created. So, no matter how many clients access the class there is only ever one instance (that all clients access) Here's some sample code of how to achieve a Singleton class : using System; using System.Collections.Generic; using System.Text; namespace KenAndSarah.GpsControl { public class GpsControl { private static GpsControl instance = null; private GpsControl() { // do not allow a public constructor } // call this to get (or create) a reference to the class public static GpsControl GetGpsControl() { if (instance == null) instance = new GpsControl(); return instance; } } } So to clients would simply use it like this GpsControl gps = GpsControl.GetGpsControl(); Any subsequent clients who make the same call get a reference to the already created instance of the class.
Here's the code for the macros I created - feel free to copy / compile it yourself. I also included a compiled DLL here - BUT it is compiled against .NET2.0 so will only work if your hosting Dasblog in a ASP.NET2.0 virtual directory. - Copy the compiled DLL into your /bin folder
- Edit your Web.config file, locate the <newtelligence.DasBlog.Macros> node
- Add the following element <add macro="khmacros" type="KensDasblogMacros.KensMacros, KensMacros"/>
- Edit your template pages to include <%TrackbackCount()|khmacros%> or <%TrackbackountAll()|khmacros%> or <%KensBlogStats()|khmacros%>
using System; using System.Collections; using System.Text; using System.Web.UI; using newtelligence.DasBlog.Runtime; using newtelligence.DasBlog.Web.Core; using newtelligence.DasBlog.Util; namespace KensDasblogMacros { public class KensMacros { protected SharedBasePage sharedBasePage; protected Entry currentEntry; public KensMacros(SharedBasePage page, Entry entry) { sharedBasePage = page; currentEntry = entry; } public virtual Control TrackbackCount() { if (this.currentEntry != null) { int trackbackCount = 0; IBlogDataService dataService = sharedBasePage.DataService; trackbackCount = dataService.GetTrackingsFor(currentEntry.EntryId).Count; return new LiteralControl(trackbackCount.ToString()); } return new LiteralControl(""); } public virtual Control TrackbackCountAll() { int trackbackCountAll = 0; IBlogDataService dataService = sharedBasePage.DataService; DateTime[] daysWithEntries = dataService.GetDaysWithEntries(UTCTimeZone.CurrentTimeZone); foreach (DateTime day in daysWithEntries) { EntryCollection entries = dataService.GetEntriesForDay(day, UTCTimeZone.CurrentTimeZone, String.Empty, 1, int.MaxValue, String.Empty); foreach (Entry potentialEntry in entries) { trackbackCountAll += dataService.GetTrackingsFor(potentialEntry.EntryId).Count; } return new LiteralControl(trackbackCountAll.ToString()); } return new LiteralControl(""); } public virtual Control KensBlogStats() { StringBuilder sb = new StringBuilder(); try { IBlogDataService dataService = sharedBasePage.DataService; DateTime monthFirst = new DateTime((DateTime.UtcNow.Year), (DateTime.UtcNow.Month), 1, 0, 0, 0); DateTime monthLast = new DateTime((DateTime.UtcNow.Year), (DateTime.UtcNow.Month), DateTime.DaysInMonth(DateTime.UtcNow.Year,DateTime.UtcNow.Month),23,59,59); DateTime weekFirst = Macros.GetStartOfCurrentWeek(); DateTime weekLast = Macros.GetEndOfCurrentWeek(); DateTime yearFirst = Macros.GetStartOfYear(DateTime.UtcNow.Year); DateTime yearLast = Macros.GetEndOfYear(DateTime.UtcNow.Year); int allEntriesCount = 0; int yearPostCount = 0; int weekPostCount = 0; int monthPostCount = 0; int trackbackCount = 0; DateTime[] daysWithEntries = dataService.GetDaysWithEntries(newtelligence.DasBlog.Util.UTCTimeZone.CurrentTimeZone); foreach (DateTime day in daysWithEntries) { EntryCollection entries = dataService.GetEntriesForDay(day, newtelligence.DasBlog.Util.UTCTimeZone.CurrentTimeZone, String.Empty, 1, int.MaxValue, String.Empty); allEntriesCount += entries.Count; foreach (Entry potentialEntry in entries) { if (potentialEntry.CreatedUtc > monthFirst && potentialEntry.CreatedUtc <= monthLast) { monthPostCount++; } if (potentialEntry.CreatedUtc > weekFirst && potentialEntry.CreatedUtc <= weekLast) { weekPostCount++; } if (potentialEntry.CreatedUtc > yearFirst && potentialEntry.CreatedUtc <= yearLast) { yearPostCount++; } trackbackCount += dataService.GetTrackingsFor(potentialEntry.EntryId).Count; } } int commentCount = dataService.GetAllComments().Count; sb.Append("<div class=\"blogStats\">"); sb.Append("<table border=\"0\" width=\"100%\">"); sb.Append("<tr><td align=\"left\">Total Posts</td><td align=\"right\">" + allEntriesCount + "</td></tr>"); sb.Append("<tr><td align=\"left\">This Year</td><td align=\"right\">" + yearPostCount + "</tr></td>"); sb.Append("<tr><td align=\"left\">This Month</td><td align=\"right\">" + monthPostCount + "</tr></td>"); sb.Append("<tr><td align=\"left\">This Week</td><td align=\"right\">" + weekPostCount + "</tr></td>"); sb.Append("<tr><td align=\"left\">Comments</td><td align=\"right\">" + commentCount + "</tr></td>"); sb.Append("<tr><td align=\"left\">Trackbacks</td><td align=\"right\">" + trackbackCount + "</tr></td>"); sb.Append("</table>"); sb.Append("</div>"); } catch (Exception ex) { sharedBasePage.LoggingService.AddEvent(new EventDataItem(EventCodes.Error, "KensBlogStats Error: " + ex.ToString(), String.Empty)); } return new LiteralControl(sb.ToString()); } } }
So, having recently updated this website to Dasblog 1.9, I decided it was time to check out the source and have a play around. The initial easy step to get involved seemed to be writing some Macros (I wanted to extend the default blogStats() macro to include Total Trackbacks and also add a Trackback Count to each post item in the footer. There is a great intro to Creating Dasblog Macros on their Documentation Site, also googling for Dasblog macros uncovered a few good sites Anyway, I cracked open VS and spent a couple of hours writing some new macros, compiled them, made the requisite changes to my homeTemplate and itemTemplate but they just seemed to be return null strings. Checking the (Dasblog) event log showed that it was failing the find the Type for my Macros. I checked and rechecked everything and was convinced that everything was as it should be. Stumped!! Viewed my DLL in reflector, typenames were all correct - what was I doing wrong ?? A quick post to the Dasblog developers mailing list resulted in someone suggesting that I check if I was running a .NET2 compiled DLL in a .Net1.1 IIS virtual directory - Doh !! Updated the virtual directory to ASP.NET 2.0 (easier than reverting to VS2003 from VS2005), 'touched' the web.config, refreshed the page and 'ta da...' Changes and source code to be rolled out to this web site in the next day or so (more testing to do on how ASP.NET 2.0 works out), 
Three months ago I implemented SCRUM for the development team I manage at work (C2C Systems). So, whilst I agree with some elements of Steve Yegge's comments about getting the best out of developers, I disagree with the blanket statement that all Agile methodologies are no good - I am a great advocate of SCRUM - and my reasons ?? I implemented it and it works !! Here's my comments / thoughts and experiences so far.... So far we have had 5 SPRINTs of between 1 and 2 weeks, and we are just getting to the stage where we have learned all (most of) the lessons and are in a position to begin 'living by it' So, how has it been, what benefits did it bring and is it successful or not. Better communication of project status - the daily SCRUM meetings (15 minutes at the end of each day), involving all developers are really working out well - the developers appreciate being 100% up to date with the status, understanding what everyone else is doing, how much work is still to do, how close we are to meeting the deadline / target. NOTE: We have a 10-15 minute meeting at then end of every day, the status sheet and burndown chart are both updated and published in a prominent position. There seems to be a general feeling that ticking things off the list gives a sense of progress (getting closer to the objective / target) - previously we simply had a big queue of things and it was not easy to gauge how far through we were or easily see how much closer we were getting to completing. Also, as each 'feature' is ticked off, I have more confidence that we can do a snapshot release or put together an early beta for a customer demo - basically it allows additional flexibility. Statistics / Status - I'm a great 'measurer', I love to measure every facet of what we are doing. All these stats are on the status sheet and are visible to everyone, so each person can see how they are doing (accuracy of time estimates, hours worked towards the Sprint / Backlog item, percentage of time spent on the Sprint - as a department we have a target percentage of work towards new software development - the Sprint - figure we need to achieve.) Estimation - as with any project there is a general bias towards overestimating - this is (I believe) reduced with SCRUM - one of the measures on my spreadsheet is the accuracy of the estimates. So, not only is there a measure on the spread of how well the developer estimated the time required but it is also very visible to everyone why we need accurate estimates (so we can effectively plan the Sprints). Early visibility of problems (allowing early corrective action) - this is the opposite of the above, under estimation - if this happens then at the very least I get almost immediate visibility of the issue and can take corrective action (more on this later) Identification of where we are lacking good process - measuring or noting the impediments gives a very good handle on where your processes are falling down, for example if the developers are spending 2 hours chasing down Product Management for answers to ambiguous requirement details then you know you need to improve the requirements process (yes you can see this in normal development lifecycle, but measuring it as an impediment give you good solid / tangible metrics to go Prod Mgmt with to discuss the issue and have them sort it out. Identification of where we were unexpectedly burning time that was not being allocated - what I mean by this is that we were averaging XX% of development time spent on new feature development, after a couple of Sprints we noticed that we had not been including time for: Code reviews, Demo'ing features to Support, Memory leak testing, Measuring performance metrics and the like - all necessary tasks but we had not been measuring them in our 'time towards new feature development'. Links / Useful Info. Control Chaos Mountain Goat Software The SCRUM Alliance Yahoo SCRUM Group A sample SCRUM Excel Spreadsheet that I use...
Quick update on the TaHoGen open source project...
I just tidied up the whole source tree, added all the projects in a logical layout to one solution. I also sorted out the Visual Studio addin with better error handling and added a Setup project so that it can be easily installed by an end user.
Murad's excellent SchemaBrowser was added added and checked in, now allowing us to glean data from databases to use in the code generation. We're closing in on CodeSmith...
Next step is to demonstrate use by including a number of templates.
The problem with the addin (that was so difficult to remedy) was MDA's - difficult to troubleshoot and even more difficult to fix.
When the addin is called by VS it tries to save a reference to the instance of VS that is creating it - this is so we can get a handle on the OutputWindow and add some new panes to it.
These sometimes (intermittently) get blocked by MDA's and the panes do not get created - the panes only show build output text so I added some error handling to continue processing even if we cannot write to the pane.
Anyway, if you want to take it for a test run, you can get it here.
Released today, a new version - get it here. They have added the following (list extracted from the Windows Liver Writer blog post)
The following is a summary of the changes in the Writer 1.0 (Beta) Update:
- Tagging support
- Support for Blogger Beta
- Categories are sorted by name and support scrolling, plus improved support for reading categories from your blog
- Improved startup performance
- Paste is enabled for Title region and TAB/SHIFT+TAB navigation between title and body supported
- Insert hyperlink added to context menu when text is selected
- Title attribute in Insert Link dialog
- Custom date support for Community Server
- Improved keyboard shortcuts for switching views
- Change spell-check shortcut key to F7
- Add ‘png’ to insert image dialog file type filter
- More robust image posting to Live Spaces
- Improved style detection for blogs
- Fixed issues with pasting URLs and links
- Remember last window size and position when opening a new post
- Open post dialog retrieves more than 25 old posts
From what I have noticed :-
- It still takes an age to open.
- There is still no support for adding a file to a post (and having it uploaded / FTP'd), so my 'Insert File (via FTP) plugin' is still valid.
- There is still no support to add new categories (you can choose from existing categories)
- The insert 'task box' does not provide a scrollbar
(so some items get hidden as you create more drafts)
Other things I noticed about the SDK when writing my plugin :
- No way to get a ref to the current blog provider
- No way to get properties for the current blog (this would be great as my plugin would be able to automatically pick up the FTP settings)
- The icon size for displaying on the Insert tab is a crazy 20x18. Why didn't they simply go with a standard size (16x16 for example).
See 'Insert File (via FTP) icon on the embedded image for how it looks when trying to scale a standard image to this custom size - AWFUL.
However, I can't complain, overall I'm pretty happy - it's FREE, it makes my post creating MUCH FASTER and the way it shows me how the post will look on the website (automagically using my website CSS / formatting) is just AMAZING
Blank entry, simply to list out the categories.
|
|
|
|
|
|