More on device development on Vista

Tue, December 26, 2006, 06:07 PM under MobileAndEmbedded
Remember the problem I got when trying to deploy to a real device from VS2005 on Vista? As that blog entry says, the solution was to run VS elevated once and that rectified the issue.

On an internal list I noticed someone else had a device issue on Vista this time with Platform Builder 6.0 and their error apparently was:
PB Debugger Warning: Debugger service map is set to none. If your image has debugging support it may not boot properly

...guess what the solution was again? Correct, run VS elevated once.

The other day at an offsite I did a very short intro to Windows Mobile development so I wanted to show first a small desktop app, then the same code in a device project connecting to a device and then connecting to an emulator. I prepared the machine before the short presentation by running VS normally for the desktop project and then running another instance elevated for the device project. I also wanted to save time by launching the emulator ready to use, so I did that from the VS menu and the first instance of VS that I came across was the desktop project. Can you spot the mistake I made?

When later in the presentation I tried to connect from the device project to the emulator I was treated to this:
---------------------------
Device Emulator
---------------------------
Error: The current VMID is in use. Wait for the other application to exit.
---------------------------
OK
---------------------------
Cryptic or what? The solution of course was to shut down the emulator and this time launch it from the elevated VS instance.

The moral of the story: You cannot have an elevated VS instance talking to a non-elevated emulator.

NETCF goodness in XNA and hopefully vice versa

Fri, December 22, 2006, 05:00 PM under MobileAndEmbedded
I hope by now everyone has heard about the XNA Framework, a set of managed code libraries for writing games on the Xbox and the PC.

Not everyone will know that the engine in XNA is based on the CLR of the .NET Compact Framework (I first heard about it here). What this could mean to device developers is that the next version of the NETCF has even more performance improvements (wouldn’t you back port any perf changes you made ;-)).

Existing NETCF application developers are prime candidates for becoming good XNA game developers (assuming you are not graphically challenged like me!). For those of you that haven’t dabbled with the NETCF before, learn how to write XNA code that performs well and read these 2 fresh posts by Chris To of the NETCF team: Part 1, Part 2.

Writing managed control panel items

Fri, December 22, 2006, 09:36 AM under Windows | Vista
In the past, if you had to develop control panel items you would start thinking about .cpl files. With Windows Vista, there seems to be a tendency to take advantage of the new ability to create them in separate executables! Those of you that know me long enough can see where I am going with this... it means that we can develop these in managed code now :-)

I will assume that you have a scenario for actually integrating with the control panel and I will just share the mechanics. Create your managed Windows Forms application and give it whatever UI you want. You actually don’t have to do anything special in the project. In fact, you could even reuse your existing main application and just use a command line option for when it gets launched from the control panel.

So once you have the exe, how do you integrate it with the control panel? The answer is by adding some registry entries.
1. Buy yourself a GUID. In all my screenshots below, replace my guid ({ABB4AAE7-3D21-45f7-AA1C-F470FAB07B89}) for the one you have.

2. Create a key with this GUID under HKLM at the path shown in the screenshot below (hint: look at the statusbar):

3. Do the same this time under HKCR at the path shown in the screenshot below:

4. Look at the values for the screenshot above. For the first 3 values you can enter anything you like. The last value points to a path and do not worry about that right now. The 4th value (System.ControlPanel.Category) tells the system under which category you want a link to your executable to appear in. I’ve chosen 7 and 9 which are the “User Accounts” and “Ease of Access” categories. The following screenshot shows the effect of the few registry entries we created. Note how values from above match the UI (inc. tooltip).

You can find your link under both aforementioned categories and it is immediately searchable as well.

5. If you click on your item, explorer.exe will show an error box “Application not found”. Close the control panel and let’s go make one more registry entry. Create 3 subkeys as shown in the following screenshot and note how the default value under Command specifies the path to the executable (you could have specified a command line argument if you wanted):

