Paul's MCS Developer Blog

Sharing and blabbing on my findings as a Microsoft consultant

April, 2008

Posts
  • Paul's MCS Developer Blog

    Personal Twitter Client Counter

    • 0 Comments

    Get a count and percentage of how many updates you've had with each twitter tool.

    Download C# 3.5 WPF Source Code
    Note: This source code is mostly a quick hack to get the data I wanted. Also, if you run this on your own data, note that you may need to wait a few minutes for results to come back.

    In testing out various twitter clients, I wanted to get a feel for my personal usage (how much I've used each client), so I decided I'd write some code around it. To begin, here are the results:

    web, 1770, 41.549%  Clipboard02
    im, 1214, 28.498%
    txt, 713, 16.737%
    SnapFoo, 153, 3.592%
    twigadge, 146, 3.427%
    Twadget, 128, 3.005%
    TwitterFox, 61, 1.432%
    Snitter, 21, 0.493% 
    Jott, 17, 0.399%
    TwitBin, 16, 0.376%
    twitterfeed, 7, 0.164%
    Spaz, 6, 0.141%
    Twitter Opera widget, 3, 0.070%
    twhirl, 3, 0.070%
    Twittearth, 2, 0.047%

    I snagged an API code sample and fired up my trusty Visual Studio 2005. Thankfully (so I could step out of my box a bit), the code sample was in C# 3.5! So... I popped open my laptop and set out coding (finally, for the first time outside of dragging some controls around) in Visual Studio 2008.

    As part of this, I wrote my first LINQ-to-XML query!

    This code makes a request to twitter (you have to be authenticated first) and gets an anonymous type list called sc that has the key (the name of the source, as shown above) and the count from that page. After that I work some magic to aggregate them across all pages, though I'm investigating how to do the aggregation by first combining the XElement-s from each page (though that would take up a lot of memory).

    url = "http://twitter.com/account/archive.xml?page=" + x.ToString();
    
    WebRequest Request = HttpWebRequest.Create(url);
    Request.Credentials = new NetworkCredential(userName, password);
    WebResponse Response = Request.GetResponse();
    Stream stream = Response.GetResponseStream();
    TextReader reader = new StringReader(new StreamReader(stream).ReadToEnd());
    XElement statuses = XElement.Load(reader);
    
    // My first LINQ query!
    var sourceNames = from source in statuses.Descendants("source")
                      group source by source.Value into sc
                      orderby sc.Count() descending
                      select new { sc.Key, MyCount = sc.Count() };

    I also got to play around in WPF just a little. Nothing fancy at all, but it was nice to see the new IDE in action. It feels much more powerful.

    I may play around with this some more, add graphing, toy around with it as a Silverlight 2 app. Or it might just sit there and do nothing ;-)

     If you'd like a more full-featured statistics tool for your twitter status updates, check out TweetStats (my stats).

  • Paul's MCS Developer Blog

    Latest tool: XPath query field extractor for InfoPath

    • 0 Comments

    Update: This tool seems to be only relevant with InfoPath 2003. A co-worker pointed out that due the customer pains around a lack of a feature like this, in InfoPath 2007 you can right-click a node in the data source and choose "Copy XPath". Cool! Thanks to Scott Heim for pointing this out.

    So, I love making tools. One-off things that process something. Batch files that lessen monotony. Sexy little WinForm apps for displaying data. XSL transformations that regurgitate and pre-process XML.

    My latest tool is a small WinForms app that pulls out a list of fields form an InfoPath document so they can be referenced as XPath. This is pretty neat because my client needed a documentation artifact, and this saved quite a bit of tedium. Getting this data also proved difficult because the Namespace URI for the "my" namespace is always changing because it includes a timestamp (see solution below).

    Here's a sample of the output. You can use each of these lines as XPath queries against the document:

    my:MyFields/my:secMain my:MyFields/my:secMain/my:secPhysicalDescriptionHeader my:MyFields/my:secMain/my:secDualCitizenshipMain my:MyFields/my:secMain/my:secDualCitizenshipMain/my:secDualCitizenshipName my:MyFields/my:secMain/my:secDualCitizenshipMain/my:secDualCitizenship
    .
    .
    .

    The tool uses the CAB SDK's extract.exe via a command shell to pull out the template.xml file from the InfoPath XSN file.

    The code for using the SDK was pretty straightforward. In this case (since we want the XML template in the InfoPath, the variable ExtractionFileName is defined as:

    private const string ExtractionFileName = "template.xml";

    And fileName is the location of the XSN file. The code for the extraction is:

    // Use the CAB SDK to grab the template file from the InfoPath XSN package
    Process proc = new Process();
    proc.StartInfo.FileName = ".\\EXTRACT.EXE";
    proc.StartInfo.Arguments = string.Format("\"{0}\" {1}", fileName, ExtractionFileName);
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    proc.Start();
    proc.WaitForExit();

    Dealing with the ever-changing "my" namespace

    One particular challenge arose. Since the "my" namespace in InfoPath is defined with a timestamp, every time you change the schema the namespace URI changes. So, I had to do a little preprocessing before I could read the fields (since they're all in the "my" namespace). Thankfully the timestamp is of fixed length.

    XmlDocument doc = new XmlDocument();
    doc.Load(extractionFilePath);
    
    // Use a low-tech way to get the "my:" namespace URI, since it 
    // differs by form and when changes are made
    string fileContents = File.ReadAllText(extractionFilePath);
    int myIndex = fileContents.IndexOf("xmlns:my=") + 10;
    string myNamespace = fileContents.Substring(myIndex, 75);
    
    XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
    mgr.AddNamespace("my", myNamespace);
    
    XmlNode myFieldsNode = doc.SelectSingleNode("//my:myFields", mgr);

    After you get the "myFieldsNode" you can recursively iterate through the nodes and output the fields.

  • Paul's MCS Developer Blog

    Synchronize XSD from an InfoPath document with a SharePoint project for server-side XSD validation

    • 0 Comments

    In order to implement server-side XSD validation against an InfoPath form submission, I had to pull the XSD from the InfoPath document archive (XSN file) and use that to update an embedded resource in a SharePoint solution project (including automated checkout/checkin in TFS). I was able to do it using a batch file.

    Pretty specialized need, but maybe somebody could make use of it someday ;).

    Note: If you want to use this code, you'll have to combine some of the lines that were too long to display.

    @echo off 
    
    rem ***********************************************************
    rem This batch file is used to extract the XSD files from each 
    rem of the InfoPath forms, and copy them into the source tree
    rem Download and install the Microsoft CAB SDK from 
    rem http://support.microsoft.com/kb/310618 to c:\cabsdk
    rem *********************************************************** 
    
    rem IMPORTANT: Set these values to your system. Do not include 
    rem trailing slashes, and include values in quotes if necessary 
    
    set CABSDK_PATH=c:\cabsdk\bin
    set ROOT=C:\projects\projectname
    set TFS_USERNAME="domain\user.name"
    set TFS_PASSWORD=password 
    
    rem These should be relatively fixed
    set FORMS_ROOT=%ROOT%\Project.Namespace\12\TEMPLATE\Layouts\infopathForms
    set XSD_ROOT=%ROOT%\Project.Namespace\12\Resources
    set TF_PATH=C:\Program Files\Microsoft Visual Studio 8\Common7\IDE 
    
    echo.
    echo ********* InfoPath Form 1 *********
    echo.
    set FORM_PATH=%FORMS_ROOT%\Form 1\Form1.xsn
    set XSD_PATH=%XSD_ROOT%\Form1.xsd
    set RETURN=FINISH
    goto UPDATE_SCHEMA 
    
    :FINISH
    goto FINISH_BATCH
    
    :UPDATE_SCHEMA
    echo Checking file out...
    "%TF_PATH%\tf.exe" edit "%XSD_PATH%" 
        /login:%TFS_USERNAME%,%TFS_PASSWORD% /noprompt >/nil 
    
    echo Extracting file...
    del myschema.xsd
    "%CABSDK_PATH%\extract.exe" "%FORM_PATH%" myschema.xsd >/nil 
    
    echo Replacing file...
    copy myschema.xsd "%XSD_PATH%" >/nil 
    
    echo Checking file in...
    "%TF_PATH%\tf.exe" checkin "%XSD_PATH%" 
        /login:%TFS_USERNAME%,%TFS_PASSWORD% /noprompt 
        /comment:"Automated checkin from XsdExtractor script" >/nil 
    
    goto %RETURN% 
    
    :FINISH_BATCH 
    
  • Paul's MCS Developer Blog

    Live Writer: Word+Social media, for bloggers

    • 0 Comments

    I just started using Windows Live Writer to update my blogs*. I'm thoroughly impressed with what I see, both from the practical sense and just how much cool seems to surround this thing.

    1) My Apartment Building, Washington, DC

    Software+Services is Microsoft's answer to the debate about where the future of computing is going in the near future. My take on what this means is a badass WinForms interface with a sexy back-end built around some Web 2.0-ish stuff. That's the technical explanation.

    Live Writer epitomizes all of this. It's a lightweight, feature- and graphics-rich editing environment, and it's very closely integrated with a bunch of "Web 2.0" sites, including a pile of blog packages and social media sites.

    There are some neat plug-ins "out of the box", including one that took me exactly 12 seconds to show you an image of my apartment building (see image 1).

    Plus, there seems to be an active plug-in community developing things to better pretty up source code, integrate with Flickr, Facebook and other sites. Some of em are crap, but the architecture seems like it must be easy enough to be accessible. One cool one is the Amazon Book Lookup plugin (see example below)

    Some of the interface features I'm falling in love with include the ability to match the style to the blog's style (so I can switch between the three blogs and see how it'll look in each one), and the ability to pull up old posts from the "Open" menu.

    Party of One: The Loners' Manifesto
    by Anneli Rufus

    Read more about this book...

    * My blogs:

Page 1 of 1 (4 items)