Digg, Flotzam and the Desktop

October 24 2007

I updated Flotzam to support Digg, so now those of you with a Digg addiction (addiggtion?) can watch those Diggs go by.  One thing I did was enable customization so that you can configure Digg by topic or by type (new, popular or all). 

The Digg API is quite nice as is Headzoo's .NET wrapper up on Codeplex. He has a simple desktop app that I published using ClickOnce, which you can try here.

.NET Source Released

October 3 2007

The implications for Microsoft releasing the source of the .NET Framework, including WPF, are huge. Love it. 

Joshua Allen on Marc Andreessen

September 20 2007

Joshua Allen has some good posts going on over on VisitMix.   His most recent, Response to Three Platforms You Meet, is an excellent response to Marc Andreessen's post on The three kinds of platforms you meet on the Internet.  Joshua's take is not what you might expect. He's on to something here, thinking about data as opposed to APIs, something that I'm thinking more and more about, regarding the flow of data on the web.  In general, I'm all about Joshua's particular perspective on the world. He's a great voice coming out of Microsoft.  Folks like him and Jon Udell are inspiring voices and yet more evidence that there's more to Microsoft than meets the eye.

Triangulating Moonlight, Yochai Benkler and Web 2.0

September 12 2007

With the recent announcement of Silverlight being released to the web and the corollary announcement that Microsoft will work with Novell to create a player, named Moonlight, for running Silverlight on Linux, there's been quite a bit of commentary, some of which can be seen on Digg and SlashDot.  There are many different lenses to view this announcement with.  For me, the announcement dovetails with a lot of thinking I've been doing about the Web 2.0 phenomenon and, in particular, its articulation by Yochai Benkler in The Wealth of Networks.  I'm about halfway through the book (at over 500 pages it is dense).  As Bruce Sterling commented at SxSW last year, it is the Das Capital of Web 2.0 -- the allusion to Adam Smith in the title shouldn't be discounted either.  Invisible hand of Web 2.0 anyone?

I love Benkler's theorization of commons-based peer production.  He quite elegantly unpacks the "new modes of production" that are governing the transformation of information and entertainment.  But sometimes I feel his position isn't nuanced enough and becomes either too celebratory or too barbed.  And Microsoft seems to always fall into the "bad guy" camp, where, for example, IBM doesn't?    I don't feel that he gives Microsoft credence in being a positive force toward the "transformation of markets and freedom."  Partly, this is because he wants to use open source as his shining example of how commons-based peer production works and, rhetorically, he must position Microsoft as the "other way". He never teases this out fully, a shame, and his discussion of technology disrupts his more interesting theorization on the cultural and economic consequences.  In discrediting Microsoft, he ends up putting Microsoft down and not recognizing that, in fact, Microsoft is not antithetical to commons-based peer production.  He falls into the very common trap of not acknowledging Microsoft as a platform company.  The infrastructure required for commons-based peer production is made available by Microsoft, often for free, whether it is in the form of an operating system, a development language, a database, a web server  or a blogging engine. The list could go on and on here: Popfly, Codeplex (not to mention the thousands of Windows and .NET projects on SourceForge), Windows Live and more.

And this is where Moonlight comes to mind: to me it is yet another example of how Microsoft is in fact committed to the explosion of the Web 2.0 phenomenon.  Just as Microsoft embraced web services and interoperability for improved heterogeneity in the back end, Silverlight and Moonlight are acts of embracing interoperability and heterogeneity on the front end.  To bring it back to Benkler, I can create my videos using Microsoft tooling and know that they will be viewable on a Mac, a Windows box or a Linux box in the browser of my choice.

Why Rhizohm?

August 29 2007

The inspiration for this neologism -- which mashes up rhizome + ohm -- are the writings of Gilles Deleuze and Felix Guattari, in particular the introduction to their book, A thousand plateaus [1], in which they articulate a vision and explication of rhizomatic systems.  A rhizome, in botany, is a horizontal stem of a plant that sends out roots and shoots from its nodes.

[2]

Deleuze and Guattari use the rhizome as a metaphor to think about non-hierarchical, "anexact" systems, which are applicable far beyond botany.  They provide examples of animal rhizomes in their pack form such as rats or burrow and my favorite example being ants: "You can never get rid of ants because they form an animal rhizome that can rebound time and again after most of it has been destroyed." (p.9)

[3]

(Which makes me think of Rudy Rucker's The Hacker and the Ants [4] but that's another whole post.)

But the most interesting application of rhizomatic structures applies to human systems.  They outline four characteristics of rhizomatic systems:

  1. Principle of Connection: "Any point of a rhizome can be connected to anything other and must be. This is very different from the tree or root, which plots a point, fixes an order." (p.7)
  2. Principle of Heterogeneity: "There is no ideal speaker-listener, nay more than there is a homogenous linguistic community.  Language is, in Weinreich's words, 'an essentially heterogeneous reality.'" (p.7)
  3. Principle of Multiplicity: "Unity always operates in an empty dimension supplementary to that of the system considered (overcoding). The point is that a rhizome or multiplicity never allows itself to be overcoded, never has available a supplementary dimension over and above  its number of lines..." (p.8-9)
  4. Principle of Asignifying Rupture: "Every rhizome contains lines of segmentarity according to which it is stratified, territorialized, organized, signified, attributed, etc., as well as lines of deterritorialization down which it constantly flees." (p.) This last point is very important, in that it complicates the very simple binary or dialectic that starts to appear and is tempting to reduce their thinking to.

