Out of Office

Sat, August 26, 2006, 12:43 AM under Personal
Last weekend we went to Amsterdam with my mates for stag do and yesterday I married Jenny at Brighton Town Tall (there will be a proper religious wedding in Greece next year).

So in a couple of hours we are flying to Malta for our first honeymoon (and some diving of course :-))

Normal service will resume on Monday 4th September – don’t call me, I’ll call you!

Vista: RegisterApplicationRecoveryCallback

Thu, August 24, 2006, 05:11 AM under Windows | Vista
We looked previously at RegisterApplicationRestart and that blog entry serves as the introduction to the Application Recovery APIs in Vista so I suggest you read that before continuing below.

To demo this, we'll start with the code we've already created.
f) For both samples, let's offer an additional user option for hanging the application. We can do this via a dedicated button like this:
    // hang
private void button3_Click(object sender, EventArgs e)
{
while (true) { }
}
g) Our pinvoke wrappers cover 3 functions RegisterApplicationRecoveryCallback, ApplicationRecoveryInProgress, ApplicationRecoveryFinished and a helper delegate as shown here:
    [DllImport("kernel32.dll")]
static extern uint RegisterApplicationRecoveryCallback(IntPtr pRecoveryCallback, IntPtr pvParameter, int dwPingInterval, int dwFlags);

[DllImport("kernel32.dll")]
static extern uint ApplicationRecoveryInProgress(out bool pbCancelled);

[DllImport("kernel32.dll")]
static extern uint ApplicationRecoveryFinished(bool bSuccess);

delegate int ApplicationRecoveryCallback(IntPtr pvParameter);
Taking advantage of the APIs involves two functions:
h) First, we register our interest to be called back, by passing in the method that must be called:
    private ApplicationRecoveryCallback mCallback;

// recover
private void button4_Click(object sender, EventArgs e)
{
mCallback = new ApplicationRecoveryCallback(this.RecoverIt);

IntPtr del = Marshal.GetFunctionPointerForDelegate(mCallback);

RegisterApplicationRecoveryCallback(del, IntPtr.Zero, 5000, 1 4);
}
i) Second, we need to write a method that will run our recovery code (I also used a helper method for code clarity):
    private int RecoverIt(IntPtr pvParameter)
{
// just an action that proves this runs
File.Create(Environment.CurrentDirectory + @"\recover.txt").Close();

int i = 4; //random number to simulate delay
while (i != 0)
{
bool b = this.Ping();
if (b) return 0;
Thread.Sleep(3000); //simulates some recovery action
i--;
}

ApplicationRecoveryFinished(true);
return 0;
}

private bool Ping()
{
bool esc;
ApplicationRecoveryInProgress(out esc);
if (esc)
{
MessageBox.Show("Cancelled");
}
return esc;
}
That's all there is to it. Now run your app, and after you have called RegisterApplicationRecoveryCallback, wait for 60 seconds before crashing/hanging the app via the appropriate button. Note how at that instance, in your application's folder an empty file is created (this is proof that your recovery method run).

The other relevant recovery functions that you could pinvoke are UnregisterApplicationRecoveryCallback and GetApplicationRecoveryCallback.
Incidentally, these restart and recovery APIs is what the new Restart Manager is based on.

channel9

Wed, August 23, 2006, 09:08 AM under Windows | Vista
...has my screencast on glass summarising my blog posts on the topic that regular readers will be familiar with. Go watch it!

...and this, this, this and that.

NxtGenUG chat

Tue, August 22, 2006, 03:36 AM under Random
Those crazy guys from the NxtGenUG are cornering anyone they can find, shoving a microphone in their face and recording short interviews!

Dave caught me at the Office event 2 months ago (little after I joined MS) and the results are up on their site (read or listen).

Vista: Application Recovery

Mon, August 21, 2006, 04:28 PM under Windows | Vista
Out of the many new native functions in Vista, two that I've been looking at using from managed code are the Application Recovery APIs.

