I’ve been busy creating a web service or two for MahTweets 3. The biggest problem I have with creating web services is I generally hate storing user credentials/data. Using a delegated identity system like OpenID makes me feel better about it. It also means users of the service don’t have to sign up for yet another service, and can safely use their existing accounts from one of the thousands of OpenID service providers.
However, I wanted to use the service in a desktop client and OpenID is only a browser tech. That’s where OAuth enters the story. OAuth is getting more an more popular for authentication of web services so that users never have to enter in the username/password on unknown websites or desktop clients. Vimeo, Twitter, Yammer, LinkedIn and many more are already using OAuth today.
As for the service itself, of late I’ve been seeing a bit about Astoria/RIA Data Services/WCF Data Services. It’s had a few names in its time. WCF Data Services pushes out OpenData (aka oData), and lets you use LINQ in your client to query the web service. As always, Scott Hanselman has a great post on the basics of OData.
OAuth securing an oData service using OpenID for identity – OoO!
The flow from the client side is request access via OAuth, open browser and login with OpenID, "allow" client via OAuth, copy generated PIN verifier into the client, then have full access to web service. The OpenID portion of it could easily be replaced with username/password, FacebookConnect, or even another OAuth service that can be used for identity like Twitter.
Server Side
The server side stuff is mostly the same as what is found in the DotNetOpenAuth samples. I had problems getting it to work in an MVC Application, but that was solved by just adding SubmitChanges() at the end of ExpireRequestTokenAndStoreNewAccessToken and AuthorizeRequestToken within DatabaseTokenManager.
I’m not going to cover the DotNetOpenAuth setup, its long winded and mostly copy & pasting code.
Create a new WCF Data Service, open up the svc markup (ie, api.svc, not api.svc.cs) and modify the Factory to something like:
<%@ ServiceHost Language="C#" Factory="MahTweetsWebsite.Application.WCFRestOAuthFactory" Service="MahTweetsWebsite.api" %>
Then create WCFRestOAuthFactory.cs
public class WCFRestOAuthFactory : DataServiceHostFactory
{
protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new WCFRestOAuth(serviceType, baseAddresses);
}
}
public class WCFRestOAuth : DataServiceHost
{
public WCFRestOAuth(Type serviceType, Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
this.Authorization.ServiceAuthorizationManager = new OAuthAuthorizationManager();
}
}
All WCFRestOAuthFactory does is create a new WCF service of the Service specified and assigns the ServiceAuthorizationManager, which in this case is OAuthAuthorizationManager (copied from DNOA). There are other ways you can intercept calls in WCF Data Services to attach security – notably overriding OnStartProcessingRequest(ProcessingRequestArgs args) in the service class itself.
The next dilemma is what if you want one service to provide certain data without authentication? In the MahTweets webservice, things like a list of available Plugins to download doesn’t really need to be authenticated. I’ll admit that I’ve not really sorted this out, but as a basic guess, inspecting the RequestUri inside of OAuthAuthorizationManager is one possibility.
protected override bool CheckAccessCore(OperationContext operationContext)
{
if (!base.CheckAccessCore(operationContext))
{
return false;
}
HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
Uri requestUri = operationContext.RequestContext.RequestMessage.Properties["OriginalHttpRequestUri"] as Uri;
ServiceProvider sp = Constants.CreateServiceProvider();
if (requestUri.AbsolutePath == "/Api.svc/$metadata")
return true;
if (requestUri.AbsolutePath.StartsWith("/Api.svc/Plugins"))
return true;
// other auth bits
}
I’m not saying this is a great way to do it, but the best I’ve come up with so far.
Client Side
The client side consists of two parts – the OAuth "dance" to get the tokens, much like any OAuth accessing service. Again, I’ll use DotNetOpenAuth for this. This is my console application.
public static class MahTweetsOAuthService
{
public static readonly ServiceProviderDescription Description = new ServiceProviderDescription
{
RequestTokenEndpoint = new MessageReceivingEndpoint("http://localhost:57500/OAuth.ashx", HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
UserAuthorizationEndpoint = new MessageReceivingEndpoint("http://localhost:57500/OAuth.ashx", HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
AccessTokenEndpoint = new MessageReceivingEndpoint("http://localhost:57500/OAuth.ashx", HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
ProtocolVersion = ProtocolVersion.V10a,
};
}
public class OAuthWrapper
{
public DotNetOpenAuth.OAuth.DesktopConsumer consumer { get; set; }
private String RequestToken = "";
public String ConsumerKey { get; set; }
public String ConsumerSecret { get; set; }
public OAuthWrapper(String ConsumerKey, String ConsumerSecret)
{
this.ConsumerKey = ConsumerKey;
this.ConsumerSecret = ConsumerSecret;
consumer = new DotNetOpenAuth.OAuth.DesktopConsumer(MahTweetsOAuthService.Description,
new OAuthTokenManager()
{
ConsumerKey = this.ConsumerKey,
ConsumerSecret = this.ConsumerSecret
});
}
public String BeginAuth()
{
var requestArgs = new Dictionary<string, string>();
requestArgs["scope"] = "http://tempuri.org/IDataApi/GetName|http://tempuri.org/IDataApi/GetAge|http://tempuri.org/IDataApi/GetFavoriteSites";
return this.consumer.RequestUserAuthorization(requestArgs, null, out this.RequestToken).AbsoluteUri;
}
public String CompleteAuth(String Verifier)
{
var response = this.consumer.ProcessUserAuthorization(this.RequestToken, Verifier);
return response.AccessToken;
}
public IConsumerTokenManager TokenManager
{
get { return (IConsumerTokenManager)consumer.TokenManager; }
}
}
class Program
{
static void Main(string[] args)
{
//Oauth Authentication
OAuthWrapper t = new OAuthWrapper("123", "123");
System.Diagnostics.Process.Start(t.BeginAuth());
Console.WriteLine("Please enter the PIN");
t.CompleteAuth(Console.ReadLine());
Console.WriteLine("Press anykey to continue");
}
}
The very basic wrapper is designed to make the initial OAuth dance as easy and reusable as possible.
The next part is the WCF Data Services/OData specific bits. OData itself doesn’t specify any standards for authentication, which is a little confusing at first. OAuth requires several headers, one part of that is the OAuth signature which requires the address of the resource you’re requesting to generate.
From what I can see (and I very well may be wrong), there isn’t a really awesome way to do this with WCF Data Services on the client side – if you create an extension on the service (DataServiceContext), it doesn’t yet know the full address (it only has the base address), and if you create an extension for DataServiceQuery<T>, it doesn’t know about the Context so you can’t hijack the SendingRequest event to insert the OAuth header. The best solution I could come up with was creating the extension for DataServiceQuery<T> and passing in the service.
public static class ODataExtensions
{
public static DataServiceQuery<T> AsOAuth<T>(this DataServiceQuery<T> Query, DataServiceContext context, IConsumerTokenManager t)
{
context.SendingRequest += (s, e) =>
{
var serviceEndpoint = new MessageReceivingEndpoint(Query.RequestUri.ToString(), HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest);
var wcf = new DesktopConsumer(MahTweetsOAuthService.Description, t);
WebRequest httpRequest = wcf.PrepareAuthorizedRequest(serviceEndpoint, ((OAuthTokenManager)t).AccessToken);
HttpRequestMessageProperty httpDetails = new HttpRequestMessageProperty();
httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
e.Request.Headers = httpDetails.Headers;
};
return Query;
}
}
Usage:
mahtweetsdbEntities api = new ServiceReference2.mahtweetsdbEntities(new Uri("http://localhost:57500/Api.svc/"));
var y = api.Screencasts.AsOAuth(api, t.TokenManager).Execute();
Immediately you’ll see some less than ideal code in there. The default IConsumerTokenManager doesn’t expose the AccessToken, but my OAuthTokenManager does. You could modify the extension to include a string token parameter, or just modify token manager to expose it. The next less-than-generic snippet is the ServiceProviderDescription, which is using the service description from a static class. Again, you could pass in another parameter containing the service description. The last issue is the request method in the service endpoint – this obviously won’t work for other HttpVerbs, so it might be worth passing in that parameter.
It’ll take me a day or three, but I’ll get a sample project together for OoO.
While delving further into Android, I’ve been creating a “hello world” type of app – its not as complex as what MahTweetsMobile will be, but it is encompassing a lot of different elements (custom ListAdapter, SQLite for persistent storage, different types of menus, loading external intents, etc).
One “difficult” element has been events. I say “difficult” because by design, its freaking nuts.
Scenario
I’ve got a custom ListViewAdapter, for my custom list elements, where the ListView items include a checkbox. This checkbox is to indicate the status of the items (for reference, its a shopping list app, you tick the checkboxes to show which items you’ve bought while shopping, the items then go grey in colour).

I wanted to add a “long press” context menu so that you could easily bring up a menu (with options such as Edit Item or Delete Item)
The Problem
Normally when “attaching” event listeners with ListViews, you use setOnCreateContextMenuListener on the ListView itself. You then override your Activity’s onContextItemSelected, figure out what menu button was pressed as well as what item it was pressed on.
ListView x = (ListView)findViewById(R.id.ListView01);
x.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
public void onCreateContextMenu(ContextMenu contextMenu, View view,
ContextMenuInfo arg2)
{
contextMenu.add(0,CMENU_DELETE, 0, "Delete Item");
}
});
public boolean onContextItemSelected(MenuItem item)
{
AdapterContextMenuInfo menuInfo =
(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
switch (item.getItemId())
{
case CMENU_DELETE:
//Use menuInfo.position along with the adapter.getItem
//ie Product p = (Product)adapter.getItem(menuInfo.position);
return true;
}
return true;
}
As you can see, its ugly code, but it works. Sort of. The problem was the checkboxes.
As soon as you add checkboxes to the individual items view, any listener created on the ListView never fires – the CheckBox swallows the event!
The Apparent Solution
Apparently this is a known bug (or more accurately, this is by design!). The solution is to set the event handlers on the rows themselves; inside the custom ListAdapter, when you’re inflating the various UI elements – look at my previous post on Custom ListAdapter, it’s under the getView method – on that “rowLayout” use the same setOnCreateContextMenuListener as the code used on ListView above, except only apply it to the individual row’s.
That would be fine if you didn’t care which item was pressed. That’s right, the cast to AdapterContextMenuInfo of item.getMenuInfo() in your Activity’s (yes, your activity has to override this, nowhere else works. argh!) onContextItemSelected always returns null because item.getMenuInfo() is always null.
The Actual Solution
I have no idea how I stumbled across this solution – I think I was in the process of undo-ing lines of code to try and figure out “where I’d gone wrong”.
Fact: To get the event to fire with checkboxes you need it to be set on the rowLayout.
Fact: To get menuInfo to be anything other than null (ie, tell you where it came from), you need it set on the ListView
Solution? Combine them. Wait, what? Two event listeners to get them to work? Yup.
On the rowLayout, set the listener:
rowLayout.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
public void onCreateContextMenu(ContextMenu contextMenu, View view,
ContextMenuInfo arg2)
{
}
});
Notice the lack of code inside the onCreateContextMenu? Well, any ContextMenu items added inside this method won’t have AdapterContextMenuInfo – so don’t set anything, no menus will appear.
Now also set the adapter on the ListView using the code above.
Now it all works. WTF doesn’t begin to describe this.
Disclaimer: This post presumes you’ve setup the Android SDK and Eclipse. If not, check out the Android Developer Guide
Some of the Android developer documents seem great, but in general there seems to be a lacking of documentation/examples – while the Java language is giving me no problems, how to do things with the Android API can be a bit of a nightmare to figure out.
It is possibly because Android is relatively new or because I’m used to MSDN which is a fantastic resource. Regardless, I started to want to develop MahTweetsMobile for Android and was having difficulty in ‘binding’ a ‘view’ to a list of elements, ala WPF/XAML’s DataTemplates.
It turns out its not as magical as what WPF is and requires manual binding, but its not impossible.
The View
To get a list to display anything other than just a string, you need to define your own view in either XML or code-behind. I find XML to be a little nicer, and its easier to update.
In Eclipse (I’m sure it’ll work in other IDE’s too, but this is what I’m using), you can create a new view by navigating to res –> layout, right clicking on the folder and selecting New –> Other, then from the popup select Android –> Android XML File
Make sure in the next dialog you select the Layout resource type, and give the file a name like "tweetview.xml" (all in lower case, as java/ADK will complain otherwise).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget32"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TableLayout
android:id="@+id/widget33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TableRow
android:id="@+id/widget35"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageButton
android:id="@+id/imgbtnAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</ImageButton>
<LinearLayout
android:id="@+id/widget39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
>
</TextView>
<TextView
android:id="@+id/txtTweet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
>
</TextView>
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>
The Model
Just a simple class to hold our data,
package mahapps.MahTweets;
import java.util.Date;
public class Tweet {
public int ID;
public String Name;
public String Text;
public Date Timestamp;
public int getID()
{
return this.ID;
}
public String getName()
{
return this.Name;
}
public String getText()
{
return this.Text;
}
public Tweet()
{
}
}
The Custom ListAdapter
This is the "heavy lifting" code – this is what "binds" a Tweet object to the TweetView.
package mahapps.MahTweets;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.*;
public class TweetAdapter extends BaseAdapter
{
private List<Tweet> elements;
private Context c;
public TweetAdapter(Context c, List<Tweet> Tweets)
{
this.elements = Tweets;
this.c = c;
}
public int getCount() {
return elements.size();
}
public Object getItem(int position) {
return elements.get(position);
}
public long getItemId(int id) {
return id;
}
public void Remove(int id)
{
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout rowLayout;
Tweet t = elements.get(position);
if (convertView == null)
{
rowLayout = (LinearLayout)LayoutInflater.from(c).inflate
(R.layout.TweetListView, parent, false);
TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
tv.setText(t.getText());
//...
//and so on for all the properties/UI elements
//...
} else {
rowLayout = (RelativeLayout)convertView;
}
return rowLayout;
}
}
You can then use this in your main Activity:
ListView x = (ListView)findViewById(R.id.ListView01);
x.setAdapter(new TweetAdapter(this, MyListOfTweets));
If you’re using a ListActivity, you’d just set that Activity’s adapter.
Your ListView items should then appear in more detail!