Launch the control panel again, and this time when clicking on your link, your application will open.

Also, remember the string we entered for the System.ApplicationName registry value? If you entered the same as me, you can now launch your application from the command line
control /name Daniel.MothPanelApplet

6. An optional additional step is to specify task links under your item. This is where the path to the file we mentioned above comes in. At the moment your System.Software.TasksFileUrl value points to an invalid path. Make it point to this file after you copy it to your machine. Close Control Panel and after reopening it, under “User Accounts”, you find a something like the following:

If you navigate to the “Ease of Access” category, you’ll find a slight variation as shown in the screenshot behind this link.

More Info
There is a lot more to check out including how to change the icon that appears in the control panel, what the numbers for the other categories are, how to launch other items from the command line, design guidelines, explanations on the XML file for tasks, creating cpl items, what else is new in Vista and a lot more. The following msdn links should cover that material for you:

Tour of UI

Quick intro similar to mine

UX guidelines for control panels

Comprehensive control panel overview

TVS_EX_AUTOHSCROLL

Tue, December 19, 2006, 10:39 AM under Windows | Vista
Open your windows explorer on Vista and click around the “Folders” section in the left (below your “Favorite Links”). Do you observe two things that were not there pre-Vista? That is right, the treeview has no horizontal scrollbar at the bottom and scrolling happens for you automatically as you select nodes that are not fully visible and as you mouse over around. Resize that area to be smaller if you are not observing this effect. Now do you notice the effect? Cool :)

It turns out that you can make any TreeView behave like that, if you want to. The clue for me was accidentally coming across the TVS_EX_AUTOHSCROLL constant.

<this took me longer than what it should>
I must admit that it took me a while to get this working. First when my simple mind encountered extended style it thought: “I know those and I know how to change them for managed controls”. So I overrode CreateParams and changed the ExStyle property but that had no effect. I then assumed that the reason it wasn’t working was because I had to send it the TVM_SETAUTOSCROLLINFO message so I played with that, messing with various values since the documentation gives no clue to sensible starters and then gave up when I was still not observing the results. BTW, spy++ wasn’t helping much since prolongued use caused the machine to freeze and rebooting added to my overall frustration. Eventually a virtual slap made me realise that I need to send a custom message for the extended treeview style (not window style). Digging around I found the TVM_SETEXTENDEDSTYLE message and tried sending that. Another round of trials and errors with no luck; only after opening commctrl.h I could work out what params to send and in what order. I knew the messages were reaching the TreeView as I started using my own TreeView and overriding DefWndProc with debug statements to make sure that the message wasn't been swallowed by the managed implementation. A complete red herring came out of nowhere questioning whether I was using v6 of comctl32.dll (of course I was, my commandlinkbutton etc worked fine, but to be positive, I manifested the assembly to make sure that was indeed the case). At this point, you can imagine that I was hacking at this API for quite a while, editing code and then running the project. At some point I got lazy and my test of whether it worked or not was: Does an hscrollbar appear in the treeview. Well it turns out that, at least for the System.Windows.Forms.TreeView, the documentation is wrong: the hscrollbar does not go away with this style!! Doh! God knows how many times I had this working and thought I hadn’t because of the visual false positive :-(
</this should it what than longer me took>

Anyway, once I started testing properly again, not only it worked but I also realised that you don’t really need to send auto scroll info since it has some sensible defaults. So the bare minimum to get the TreeView to automatically scroll horizontally based on node selected and mouse position, is the following:
NativeMethods.SendMessage(treeView1.Handle, NativeMethods.TVM_SETEXTENDEDSTYLE, 0, NativeMethods.TVS_EX_AUTOHSCROLL);

If you actually want to change the speed of auto scrolling combined with a scroll timeout, then you must do this:
NativeMethods.SendMessage(treeView1.Handle, NativeMethods.TVM_SETAUTOSCROLLINFO, 30, 10); 