There are 9 functions but two are the main ones: RegisterApplicationRestart and RegisterApplicationRecoveryCallback. These two serve two different, but complementary goals:
1. When your application crashes, it automatically restarts
2. When your application crashes, it gets a chance to save some recovery information

To demo this we need:
a) A new Windows Form application that has a button for crashing the application. Something like this:
// crash
private void button2_Click(object sender, EventArgs e)
{
int zero = 0;
int error = 5 / zero;
}
b) We must turn off .NET's exception handling. I've previously talked about global exception handling in .NET 2.0 but I never mentioned the ability to turn off plain exception catching, which we can do in our config file or in the Main function like this:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
c) We then need to re-declare in managed code the RegisterApplicationRestart like this:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint RegisterApplicationRestart(string pszCommandline, int dwFlags);
Taking advantage of the API involves two lines of code in two different places.
d) First, we need to actually tell Vista that we want to be restarted (do this in your form_load or wherever else you see fit):
RegisterApplicationRestart("some_text_like_eg_pathname ", 0);

e) Second, on startup check if our application crashed last time (and use the string we passed to the API call):
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
{
this.Text = args[1];
}
Now run your app, and after you have called RegisterApplicationRestart, wait for 60 seconds before hitting the button that crashes your app. If you have windows error reporting enabled, you'll see the dialogs for checking for a solution, sending information and sending additional information. This is an interactive process where you can OK or cancel communications with winqual. Either way, once those dialogs are gone, your application will restart :-)

The other relevant restart functions that you could pinvoke are GetApplicationRestartSettings and UnregisterApplicationRestart.

In the next blog post, we'll look at the RegisterApplicationRecoveryCallback.

Using Vista's search in your managed apps

Wed, August 16, 2006, 04:41 AM under Windows | Vista
In an internal conversation, someone indicated they were interested in using “search” from their application. There are two great sources for that:

Catherine’s blog entries and Ian’s screencast.
--
UPDATE: Also see a search sample

Windows Workflow Foundation (WF)

Mon, August 14, 2006, 02:31 AM under dotNET | dotNET
As I described previously, .NET Framework 3.0 is simply adding four elements to the released .NET 2.0 bits. While these library/framework bits are released with Windows Vista at the end of the year, the VS/tools side of things is planned for release next year with Orcas. One of the technologies however will have tool support from the start (with a VS2005 add on) and that is Windows Workflow Foundation (WF). I personally think that this will lead to WF being widely adopted earlier that the others. So if you haven't checked it out yet, now is a great time to start! Below are some online resources to help you out.

If I've missed a good WF link, drop me a line (as always from the link on the left).

1. The central official WF sites on MSDN and the NetFx3 home.

2. A bunch of articles on msdn here, here, here and here.

3. Scott has some truly great articles on his blog here, here, here and here.

4. Watch a bunch of WF webcasts. They are linked from this blog post by Paul Andrew.

5. Plenty of screencasts on channel9 and on our msdn uk nuggets page (from my colleague Mike Tauly, filter nuggets by technology "Workflow Foundation").

6. In addition to any blogs you come across from the links above, examples of good blog posts are these by: Matthew Winkler, Moustafa Ahmed, Nate Talbert and Tom Lake. Also read these on “Why WF” by: James Conard, Dave Green and Dennis Pilarinos.

7. For support, as with any other technology, head for the forums.

And remember, if you are on Windows Vista 5472, the only NetFx technology with full tool support etc is WF :-)
Check out the build matrix on Tom Archer's blog

Speaker Idol

Sun, August 13, 2006, 05:19 PM under Links
I was over at the Tech Ed Europe site to steal a logo for my blog (check it out on the left) and came accross this uber cool concept/contest: Speaker Idol.

Vista glass answers and DwmEnableBlurBehindWindow

Fri, August 11, 2006, 06:06 PM under Windows | Vista
While I have explained how to get glass on Vista with C# (twice), I did leave two open questions (hint: read the last paragraph of my last glass blog post or the stuff below won't make any sense).