Now that Rafael Rivera and Long Zheng have launched Geosense For Windows (or you can see Long’s post on it), I can happily brag how MahTweets has supported this since before they started working on it.
Geosense and MahTweets both use the Windows 7 Location and Sensor Platform – Geosense being the provider, MahTweet being the consumer. We supported it in MahTweets to geotag tweets and Flickr photos, in the hope that one day Microsoft or the hardware partners would be kind enough to consider Australia a real country and finally release some relevant hardware to the platform here. So far that hasn’t happened, which is where Geosense steps in.
Geosense with .NET
Geosense by itself doesn’t really do anything terribly exciting to the end user – it’s what Geosense enables for developers that is awesome. Location based services and games are primarily on phones only as it can be a hassle for the user to manually enter their location all the time – now it’s dead easy to bring those services and games to the desktop through rich clients.
To start with, grab the Sensor and Location .NET Interop Sample Library.
Below is an abridged version of the MahTweets GlobalPosition class file (it does some other stuff for other platforms that don’t have the sensor API’s, but that’s just a matter of people manually setting their location).
using Windows7.Location;
public class Location
{
public String City { get; set; }
public String Country { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public static class GlobalPosition
{
private static LatLongLocationProvider _provider;
private static CivicAddressLocationProvider _civicprovider;
private static bool _loadproviderthrowsexception = false;
private const uint DEFAULT_REPORT_INTERVAL = 0;
public static Location GetLocation()
{
Location l = new Location();
try
{
if (_loadproviderthrowsexception)
{
return null;
}
if (_provider == null)
{
_provider = new LatLongLocationProvider(DEFAULT_REPORT_INTERVAL);
_civicprovider = new CivicAddressLocationProvider(DEFAULT_REPORT_INTERVAL);
}
var y = _civicprovider.GetReport() as CivicAddressLocationReport;
l.City = y.City;
l.Country = y.CountryOrRegion;
var x = _provider.GetReport() as LatLongLocationReport;
l.Latitude = x.Latitude;
l.Longitude = x.Longitude;
return l;
}
catch (Exception ex)
{
return null;
}
}
}
Easy. The code speaks for itself – create a LocationProvider, query it to get the Latitude/Longitude. The rest is up to you.
Bonus Points
And if you’re a Powershell junkie, the following works too
[Reflection.Assembly]::LoadFile("<absolute location to dll>\Windows7.SensorAndLocation.dll")
$provider = new-object Windows7.Location.LatLongLocationProvider(0)
$position = $provider.GetReport()
$position.Latitude
$position.Longitude
Disclaimer: I’m new to Android, I could be doing this all wrong. If I am, please comment and correct me.
Programming for Android is an interesting experience, coming from a .NET/C# background. I’ve done plenty of Java before in Uni and disliked it, but that was before I started playing with WPF.
Like WPF, Android’s UI is created using XML based documents, but unlike WPF, there aren’t any nice WYSIWYG builders. And most of the time it seems you need a combination of code behind and XML to get what you want for the UI, which can get a bit frustrating.
The divider between the items in this particular app is more annoying than it is useful, so I wanted to get rid of it. I was initially looking for separator or border, but the name is divider, and it has two properties.To set the divider between the ListItems to "nothing", you have two options. The first is in Java,
ListView x = (ListView)findViewById(R.id.ListView01);
x.setDivider(null);
x.setDividerHeight(0);
The alternative is to set it in XML, but in this case its more of a hack than the above of turning it ‘off’.
<ListView
android:id="@+id/ListView01"
android:background="#ffffff"
android:dividerHeight="0px"
android:divider="#ffffff" />
Even though the dividerHeight is set to 0 (0px, 0dp, whatever, the results were the same), a black line was still visible. The best solution is to set the colour (the divider value) to the same as your background. Using a gradient or image as the background? Set it in the code behind.

Awhile ago I heard the saying “Microsoft is a platform company” (rather than lots and lots of products), one great example of that is Windows Home Server. WHS’s is built upon Windows Server 2003, so you can create apps and extend it much like any other Windows OS, but you can also extend the “Home Server Console” very easily using Visual Studio/.NET.
Requirements
Setting up your WHS Add-in
Create a .NET 2.0 Library Project (WHS does not ship with .NET 3.0/3.5, although they will work if installed), then you need to reference two libraries to build WHS add-ins which can be found on your WHS box. That’s right, there is no SDK download, the required libraries are found on your server.
From “C:\Program Files\Windows Home Server” copy HomeServerExt.dll and Microsoft.HomeServer.SDK.Interop.v1.dll from your server to your development machine, then reference both of them in your solution. This will give you the namespace Microsoft.HomeServer.SDK.Interop.v1. Alongside those, for the UI you’ll need to add references to System.Forms and System.Drawing.
WHS requires a particular assembly name structure, so right click on your project, change the Assembly name to “HomeServerConsoleTab.<yourprojectname>”, ie “HomeServerConsoleTab.WHSStats”
WHS Stats

WHS Stats uses Windows Management Interface (WMI) to return the names of several pieces of hardware on the server. This could be turned into a fully fledged hardware monitor, but I’m trying to keep it a very simply example that has more real world value than the veteran Hello World.
WHS Tab Add-ins (which appear in the main WHS Console screen versus Settings Add-in’s which appear after you click Settings from the Console) require two classes. In this case it’s WHSStats(.cs) which implements Microsoft.HomeServer.Extensibility.IConsoleTab and WHSStatsPanel(.cs), a UserControl, which contains the UI.
WHSStats.cs
using System;
using System.Text;
using Microsoft.HomeServer.Extensibility;
using Microsoft.HomeServer.SDK.Interop.v1;
using System.Drawing;
using System.Collections.Generic;
using System.Management;
namespace WHSTempAddin
{
public class WHSTempAddin : Microsoft.HomeServer.Extensibility.IConsoleTab
{
private IConsoleServices services;
private WHSTempAddinUI nPanel;
private WHSInfoClass whsInfo;
public WHSTempAddin(int width, int height, IConsoleServices consoleServices)
{
nPanel = new WHSTempAddinUI();
whsInfo = new WHSInfoClass();
this.services = consoleServices;
nPanel.Load += new EventHandler(nPanel_Load);
}
public Bitmap TabImage
{
get { return Properties.Resources.WHSTempAddinImg; }
}
public bool GetHelp()
{
throw new NotImplementedException();
}
public Guid SettingsGuid
{
get { return Guid.Empty; }
}
public System.Windows.Forms.Control TabControl
{
get { return nPanel; }
}
public string TabText
{
get { return "WHS Stats"; }
}
void nPanel_Load(object sender, EventArgs e)
{
nPanel.lstCPUDetails.DataSource = getCPUDetails();
nPanel.lstGPUDetails.DataSource = getGPUDetails();
nPanel.lstNetworkDetails.DataSource = getNetworkInterfaceDetails();
}
private List<String> getCPUDetails()
{
List<String> data = new List<string>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT *
from Win32_Processor");
foreach (ManagementObject adapterObject in searcher.Get())
{
data.Add(adapterObject["Name"].ToString());
data.Add("CPU Load: " + adapterObject["LoadPercentage"] + "%");
}
return data;
}
private List<String> getNetworkInterfaceDetails()
{
List<String> data = new List<string>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select *
from Win32_PerfRawData_Tcpip_NetworkInterface");
foreach (ManagementObject adapterObject in searcher.Get())
{
UInt64 i = (UInt64)adapterObject["CurrentBandwidth"];
data.Add("Adapter name: " + adapterObject["Name"]);
data.Add("Current bandwidth: " + (i / 1000000) + "MB/s");
data.Add("KBytes In/sec: " +
((UInt64)adapterObject["BytesReceivedPersec"] / 100000) + "KB/s");
data.Add("KBytes Out/sec: " +
((UInt64)adapterObject["BytesSentPersec"] / 1000000) + "KB/s");
}
return data;
}
private List<String> getGPUDetails()
{
List<String> data = new List<string>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT *
from Win32_VideoController");
foreach (ManagementObject adapterObject in searcher.Get())
data.Add(adapterObject["Name"].ToString());
return data;
}
}
}
The constructor, TabText, SettingsGuid, TabImage and GetHelp the minimum methods to implement for a WHS Add-in. Key things to note, TabImage is a Resource added to the project, its recommended to be a 32×32 image (I used one slightly larger, that could explain why it is skewed off to one side); TabText is what appears on the Tab to select your add-in so don’t make it too long!
The rest of the code is hooking up the listboxes (below) to WMI queries about the hardware.
WHSStatsPanel.cs

Building and deploying the project
These particular instructions are mostly copied from MSDN
- Add New Project, select Setup and Deployment Projects, and then select Setup Project.
- In the File System editor (of the Setup Project), select the Application Folder node. Right-click the Application Folder, point to Add, then select Project Output.In the Add Project Output Group dialog, verify that Primary Output is highlighted. Click OK to add the project output and close the dialog box.
- In the File System editor, right-click Application Folder and then click Properties Window. In the properties window, in DefaultLocation, type [ProgramFilesFolder]\Windows Home Server.
- In the Solution Explorer, expand the Detected Dependencies. Right-click HomeServerExt.dll and Microsoft.HomeServer.SDK.Interop.v1.dll, then click Exclude.
- Now in Visual Studio 2008, you’ll need to set the .NET Framework under Launch Conditions to .NET 2.0.That is View –> Editor –> Launch Conditions. Regardless of whether you’ve selected .NET 2.0, 3.0, 3.5 or 3.5 SP1, this needs to be set. VS2008 defaults to .NET 3.5 in the launch conditions, which stops the installer from even running!
- This step is “sort of” optional. If you plan to Remote Desktop into your server and run the installer that way, you don’t need to do this…but if you plan to run the installer through the Windows Home Server console, you need to place the installer in \\Server\Software\Add-Ins. Even then, you need to insert the “WHSLogo” property (and set it to 1) in the MSI before WHS will pick it up.
To do this, you’ll need ORCA (it’s in the Windows SDK, see above for the links to that; Once you install the SDK, you’ll find the ORCA installer in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\Orca.MSI). 
- With ORCA open, click File, click Open, browse to the location of the MSI file that contains your Add-in, and then click Open.
- In the Tables column, click Property.
- Right-click anywhere in the column area where the Property and Value columns are listed, and then click Add Row.
- In the Add Row dialog, type WHSLogo for the Property, click Value, and then type 1. Click OK to enter the property and to close the dialog.
- Click File, click Save, and then click Exit to close ORCA.

Scanners are perhaps becoming less and less used as we all move towards a paperless environment with digitals bills and digital photos, but a lot of "official" documentation must always be presented with the original physical copy. The wife and I have a huge collection of such documents which have been horribly archived in several filing cabinets – finding the right document is often a nightmare, let alone using any of the information in them. To combat this, I’ve started on a document manager which (aims to) make it a smooth process from scanning, archiving, searching, tagging, etc all in one.
I thought I’d share the scanning code section, because while scanning wasn’t the easiest thing to dig up, it still wasn’t half as daunting as I thought it would be. Further down you’ll also see code to do optical character recognition (OCR) – that is converting a scanned text document into usable text.
TWAIN or WIA?
In years past, TWAIN (commonly known as Technology Without An Interesting Name) was the way to perform scanning, so that was my starting point on my dig for scanning code. However, I came across a mention of Windows Image Acquisition in my scanners drivers.
"In comparison to TWAIN, WIA is said to be more flexible, because it is a standardized interface that doesn’t require a tight bundling of scanner software and driver (TWAIN-only scanners are often limited to functions that are enabled in its driver-software-bundle). Most recent scanners support WIA."
(source: Wikipedia)
Lift the image from a physical file into memory
To access WIA in .NET, you’ll need to add a reference to the COM library, "Microsoft Windows Image Acquisition Library v2.0" (wiaaut.dll).
using WIA;
….
const string wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}";
CommonDialogClass wiaDiag = new CommonDialogClass();
WIA.ImageFile wiaImage = null;
wiaImage = wiaDiag.ShowAcquireImage(
WiaDeviceType.UnspecifiedDeviceType,
WiaImageIntent.GrayscaleIntent,
WiaImageBias.MaximizeQuality,
wiaFormatJPEG, true, true, false);
This isn’t the only way to perform a WIA scan, but it is a very quick and easy way to do it. A standard dialog will appear asking you to select the scanner, and then another dialog will give you a few options (such a previewing, image quality, image mode, which source – by that I mean a document feeder or flatbed depending on your scanners capabilities).
Doing something with the scan
Once the document is scanned in you have to figure out what you want to do with it. If it was a photo for example, simply saving it to JPEG may be suffice, but if it is document you may want to perform OCR to extract the text first.
Saving to JPEG
Saving to JPEG is very easy, wiaImage.SaveFile("temp.jpg");
If you wanted to do more with the JPEG (resize, colour change, filtering, or simply just display in your app) but still wish to treat it as an image, you need to get the image data into either a System.Drawing.Image (WinForms) or System.Windows.Controls.Image (WPF).
WIA.Vector vector = wiaImage.FileData;
Image image = new Image();
image.Source = BitmapFrame.Create(new MemoryStream((byte[])vector.get_BinaryData()));
OCR
OCR is by no means a small task to undertake by yourself, but luckily Office (2003 and up) includes an API named Microsoft Office Document Imaging (MODI) you can program against to let Office process the image for you. Unfortunately, MODI isn’t installed by default with Office 2007 but it is easy enough to add by running the Office setup again, selecting "Add or Remove Features", and then selecting "Scanning, OCR and Indexing Service Filter"
All Office OCR operations must go through the COM library, "Microsoft Office Document Imaging 12.0 Type Library" (that’s for Office 2007) (MDIVWCTL.DLL) so add a reference to it.
MODI.Document mDoc = new MODI.Document();
mDoc.Create("temp.jpg");
mDoc.OCR(MODI.MiLANGUAGES.miLANG_SYSDEFAULT, true, true);
MODI.Image mImage = (MODI.Image)mDoc.Images[0];MessageBox.Show(mImage.Layout.Text);
The key thing to note is that MODI.Document only accept input files from an string representing the filepath, so you have to save the scanned document to disk (in either JPEG or TIFF) rather than reading from memory.
As far as I can tell, this doesn’t retain any layout data (ie, BlockA of text was situation at X,Y) so it doesn’t appear to be the perfect solution for my document manager but it is free (well, so long as you’ve got Office) so I’ll overlook that for now.
Many multi-user applications require a database, be it a web app (probably more often a web app!) or win forms. In single user applications, often it is beneficial if there is a database (in speed, complexity and robustness), but the problem is distributing the database server. I’ve had a few applications that come bundled with MySQL, and it just plain ole sucks.
Some of the reasons for using a database in your application include
- Faster than flat file storage such as XML
- Can have complex relationships
- Can have varying datatypes that don’t break an XML parser
- Can then later redeploy in another project, such as a website using SQL Server easier
One of the easier ways to distribute your winform/WPF application with a database is with Microsoft’s SQL Compact Edition (SQLCE). It has a fairly low footprint, is very fast, and is reasonably powerful despite the reduced operations (which allows it to be fast/low footprint/etc). Visual Studio’s deployment tools even allow you to check for the SQL CE prerequisite on the target machine before installing, and will download SQL CE if it isn’t found!
Adding SQL CE to your project
Providing SQL CE was installed during your Visual Studio install (default install settings), to get a SQL CE database in to your project, all you need to do is add a New Item > Local Database to your project. This will automagically add the references your project will need to access SQL CE databases (although you’ll still need Using System.Data.SqlServerCE;)


Double clicking on your new database in the Project Explorer will activate the Server Explorer, allowing you to add Tables to the database.

Using SQL CE
The way you access data is nearly identical to a normal SQL Server, except it all lives in the System.Data.SqlServerCE namespace, and usually has SqlCeClass rather than SqlClass. ie:
SqlCeConnection sqlCon = new SqlCeConnection(TestApp.Properties.Settings.Default.TestConnectionString);
SqlCeCommand sqlCom = new SqlCeCommand();
sqlCom.Connection = sqlCon;
sqlCom.CommandText = "SELECT * FROM TestTable";
SqlCeDataAdapter sqlDa = new SqlCeDataAdapter(sqlCom);
DataSet ds = new DataSet();
sqlCon.Open();
sqlDa.Fill(ds);
sqlCon.Close();
Using LINQ with SQL CE
In .NET 3.5, you can also use LINQ against SQL CE. Currently (VS2008) you have to use the SQLMetal tool from the Visual Studio CLI, then add the generated dbml file to your project (Add -> Existing Item)
SqlMetal SqlCeFileName.sdf /dbml:LinqClassName.dbml
In the new version of MahTweetsMediaHorn (correction, thanks Will), I’ll be using my own database rather than relying on Windows Media Players database. The LINQ to select all the albums (after generated the dbml via SqlMetal) is..
Music db = new Music(MediaHorn.Properties.Settings.Default.MusicConnectionString);
var album = from a in db.Album select a;
listBox2.ItemsSource = album;
Any and all of the usual tricks for LINQ apply to SQLCE – once you generate the dbml via SQLMetal, it really doesn’t care what is underneath. If you want to bind it properly to WPF with automagic updates for when the datasource updates, I strongly recommend looking into the very clever SyncLINQ by the equally clever Paul Stovell, which also supports Silverlight.
Deploying apps with SQL CE
As I mentioned, the Visual Studio “Publish” tool makes sure the target system has all the prerequisites before installing. SQL CE is automatically added to the list, but if you need to modify it, right click on your project, Properties, then down to the Publish tab, and the Prerequisites option will launch a new dialog.

Just make sure you distribute your application via Build -> Publish :)
Ever noticed how some applications tend to hang when you perform an operation? For example in MahTweets (my Twitter client), it used to have a looong pause every time it updated the Tweet list, and often the application would go black, almost to the ‘not responding’ stage. The GUI and application logic shared the same thread, meaning a massive change in GUI or lots of processing in the logic would stop the other.
The way around this is to use a separate thread for anything that requires a lot of processing, or that is bottled by another factor (Disk IO, or network speed, etc).
public delegate void MyDelegate();
// This method could be the method behind a button.clickpublic void InvokingMethod()
{
Thread myThread = new Thread(new ThreadStart(new MyDelegate(MyMethod)));
myThread.Start();
}
public void MyMethod()
{
//Code to execute on new thread goes here
}
There is one caveat, your new thread cannot access the GUI because this could cause some serious synchronisation issues. The way around this (in WPF at least!) is to use the Dispatcher.Invoke method.
public void GuiMethod()
{
if (!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(DispatcherPriority.Normal, new voidDelegate(GuiMethod));
return;
}
//Code that accesses the GUI
}
If you need to pass parameters, one (quick) way is with an anonymous delegate like below, I’ll let you figure out the different ways to go about it though.
Thread t = new Thread(delegate() { MyMethod(MyParam); });
If you are having problems with concurrency and synchronisation, that’s outside the scope of this post…start looking at wikipedia’s article on threading, and go from there.

Requirements
Introduction
Growl is an application for Apple’s OS X which provides a standard "toasts" interface. Toasts are popups which fade after a short amount of time, and host a small amount of data (usually text, but images, sounds, etc aren’t unheard of).
Snarl is an application for Windows which is inspired by Growl which offers a similar implementation, currently coded in Visual Basic 6.
This article will implement several features of Snarl using Windows Communication Foundation (WCF) and Windows Presentation Foundation (WPF). Before we get started on the actual code, I’ll explain briefly what WCF is.
Continue Reading »