[5]

Delueze and Guattari go on to explicate how rhizomatic systems work, especially in contrast to arboreal systems.  They provide many other great examples, such as the human brain itself: "Many people have a tree growing in their heads, but the brain itself is much more a grass than a tree." (p.15).  Ultimately, I can't do justice to their explication and I would highly recommend reading the introduction on rhizomes -- and the whole book for that matter. 

Where things get interesting is in applying some of their theories to computer science, the internet and the Web 2.0 phenomenon, which is the crux of my neologism, rhizohm, where the organic meets the digital, where we witness the marriage of hierarchy (XML, file systems, object hierarchies) with rhizomes (multiple personas, wikis, trackbacks).  I see rhizohms as the manifestation of rhizomes online.  Consider the following quote:

"To these centered systems, the authors contrast acentered systems, finite networks of automata in which communication runs from any neighbor to any other, the stems or channels do not preexist, and all individuals are interchangeable, defined only by their state at a given moment - such that the local operations are coordinated and the final, global result synchronized without a central agency." (p.17)

To me, this single statement can inform and provide models for much of what happens online.  The obvious application is to the structure of the web itself.  Already, there has been some good work on this front: check out Rhizome Navigation and some of their work:

But I want to extend my thinking about rhizohms beyond navigation and structure to the very concepts of identity and authorship on the web.  A single blog entry becomes rhizomatic when on one page exists comments from other "authors", embedded images and videos from other sources, and, of course, hyperlinks.  We each create rhizohms of the web, our own sprawls of content and presence on wikis, forums, social networks, etc. And, perhaps most interesting, is this dialectic that unfolds when rhizohms and hierarchies clash. (Wikipedia, anyone?)

Much more to be written on this topic, but that at least gets it going...

[1] Deleuze, Gilles and Guattari, Felix. A thousand plateaus; translation and forward by Brian Massumi. University of Minnesota Press, 1987.

[2] Photo courtesy of flowerfreak from Flickr under Creative Commons License

[3] Photo courtesy of albuam from Flickr under Creative Commons License

[4] Rucker, Rudy. The Hacker and the Ants.   Four Walls Eight Windows; Version 2.0 edition, 2002.

[5] Photo courtesy of dimitri66 from Flickr under Creative Commons License

 

No Dev Tools: MSBuild, MSBee, .NET 1.1 and the Command Line

August 25 2007

I was on a machine with no dev tools and needed to recompile a .dll for .NET 1.1.  I had the .csproj file and am so MSBuild-centric that I figured I'd open a command prompt and type:

set path=%path%;%windir%\Microsoft.NET\Framework\v2.0.50727

Then I'd be all set.  Ah, but I forget that this was a .NET 1.1 project -- no love.  Fortunately, the good folks from Visual Studio created a "power toy" (gotta love power toys) that allows you to use MSBuild to target .NET 1.1.  It is called MSBee.

Once that was installed (which required I download the .NET 1.1 SDK, kind of large at 100+ MB but what can you do?) I was able to compile the assembly.  Their docs were a little confusing; they suggest you can either add an <Import> to the .csproj file or pass some switches to MSBuild. I had to do both, adding the <Import> statement:

<Import Project="$(MSBuildExtensionsPath)\MSBee\MSBuildExtras.FX1_1.CSharp.targets" Condition=" '$(BuildingInsideVisualStudio)' == '' AND '$(TargetFX1_1)'=='true'" />

As well as passing the following switch:

msbuild [project file] /p:TargetFX1_1=true

But once I did that I was good to go! 

Facebook Desktop Explorer

August 22 2007

It bothers me when there is a great sample application available, but no one can get to it unless they are a developer who downloads the source and compiles the application.  Such is the case with a desktop application that is part of the Microsoft Facebook Developer Toolkit called Facebook Desktop Explorer.  The application allows you to browse Facebook friends, photos and events. It also maps all Facebook friends to Microsoft Virtual Earth. 

I've used ClickOnce to publish the application and make it simple for people to install from the web. Go check it out!  Here are some screenshots to give you a sense of the application:

WPF Tips and Tricks: Window.Show() Without Activating The Window

August 22 2007

So you want to spawn a new WPF window but you don't want it to be activated?  This is doable in Win32, but with WPF, it presents some problems ... until now.  This issue recently came up and some folks (read: not me) on the WPF team discovered a a pretty clever workaround.  Basically, the workaround is to use an obscure windows hooks that exists for Computer Based Training (CBT), which allows or a training program to choose to ignore or allow messages to get through to the window.