And if you want to get rid of the hscrollbar to make it look like the windows explorer folder view, then you must do this:
int num2 = (int)NativeMethods.GetWindowLong(treeView1.Handle, NativeMethods.GWL_STYLE);
num2 = NativeMethods.TVS_NOHSCROLL;
NativeMethods.SetWindowLong(treeView1.Handle, NativeMethods.GWL_STYLE, num2);

The pinvoke declarations for this exercise are in this NativeMethods file here.

For those of you that don’t want to repeat the above hacks for every single treeview in every single project, I’ve put all of the above in a TreeViewVista control. Just find a project that uses a TreeView already and change the ctor line to use TreeViewVista instead :-)

VS2005 SP1 RTM + SP1 Update Beta

Fri, December 15, 2006, 01:23 PM under Links
After installing the RTM version of Service Pack 1 for Visual Studio 2005, this is what will greet you the first time you run VS on Windows Vista:



It references the “SP1 Update” for VS2005 to make it run best on Vista. Note that even with that, the advice is still to run with administrative permissions. I have said before that you can get away with many things by not running VS elevated, but to play it on the safe side do follow the explicit advice given.

You can get a Beta of the SP1 Update for Vista here soon.

BTW, we are all familiar with the term “RTM” and we are all used to “SP”, but this “SP1 Update for Vista” is a new one. It made me smile but, if you think about it, what else could they have called it?

Launch elevated and modal too

Fri, December 15, 2006, 01:22 AM under Windows | Vista | UAC
Those of you that have attended my talks on UAC will have seen the demo where we extract a process and run it elevated (i.e. an elevation prompt requires the consent of the user). Here I want to add some extra juice to that one.

For the rest of you, basically, if you have some admin task in your application that you cannot redesign (i.e. get rid of), you still should not mandate that your whole application runs elevated (i.e. requires admin privileges). Instead, you should refactor that functionality in a separate process. When you require the use of that admin functionality from your main application, launch the other process elevated to do the work for you. There are a few ways you can launch the application elevated but the best one in this case is to manifest the application. An example of a manifest is here; change the level from asInvoker to requireAdministrator. Embed it in your project by pasting the following line in the “Post-build event command line” textbox of the project properties:
"$(DevEnvDir)..\..\Common7\Tools\Bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest" –outputresource:"$(TargetDir)$(TargetFileName)";#1

So what is the extra juice I want to add in this post? Well there are two things that were nagging me with the way I showed how to launch the process.

One was that the UAC consent dialog that comes up was not modal to the main application (since it was being launched for another application). By default you do not observe this but since in my setup I have disabled the policy “Switch to the secure desktop when prompting for elevation”, it affects me [NOTE: I do not recommend you disable that policy, it just happens that I have it like that for historical irrelevant reasons]. I was tipped-off that to make the UAC dialog modal, you must pass to the ShellExecute call the handle of the main app.

The other thing I didn’t like was that if the process we launch elevated has its own UI, then that is also not modal to the application.

So here is the code that addresses both of the issues above:
private void LaunchElevatedProcess()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true; // default, but be explicit
startInfo.WorkingDirectory = Environment.CurrentDirectory; //or other if you prefer
startInfo.FileName = @"some_path_to.exe";

//// if the other process did not have a manifest
//// then force it to run elevated
//startInfo.Verb = "runas";

// Two lines below make the UAC dialog modal to this app
startInfo.ErrorDialog = true;
startInfo.ErrorDialogParentHandle = this.Handle;


try
{
Process p = Process.Start(startInfo);

// block this UI until the launched process exits
// I.e. make it modal
p.WaitForExit();

}
catch(Exception ex)
{
// user cancelled
MessageBox.Show(ex.Message, "caught it!"); //for demo purposes
return;
}
}

Enjoy :)

Managed Preview Handlers for Vista and Office

Wed, December 13, 2006, 02:25 PM under Windows | Vista
Truly fantastic article on MSDN magazine January 2007 issue: Managed Preview Handler Framework.