Kenny Kerr steps up to the challenge and answers both questions on his article here!
For the answer to "why black" scroll down to the "Painting" section under the form with the red blob on it. For the question of why R=G=B fails, scroll slightly further down under the "Can you see me" forms.

If you don't care about the answers to the questions I posed then still go read Kenny's entry for the excellent clarification on the terminology at the beginning of his article. Even if you are not interested in the answers, terminology or even glass, then go read it for the coverage of other DWM topics. Go!

The other thing Kenny covers is a relevant glass API that I haven't talked about here before: DwmEnableBlurBehindWindow

I won't go into *any* description or give any context as I expect you'll read that on Kenny's blog. But after you've read the native approach, here is a simplified example of a managed version:

Create a new VS2005 winforms project on Vista, delete all Form1 files, add a new empty code file, and paste into it the following (then hit F5):
namespace GlassMoth
{
public class Form2 : System.Windows.Forms.Form
{
public Form2()
{
this.ClientSize = new System.Drawing.Size(200, 200);

System.IntPtr hr =
CreateEllipticRgn(30, 30, 170, 170); //or CreateRectRgn

DWM_BLURBEHIND dbb;
dbb.fEnable = true;
dbb.dwFlags = 1 2;
dbb.hRgnBlur = hr;
dbb.fTransitionOnMaximized = false;
DwmEnableBlurBehindWindow(this.Handle, ref dbb);
}

protected override void OnPaintBackground(
System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.FillRectangle(
new System.Drawing.SolidBrush(System.Drawing.Color.Black),
new System.Drawing.Rectangle(30, 30, 140, 140));
}

#region pinvokes
[System.Runtime.InteropServices.DllImport("gdi32")]
private static extern System.IntPtr CreateEllipticRgn(
int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

public struct DWM_BLURBEHIND
{
public int dwFlags;
public bool fEnable;
public System.IntPtr hRgnBlur;//HRGN
public bool fTransitionOnMaximized;
}

[System.Runtime.InteropServices.DllImport("dwmapi")]
private static extern int DwmEnableBlurBehindWindow(
System.IntPtr hWnd, ref DWM_BLURBEHIND pBlurBehind);
#endregion
}
}
Enjoy (believe it or not, I do have one final blog entry to do on glass... stay tuned)!

Vista Windows Experience Index

Thu, August 10, 2006, 01:19 PM under Windows | Vista
Remember the System Performance Rating (the one of the M3)? It is now called Windows Experience Index. Here is the one from my M5 running build 5472.


--
UPDATE: Also see WinSAT

Fun with partitions and Vista 5472

Wed, August 9, 2006, 01:48 PM under Windows | Vista
This is kind of a rant but there may be some useful hidden info for some of you

About a month ago I made the mistake of letting some supposedly experts take my main laptop for 2 hours in order to put Vista 5472 on it (it later became the July CTP). It seemed like a good deal: They would preserve my existing XP installation and create a new partition where they install Vista including all relevant applications that I would put on anyway (e.g. Office 2007 B2TR and all internal utilities for VPN connecting etc). I thought they were going to save me time but when I collected the laptop they had "shot" my XP installation (not exactly shot, but it does blue screen on startup every time rendering it useless).

The other ‘clever’ thing they did was create my Vista partition as 20GB and leave the other one to 40GB+ contrary to what I explicitly asked for.

Anyway, I am not going to tell you that I love 5472 because quite frankly it doesn't work as well as Beta 2 did for me but that is probably due to Toshiba driver issues on the M5 and, besides, that is not the point of this blog post. So today I realised that I actually *really* do need more space on my boot drive.

Luckily, with Vista we get the ability out of the box to extend and shrink partitions. Go to 'Computer' and select 'Manage' to open the 'Disc Management' page. By right clicking on partitions the desired options are there. Great! I shrunk my D partition and that gave me 10GB of unallocated space. When I tried to 'Extend' my C drive though I got the error:
“There is not enough space available on the disk(s) to complete this operation.”

I read on this page that I could try the same operation from the command line, so I did and got this message:
“There is not enough usable free space on specified disk(s) to extend the volume.”

Given that I had 1GB of space and was only trying to extend by 1MB (for test purposes), that didn't seem right. I then played with the unallocated space by creating another drive letter and shrinking/extending it at will: so the feature works, it is just my C drive that can't be extended!

Here is a screenshot of what my setup looked like at the time:


I could bore you with the wasted hours trying to figure this out but it is summarised best here and here. So as you can see in the screenshot above, my C drive is on the end of the disc so it cannot be extended :(

I didn't give up. I thought "well, I am going to have to use Partition magic after all". Tried installing it and it complains about not being administrator. "UAC at work" me thinks. I disable UAC (as previously described here), reboot and I see a black screen informing me that the boot sector is corrupt - brilliant! After moments filled with panic, I managed to hunt down a Vista DVD, booted from that, selected the repair tools and waited with sweat dripping from my forehead while trying to remember the last time I performed a backup… eventually booting from the DVD fixed the problem - phew!!

Back online, I use my favorite search engine to see if it is a known issue and discover that the advice is not to use partition magic or other XP utilities with Vista. Doh!

If anybody has any idea how I can extend my C drive above I would welcome it. What I ended up doing is uninstalling a whole bunch of apps, and reinstalling them selecting D as the install drive. This moves me forward at the moment but is not ideal (plus I haven’t tested this configuration before and no doubt there will be issues with some apps).

The moral of the story: You can bet your life that when RC1 hits us in September, *I* will be the one installing it on my laptop and *not* some other %^$&^£*# person!

This cost me a full day. In hindsight, I could have spent the time repaving... Don't you wish that before starting a task something would tell you how long it will *really* take? [Sigh]

Resources for Mobile CAB

Tue, August 8, 2006, 02:30 PM under MobileAndEmbedded
For all my mobility developer friends, just got word that there is a new resource where you can get and contribute information regarding the Mobile Client Software Factory.

I then looked at Eugenio's latest blog entry and found a sea of resources: bookmarked!

msfeeds.dll

Fri, August 4, 2006, 06:27 AM under IE7 RSS
If you followed the links from my Windows RSS Platform blog entry, you will have found the infamous example of using the RSS API to create a screensaver. In that same MSDN area from the treeview on the left you can find the RSS object model reference. The RSS API allows browsing the feed hierarchy, add/edit/delete the hierarchy, listening for events to changes in the hierarchy and controlling the process of synching/downloading.

Please see my blog post with a short example of utilising managed code for using the RSS API (skip to the code section and keep it in mind while reading the following).

What I want to do here is provide some tips for when you start using the RSS API.
1. It is a COM dll, so locate and reference msfeeds.dll (Microsoft Feeds, version 1.0) from the COM tab in the Visual Studio references dialog
2. This will bring in Microsoft.Feeds.Interop which is also the namespace you use from code
3. Everything starts with the FeedsManager and his RootFolder property (there is always a implicit root folder).
4. The object hierarchy is RootFolder->Subfolder->subfolder->feed->feeditem->feedenclosure
5. Most class/interface members return an object typed as System.Object. That means you have to do some casting in your code e.g. the Feeds and Subfolders properties in my example have to be cast to IFeedsEnum.

To help you navigate the RSS API, in addition to the links and descriptions above, check out the 4 class diagrams I laid out (collectively, the depict the entire API):
FeedManager , Folder and Feed , Item and Enclosure , Events

Now go to our nuggets page and watch one (by MikeT) on how to build an RSS viewer in C# using the API.

Deleting all RSS feeds in IE7

Wed, August 2, 2006, 02:46 PM under IE7 RSS

We already looked at how I deleted all the feeds in Outlook 2007 in one go, and not one by one.

Luckily IE7 understands folder structures from opml but somehow I managed to get them all in a flat list in IE as well (probably outlook messed that up for me or maybe a glitch with IE7 Beta 2 that I was using or something else, not important now).

So how do you delete all feeds in IE7? Out of the box you can't. Fastest end user way would be to create a folder and drag them all in it one-by-one and then delete the folder - yuck!

Another way is to be stupid and delete the contents of the Windows RSS Platform store directly (after shutting down all apps that use it, including IE7 of course). The feed store currently (Beta 3) is here:
"[drive letter]:\Documents and Settings\[user name]\Local Settings\Application Data\Microsoft\Feeds\[your feeds and folders]"

For me however, this was the opportunity I needed to test drive the RSS API. Unfortunately, it is so easy to use that I could achieve what I wanted with a dozen lines of code so here is my simple effort:

using Microsoft.Feeds.Interop;

class Program
{
static void Main(string[] args)
{
IFeedsManager fm = new FeedsManagerClass();
IFeedFolder ff = (IFeedFolder)fm.RootFolder;
System.Console.WriteLine("Starting deletion at root");
DeleteFolder(ff);

System.Console.WriteLine("Deleted all feeds!");
System.Console.ReadLine();
}
private static void DeleteFolder(IFeedFolder ff)
{
DeleteFeedsInFolder(ff);
System.Console.WriteLine();

foreach (IFeedFolder sf in (IFeedsEnum)ff.Subfolders)
{
System.Console.WriteLine("Deleting subfolder '{0}'", sf.Name);
//DeleteFolder(sf); //not needed really but it can demo recursion
sf.Delete();
}
}
private static void DeleteFeedsInFolder(IFeedFolder ff)
{
foreach (IFeed feed in (IFeedsEnum)ff.Feeds)
{
System.Console.WriteLine("Deleting feed {0}", feed.Name);
feed.Delete();
}
}
}
Also note that the code should explicitly release the COM objects. In other words, wherever you have a reference to an object, when you are done with it call:

System.Runtime.InteropServices.Marshal.ReleaseComObject(f);


Deleting all RSS feeds in Outlook 2007

Tue, August 1, 2006, 03:55 PM under IE7 RSS
By now you know that Outlook 12 can be an RSS aggregator. Outlook 2007 has its own RSS engine and does not fully use the Windows RSS Platform. It can share one element of the Windows RSS Platform and that is the Common Feed List. To enable this, go to 'Tools->Options->Other' and click on 'Advanced Options'. On the dialog that comes up, check the checkbox: 'Sync RSS Feeds to the System Feed List' (obvious, right? :-p). For more on outlook and RSS check out the RSS category on Michael Affronti's blog here (I think he owns the feature so you know where feedback on this has to go).

While evaluating whether I want to switch from my current aggregator to the outlook12+IE7 combo, I messed up and ended up with a looong flat list of feeds in Outlook (since outlook doesn't understand folder hierarchy in opml). So I wanted to delete *all* the feeds and while I can do that one by one, there was no mechanism to just get rid of all of them in one go (no folder multiselect).

In case you are wondering, even if you delete the subscriptions from outlook through the 'RSS Feeds' tab on the 'Tools->Account Settings' dialog, all the feed folders you have under the 'RSS Feeds' folder remain (kind of makes sense so you don't lose any cached content). Also note that by default the RSS subscriptions are stored on exchange (which is good because you have access to them from multiple machines through OWA, but also can be bad if your server pst size limit is small).

So anyway, this is unsupported and not recommended and definitely comes with no warranties and everything else in my disclaimer applies. With that out of the way, this is how got rid of all the feeds in one go:
1. Close Outlook 2007 Beta 2
2. Launch Outlook 2003 and connect it to the same exchange server
3. Notice how the RSS Feeds appears as a *regular* folder in Outlook 2003 (it treats it as any other user-created folder)
4. Delete the "RSS Folder" (obviously you can't do that in O12 as it is special, as the icon indicates)

The above worked for me so capturing it here in case it helps anyone but, again, do this at your own risk.