So, the solution is to set the hook before calling the Show() method on the window. The call back receives the HCBT_ACTIVATE notification, returns 1 to ignore/prevent the operation, then unhooks the hook. The window is shown, but does not take focus. There is no flicker or visible degradation.

If you'd like to see this working in action, check out the sample application that I've deployed via ClickOnce.  You'll notice that the main window will spawn three windows yet you will continue to be able to type in the textbox of the main window. I've posted the source code and here's the crux of the code if you are interested:

 

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;


namespace ShowWindowWithoutActivating
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public partial class Window1 : System.Windows.Window
    {
        delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        private HookProc myCallbackDelegate;
        IntPtr hook;

        DispatcherTimer dt = new DispatcherTimer();

        int counter = 0;

        public Window1()
        {
            InitializeComponent();
            textBox1.Focus();
            dt.Interval = new System.TimeSpan(0, 0, 3);
            dt.Tick += new EventHandler(TimerTick);
            dt.Start();

            // initialize our delegate
            this.myCallbackDelegate = new HookProc(this.MyCallbackFunction);

        }
        public void TimerTick(object sender, EventArgs e)
        {
            if (counter == 2) dt.Stop();
            counter++;

            Window w = new Window();
            w.Title = "TestWindow";
            w.Width = 400;
            w.Height = 300;
            w.Top = 400;
            w.Left = 400;

            // setup a cbt hook
            hook = SetWindowsHookEx(5 /* wh_cbt */, this.myCallbackDelegate, IntPtr.Zero, AppDomain.GetCurrentThreadId());
            w.Show();
        }

        private int MyCallbackFunction(int code, IntPtr wParam, IntPtr lParam)
        {
            switch (code)
            {
                case 5: /* HCBT_ACTVIATE */
                    UnhookWindowsHookEx(hook);
                    return 1; /* prevent windows from handling activate */
            }
            //return the value returned by CallNextHookEx
            return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
        }

        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int code, HookProc func, IntPtr hInstance, int threadID);

        [DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    }
}

2008 SxSW Interactive: Check Out My Session &quot;Why Microsoft Doesn't Suck&quot;

August 20 2007

I've got a session proposed for the 2008 SxSW Interactive Conference called Why Microsoft Doesn't Suck.  More philosophical than technical, this session, if picked, will be a culmination of some ideas that I have been cogitating on for awhile, many of which will start filtering out into this blog.  Reading folks like Yochai Benkler and Geert Lovink has inspired me to think beyond code.  I am hoping that the re-launch of this blog will provide a place for some of these ideas to come to fruition.  First up: what is a rhizohm anywhy?  Stay tuned...

Consuming JSON From WPF

August 9 2007

I want to throw up some prototype code that consumes JSON from WPF. (For more on JSON, see this article.) I put together that uses the JavaScriptSerializer to deserialize JSON into CLR objects, which could then be used for databinding. 

Here's what I did. First, I went and downloaded the ASP.NET AJAX framework.  Then, I created a new WPF project and added a reference the System.Web.Extensions dll, which got installed to C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions.  I then added the System.Web.Script.Serialization to my using statements.

To keep things simple, I wanted to prove I could convert this JSON:

{ "FirstName": "Karsten", "IsAlive": "true"}

 

Into this CLR type:

class Person
{
    public string FirstName;
    public bool IsAlive;
}

 

Turned out to be pretty simple.  Here's the code:

public Window1()
{
    InitializeComponent();
    JavaScriptSerializer jss = new JavaScriptSerializer();
    jss.RegisterConverters(new JavaScriptConverter[] { 
    new PersonConverter() });
    string test = "{\"FirstName\": \"Karsten\", \"IsAlive\": \"true\"}";
    Person p = jss.Deserialize<Person>(test);
    Person p = jss.d
}

Note how I register this thing called the PersonConverter after I instantiate the JavaScriptSerializer .  That's where all the work gets done and I'll discuss the PersonConverter below.  The only other interesting thing to note here is that to get the Person object,  I use the Deserialize<> method instead of the DeserializeObject(). This allows me to actually pass the type I want to have returned rather than attempting to cast the object afterward.

So, here's the code for the PersonConverter, which overrides the JavaScriptConverter :

class PersonConverter : JavaScriptConverter
{

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        Person p = new Person();
        p.FirstName = serializer.ConvertToType<string>(dictionary["FirstName"]);
        p.IsAlive = serializer.ConvertToType<bool>(dictionary["IsAlive"]);
        return p;
    }
    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new Exception("The method or operation is not implemented.");
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new Type[] { typeof(Person)}; }
    }
}

The crux of the code here is in the override of Deserialize.  I followed the SDK documentation and made sure to use the ConvertToType method instead of doing the casting myself.  Basically, I just map each property from the JSON to the CLR object.  One could probably get fancy and use Reflection to do this dynamically, if you had everything singing.

I think I'll iterate on this a little more in a future post, but the net is that you can consume JSON into your WPF applications!