If you don't know what preview handlers are, on your Vista box open explorer, click on "Organise", "Layout" and then "Preview Pane". Now select a file and watch the preview pane. The file must be an office file or video or image and some others. For each file type/extension a preview handler exists that renders it in the preview pane (this also works for Outlook 2007 preview pane for attachments).

So how do you write a preview handler? Until now the answer was COM. Now with this article, Stephen Toub shares a framework that allows us to build them with managed code! Visit the article to download the framework which includes all the source code too.

Not only that, the download also includes preview handlers for files with extensions: bin;dat;csd;xps;xml;psq;isf;msi;pdf;resx;snk;zip and xaml. So even if you are not a developer caring about the framework, go get the download for the handlers themselves, to enrich your own Vista experience.

So, in a nutshell the framework has a simple inheritance hierarchy that encapsulates the COM ugliness and offers extensibility points for hooking in your own managed preview handler. When reading the article, if you are interested in the framework’s internals, keep this class diagram in mind. Another class diagram shown below should make clear how ridiculously easy it is to create these things now:

So to write a simple Hello World preview handler:
1. Create a new Class library, and reference the MsdnMagPreviewHandlers.dll from the article download.
2. Add a new code file and add to it these few lines of code.
3. Build the dll, gac it and regasm it (see the article if you have trouble with that, both tools are in your C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin folder)
4. Create a new file somewhere, test.moth and watch the preview:

Now do you see how extremely cool the Managed Preview Handler Framework is? Use it for your own file formats! At a future entry I'll show you a more meaningful preview handler.

BTW, if you have no interest in preview handlers, the code is still a great example of how to wrap COM APIs so read the article for the in-depth explanation of this diagram.

The day the world broke...

Wed, December 13, 2006, 03:16 AM under Random
OT post, no technical content on this one...

[sigh] I woke up this morning to the sound of my phone’s alarm. Unlike other times though, there is no notification. Without a notification, I cannot dismiss the alarm! None of the hardware buttons has any effect. I ended up muting the volume. Soft resets, playing with settings etc but still no joy. I am supposed to know this stuff and I can’t get this annoying alarm to stop sounding... Given that I had a conference meeting in 5’ I just left it muted and turned my attention to dialling the conference centre number. However, the person in charge of the call hadn’t activated it. So while waiting I thought I’d boot the laptop up and check email. Can’t connect to server; it could however download the 3 security updates fine and browse other internet sites. Checked another separate web email service and it was down as well! While trying VPNing in and finding that it is a no starter too, there is a loud bang on the door. I opened the door to find the postman informing me that the door bell seems to have broken. He handed me a letter I had to sign for.

As I was opening the letter (still waiting on the phone for the conf-call to be activated while observing that I still can’t connect to any email account and dreading to put the volume up on my phone in case the alarm started sounding again), I couldn’t help but think: “Will there be a message in the letter informing me that the ‘the world is broken today’...”. I was getting scared, in fact, I checked out of the window to see if there was anything unusual!

For the record: I eventually got into email via Redmond (rather than Reading), found a cancellation for the conf call, the other web email sprung to life, the letter wasn’t pleasant but not the end of the world. Door bell still broken, phone still on mute :-/

PDC 2007 in Los Angeles on October 2-5

Tue, December 12, 2006, 12:30 PM under Links
Save the dates. Hot off the press.

WinSAT

Tue, December 12, 2006, 07:47 AM under Windows | Vista
Do you remember the Windows Experience Index (earlier known as System Performance Rating)?

Well, it is available programmatically via the Windows System Assessment Tool (i.e. the WinSAT API). This is a COM API that, at a high level, gives you back the two things: the information and a bitmap.

Here is a screenshot of the output if I query the SAT on my laptop from C# console app. Console shows the details and the pop up windows form shows the bitmap


To read the full story, download the code to run on your machine and much more detail, please visit Bart’s blog entry now.