Andrew Coates ::: MSFT

It's all about community!

  • Andrew Coates ::: MSFT

    TechEd Australia LightSwitch Decks and Resources

    • 1 Comments

    My TechEd Australia sessions proved to be pretty popular and I had a great time catching up with people afterwards.

    The number 1 resource you need for LightSwitch is http://msdn.com/lightswitch

    Here are the decks:

    Introduction to Visual Studio LightSwitch DEV201

    Advanced Solutions with Visual Studio® LightSwitch™ DEV213

  • Andrew Coates ::: MSFT

    LightSwitch Decks from TechEd NZ

    • 0 Comments

    I presented two sessions at TechEd NZ last week and I've attached the decks here for anyone who's interested.

    Introducing Visual Studio LightSwitch DEV203

    Visual Studio LightSwitch Beyond the Basics DEV308

  • Andrew Coates ::: MSFT

    Windows Azure Toolkit for Social Games & Tankster Version 1.0 | Nathan Totten

    • 0 Comments

    This looks like it could be a lot of fun. I think I've figured out what my son and I are going to do in our spare time for the next little while.

    Windows Azure Toolkit for Social Games & Tankster Version 1.0 | Nathan Totten

  • Andrew Coates ::: MSFT

    Document Creation and Conversion with the OpenXML SDK and SharePoint 2010 Word Automation Services – Part 2

    • 0 Comments

    A long time ago, I wrote Part 1 of this post, based on the presentation I did at the 2010 SharePoint Conference in Sydney. If you're following along with the code, you may want to review that post so you can set up your development environment to match mine.

    To quickly recap, the last post showed how to create Word (OpenXML, docx) documents programmatically and write them to disk using the OpenXML SDK (and therefore without the requirement for Word/Office on the machine creating the documents).

    In this part, I'll extend the solution to write the documents to a document library in SharePoint and then use Word Automation Services to automatically convert the docx files to PDF format.

    Setup

    To follow along with this walkthrough without changes, setup your SharePoint instance (at http://localhost) as follows:

    • Create a document library called "Created Docs" in the root site
    • Create a document library called "Converted Docs" in the root site

    If you use a remote server, and/or a different site or library names, you'll need to adjust some of the URI and path strings in the code below to make it work.

    Writing to a SharePoint Library

    Carrying on from last time, wire up the click event of the CreateOneSharePointDocumentButton:

    Click event handler
    1. private void CreateOneDocumentOnSharePointButton_Click(object sender, EventArgs e)
    2. {
    3.     gen.CreateOneDocumentOnSharePoint();
    4. }

    Generate a stub for the CreateOneDocumentOnSharePoint() method in the DocGenerator class using the Ctrl+. technique made possible by the Visual Studio 2010 Productivity Power Tools.

    Switch to and add a using statement to the DocGenerator class to give you access to the SharePoint Client Libraries - giving it an alias will help disambiguate the File class later:

    1. using SPC = Microsoft.SharePoint.Client;

    Using the SharePoint Client Libraries, it's very easy to write documents to a document library, and there's no need to write a document to a local drive. This means we'll use a different overload of the OpenXML SDK's WordprocessingDocument.Create() method that writes, not to a file, but to a MemoryStream.

    CreateOneDocumentOnSharePoint
    1. internal void CreateOneDocumentOnSharePoint()
    2. {
    3.   SPC.ClientContext clientContext = new SPC.ClientContext("http://localhost");
    4.   string fileUrl = "/Created Docs/MyVeryVeryCoolDoc.docx";
    5.  
    6.   sw.Reset();
    7.   sw.Start();
    8.  
    9.   using (MemoryStream ms = gen.CreatePackage())
    10.   {
    11.     ms.Seek(0, SeekOrigin.Begin);
    12.     SPC.File.SaveBinaryDirect(clientContext, fileUrl, ms, true);
    13.   }

    In this code, you create a new SharePoint.Client.ClientContext that gives access to the site (in this case at http://localhost, but if you've got things set up differently, change it here).

    Create an overload of the CreatePackage() method in the DocumentCreator class that creates and populates a MemoryStream:

    CreatPackage Overload
    1. internal MemoryStream CreatePackage()
    2. {
    3.  
    4.   MemoryStream ms = new MemoryStream();
    5.   using (WordprocessingDocument package =
    6.     WordprocessingDocument.Create
    7.     (ms, WordprocessingDocumentType.Document))
    8.   {
    9.     CreateParts(package);
    10.   }
    11.  
    12.   return ms;
    13.  
    14. }

    Move the pointer to the start of the MemoryStream and call the File.SaveBinaryDirect() method passing in the ClientContext, a string indicating where the file should be written, the stream and a boolean that tells SharePoint whether or not to overwrite an existing file with the same name.

    Running the app and clicking the One document in SharePoint button shows that it's very fast - in my case 102ms

    Writing 1 document to SharePoint took 0.1 seconds

    Writing lots of documents is fast too - add an event handler to the CreateOneSharePointDocumentButton:

    Click Event Handler
    1. private void CreateManyDocumentsOnSharePointButton_Click(object sender, EventArgs e)
    2. {
    3.   gen.CreateManyDocumentsOnSharePointInParallel((int)NumberOfDocumentsToCreate.Value);
    4.  
    5. }

    And add a CreateManyDocumentsOnSharePointInParallel() method that uses a Parallel.For() loop to call CreatePackage() and File.SaveBinaryDirect() for as many files as you create:

    Create lots of SharePoint Docs
    1. internal void CreateManyDocumentsOnSharePointInParallel(int NumberOfDocs)
    2. {
    3.   SPC.ClientContext clientContext = new SPC.ClientContext("http://localhost");
    4.   string fileUrl = "/Created Docs/MyEvenCoolerDoc{0:D5}.docx";
    5.  
    6.   sw.Reset();
    7.   sw.Start();
    8.  
    9.   Parallel.For(0, NumberOfDocs, i =>
    10.   {
    11.  
    12.     using (MemoryStream ms = gen.CreatePackage())
    13.     {
    14.       ms.Seek(0, SeekOrigin.Begin);
    15.       SPC.File.SaveBinaryDirect(clientContext, string.Format(fileUrl, i), ms, true);
    16.     }
    17.  
    18.   });
    19.  
    20.   sw.Stop();
    21.  
    22.   System.Windows.Forms.MessageBox.Show(string.Format(
    23.       "Wrote {3} documents to SharePoint ({1}{2}) in {0} ms (using parallel processing)",
    24.       sw.ElapsedMilliseconds,
    25.       clientContext.Url,
    26.       fileUrl,
    27.       NumberOfDocs));
    28.  
    29. }

    This is also pretty fast - in my case 40ms per document.

    Writing 100 documents to SharePoint (in parallel) took 4 seconds

    Navigating to the document library shows all those documents sitting just where you'd expect to see them:

    Cool documents created en-masse

    Converting Word Documents to a Fixed Format (PDF or XPS)

    PDFUp until now, we've not had to use Word (or any other Office client) as all we've been doing is generating documents, not rendering them. Just like you can create an HTML document without requiring a browser, it's perfectly valid to create a Word document (or any other OpenXML format document) without using Word.

    However, to view the document, or to create a fixed version of it like PDF or XPS, it's necessary to render it. Up until the release of SharePoint 2010, the highest fidelity way to do this was to open the document in Word. Of course, doing that on the server was fraught with difficulty. Word is not designed to be a server-side tool - it throws (sometimes modal) dialogs, it spends a lot of resources on updating the screen and it's not optimised for multi-processor, large memory scenarios. When there is a user interacting with Word though, the bottleneck is rarely the computer.

    The SharePoint team addressed this problem with the Word Automation Services feature in SharePoint 2010 (standard edition and higher). Word Automation Services is the client code from Word with the UI bits stripped out and optimised to run as a server process. All of the rendering engine is available for SharePoint to use without any of the issues (both technical and from a licensing point of view) of using Word on a server. There's lots of great info on Word Automation Services on MSDN and elsewhere. Here's the list of resources I provided in the first post in this series:

    Word Automation Services (WAS) document conversion jobs run as as an asynchronous server-side job that can either be scheduled automatically (for example, when a document is placed in a folder) or programmatically. Either way, the job won't start immediately, just the next time the WAS scheduler runs. The frequency of the scheduler running is set in Central Administration - see the links above for details on how to set it up. I set it to the minimum interval - one minute.

    Interacting programmatically with the service is pretty straightforward, but there are two gotchas:

    1. the .NET libraries are 3.5 only, so the project you create must be a .NET 3.5 project, and
    2. the calls will fail (with cryptic exceptions) if it's not a 64-bit call, so you must target either x64 or Any processor type, not x86.

    Create a new console application and make sure that the target framework is 3.5.

    Create a new console application targetting Framework 3.5

    Open the Visual Studio Configuration Manager dialog by dropping down the Solution Configurations drop-down on the Visual Studio Standard toolbar (or choosing Configuration Manager from the Build menu):

    Choose Configuration Manager

    Next, add a Solution Platform:

    image

    to target Any CPU (or x64)

    image

    Now you're ready to start building.

    Converting a single document to PDF

    Add references to the Microsoft.SharePoint and Microsoft.Office.Word.Server assemblies.

    Add using statements for those assemblies:

    1. using Microsoft.SharePoint;
    2. using Microsoft.Office.Word.Server.Conversions;

    Add a couple of static string properties to the class that you can adjust to suit the way you've got your SharePoint setup configured:

    1. // If you manually installed Word Automation Services, then replace the name
    2. // in the following line with the name that you assigned to the service when
    3. // you installed it.
    4. static string cWordServicesName = "Word Automation Services";
    5. static string siteUrl = "http://localhost";

    Now you can initiate the conversion of a single document:

    Convert a single document
    1. private static void SingleConv()
    2. {
    3.   using (SPSite spSite = new SPSite(siteUrl))
    4.   {
    5.     ConversionJob job = new ConversionJob(cWordServicesName);
    6.     job.UserToken = spSite.UserToken;
    7.     job.Settings.UpdateFields = true;
    8.     job.Settings.OutputFormat = SaveFormat.PDF;
    9.     job.AddFile(siteUrl + "/Created%20Docs/MyAwesomeDoc.docx",
    10.         siteUrl + "/Converted%20Docs/MyAwesomeDoc.pdf");
    11.     job.Start();
    12.     Console.WriteLine("Job ID: {0} started", job.JobId);
    13.     Console.WriteLine("Press the any key ...");
    14.     Console.ReadKey();
    15.   }
    16. }

    There are a few things to note here.

    Firstly, you get a reference to the Site using the SharePoint libraries, not the SharePoint Client libraries that we used to write the Word docs to the list in the first place.

    Next, you need to pass a user token to the new ConversionJob, and you get that from the SPSite user token.

    Third, you specify the output format using the SaveFormat enumeration.

    Finally, remember the service is performed asynchronously and so although you get a Job ID back, you don't get any more information about the job status (more on that when we do bulk conversions)

    Converting documents to PDF en-masse

    Converting whole libraries at once is also very easy. The ConversionJob class has an AddLibrary() method that takes as parameters a source and destination SPList object.

    Converting whole libraries
    1. private static void BulkConv()
    2. {
    3.   using (SPSite spSite = new SPSite(siteUrl))
    4.   {
    5.     Console.WriteLine("Starting conversion job");
    6.     ConversionJob job = new ConversionJob(cWordServicesName);
    7.     job.UserToken = spSite.UserToken;
    8.     job.Settings.UpdateFields = true;
    9.     job.Settings.OutputFormat = SaveFormat.PDF;
    10.     job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;
    11.     SPList listToConvert = spSite.RootWeb.Lists["Created Docs"];
    12.     SPList listToPopulate = spSite.RootWeb.Lists["Converted Docs"];
    13.     job.AddLibrary(listToConvert, listToPopulate);
    14.     job.Start();
    15.     Console.WriteLine("Bulk conversion job {0} started", job.JobId);
    16.     ConversionJobStatus status = new ConversionJobStatus(cWordServicesName,
    17.         job.JobId, null);
    18.     Console.WriteLine("Number of documents in conversion job: {0}", status.Count);
    19.     while (true)
    20.     {
    21.       System.Threading.Thread.Sleep(5000);
    22.  
    23.       status.Refresh();
    24.       if (status.Count == status.Succeeded + status.Failed)
    25.       {
    26.         Console.WriteLine("{2} Completed, Successful: {0}, Failed: {1}",
    27.             status.Succeeded, status.Failed, DateTime.Now);
    28.         break;
    29.       }
    30.       Console.WriteLine("{2} In progress, Successful: {0}, Failed: {1}",
    31.           status.Succeeded, status.Failed, DateTime.Now);
    32.     }
    33.  
    34.     Console.ReadKey();
    35.   }
    36. }

    Checking the status of the job is straightforward (as long as you have the JobId - a GUID uniquely identifying this conversion job). The ConversionJobStatus object holds information about the conversion job including how many documents are to be converted, how many have been converted successfully and how many have failed. Calling the Refresh() method gets the most up-to-date status and you can use that to poll for completion. Remember that jobs only start every <n> minutes, where n is a setting in SharePoint Central Administration

    Converting documents is an asynchronous process

    The result is a SharePoint list full of PDF files, created without ever needing to open Word.

    A library full of converted PDFs

    A converted PDF in Adobe Reader

    Conclusion

    The combination of the OpenXML SDK and Word Automation Services makes server-side document creation simple, scalable and efficient. This is definitely a tool worth adding to your arsenal.

    Source Code

    I've zipped up the two solutions - the document creation (.NET 4.0) WinForms project and the document conversion (.NET3.5) project for you to download and play with. Notice that they are NOT production ready - they're illustrative only. Use them at your peril, your mileage may vary, contents may be hot no guarantees etc … you know the drill.

    Document Creation Solution Download (241kB)
    Document Conversion Solution Download (115kB)

  • Andrew Coates ::: MSFT

    Counting the number of sections in an OpenXML Document

    • 0 Comments

    1/4/11 - Updated a couple of images and some of the code explanation

    Adam Cogan asked me a question the other day that asked (among other things) "How do you know if a doc has multiple sections?"

    In Word, of course, you can break a document up into sections by inserting a section  break from the Breaks button in the Page Setup group on the Page Layout tab:

    Inserting section breaks manually in Word is easy

    It turns out that counting these programmatically is really easy using the OpenXML SDK 2.0 (download)

    I created a new console application, added a reference to DocumentFormat.OpenXML and WindowsBase and used this code:

    Count Sections in Word Docx
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.IO.Packaging;
    6. using DocumentFormat.OpenXml.Wordprocessing;
    7. using DocumentFormat.OpenXml.Packaging;
    8. using DocumentFormat.OpenXml.Office2010.Word;
    9.  
    10. namespace CountSections
    11. {
    12.   class Program
    13.   {
    14.     static void Main(string[] args)
    15.     {
    16.       if (args.Length != 1)
    17.       {
    18.         Console.WriteLine("Usage: CountSections <filename>");
    19.       }
    20.       else
    21.       {
    22.         using (WordprocessingDocument d =
    23.             WordprocessingDocument.Open(args[0], false))
    24.         {
    25.           Console.WriteLine("Found {0} section(s)",
    26.               d.MainDocumentPart.Document.Body.Descendants().
    27.               OfType<SectionProperties>().Count()
    28.               );
    29.         }
    30.         Console.WriteLine("Press any key ...");
    31.         Console.ReadKey();
    32.       }
    33.     }
    34.   }
    35. }

    In it I take the filename passed as an argument and open it ReadOnly (line 22-23). I then find the number of sections using the typed enumerator (lines 26-27)

    I also added the path to a file in the Command Line Arguments edit box in the Debug tab of the project Properties so there's a file being passed in when I press F5:

    Pass a file name in as a command line argument

    Running the program gives the answer very quickly:

    Resulting output - we found 2 sections

    Cool huh?

    Sample file with 2 sections Download

  • Andrew Coates ::: MSFT

    Storytelling - A Moth-eaten theme

    • 1 Comments

    One of the most effective ways to get a message, any message, across is to use stories. For some reason the human brain appears to be wired to be good at remembering and regurgitating stories. I like to begin presentations with a story that’s somehow relevant and am always on the lookout for a good story to add to my repertoire.

    The best stories seem to be those told from a personal perspective - either something that happened to you or something you witnessed. Good stories also stir emotions, both in the storyteller and the listener.

    The MothThis week I heard two stories that did just that. I’ve been a listener to the Moth Podcast for some time now, and have always enjoyed the mix of professional storytelling with deeply personal and evocative content. Two of the stories I heard this week though moved me as much or more than any other I’ve heard.

    The first, told by a comedian, wasn’t funny. The second, told by someone who plays the blues, was uplifting. Both made either made me laugh or cry - literally out loud.

    Listen to

    and then tell me whether you experienced the same thing.

    While you’re there, subscribe to the Moth podcast either in iTunes or via their RSS feed.

  • Andrew Coates ::: MSFT

    More VSS to TFS Workshops this Month in MEL, SYD, BNE and Online

    • 0 Comments

    VSS to TFS Workshops

    Hot on the heels of my post on the Readify DevDay in Sydney, I got a note about even more VSS to TFS workshops (this time presented by Richard Angus from Enhance ALM).

    Topics include:

    • The benefits of migrating to TFS
    • A demonstration of the key features of TFS
    • Pre-migration planning
    • Hands-on walk through of the migration process
    • Verifying our migration and troubleshooting common issues

    Dates and locations

    Date Location Registration Link
    11 April (2 sessions) Melbourne Register
    12 April (2 sessions) Sydney Register
    13 April (2 sessions) Brisbane Register
    21 April Online Live Meeting Register
  • Andrew Coates ::: MSFT

    TFS for VSS Users - 1/2 day training in Sydney

    • 0 Comments

    I got this note from Sarah Webb at Readify today - looks like a good way to spend half a day if you’re looking to move from Visual Source Safe to a more modern source control system (and get a heap of additional goodness thrown in)

    Readify Dev Day:

    TFS for VSS Users…

    Since 2005, Team Foundation Server (TFS) has been providing integrated version control, work management and build capabilities. The release of TFS 2010 builds on the foundations formed in the earlier 2005 and 2008 products and focuses on lowering the barrier of entry for teams wanting to get the maximum benefit from TFS with minimal implementation fuss.

    Come along to this half day RDN Dev Day event to learn what is involved in getting TFS up and running in your development team. Presented by Readify Senior Consultant and Visual Studio ALM MVP, Stephen Godbold.

    TOPICS COVERED

    During this session, Stephen will be covering:

    • What you need to know to deploy and utilise the basic functions of TFS including how to implement version control, build and work management.
    • The roadmap of what greater deployment/integration will bring, along with the business value this delivers.
    • A look at the migration path from Visual Source Safe to Team Foundation Server.

    EVENT DETAILS

    Date: Friday 29 April 2011

    Location: Cliftons | 190 George Street, SYDNEY

    Duration: Half Day (including light refreshments)

    Times: AM Session: 9am – 12pm OR PM Session: 2pm – 5pm

    For more information, and to register, go to the Readify site.

  • Andrew Coates ::: MSFT

    Visual Studio 2010/.NET 4 Training Kit Updated

    • 0 Comments

    I’ve been raving about our great Training Kits for a while now (including last week’s post on the updated LightSwitch Training Kit).

    Last week we also released the March 2011 version of the Visual Studio 2010 and .NET Framework 4 Training Kit and Training Course.

    The Visual Studio 2010 and .NET Framework 4 Training Course includes videos and hands-on-labs designed to help you learn how to utilize the Visual Studio 2010 features and a variety of framework technologies including: C# 4.0, Visual Basic 10, F#, ASP.NET 4, Parallel computing, WCF, Windows Workflow, WPF, Silverlight and Windows Azure. The kit now contains 50 labs, 22 demos, 16 presentations and 12 videos.

    Link to VS2010 Training Course

    New content in this release includes:

    • Silverlight 4:
      • Hands-on Lab - Migrating a Windows Forms Application to Silverlight
      • Hands-on Lab - Migrating an ASP.NET Web Forms Application to Silverlight
      • Hands-on Lab - Working with Panels, XAML and Controls
      • Hands-on Lab - Silverlight Data Binding
      • Hands-on Lab - Migrating Existing Applications to Out-of-Browser
      • Hands-on Lab - Great UX with Blend
      • Hands-on Lab - Web Services and Silverlight
      • Hands-on Lab - Using WCF RIA Services
      • Hands-on Lab - Deep Dive into Out of Browser
      • Hands-on Lab - Using the MVVM Pattern in Silverlight Applications
    • Windows Azure:
      • Hands-on Lab – Introduction to Windows Azure
      • Hands-on Lab – Debugging Applications in Windows Azure
      • Demo Script – Hello Windows Azure
      • Demo Script – Deploying Windows Azure Services
      • Presentation – Windows Azure Platform Overview
      • Video – What is Windows Azure?

    All content has been tested to work with Visual Studio 2010 SP1. The setup scripts for all hands-on labs and demo scripts have also been updated so that the content can easily be used on a machine running Windows 7 SP1.

    You can download the March 2011 release of the Visual Studio 2010 and .NET Framework 4 Training Kit from here: http://bit.ly/auOAzR. We’re also continuing to publish the hands-on labs directly to MSDN to make it easier for developers to review and use the content without having to download an entire training kit package.  You can browse to all of the HOLs here:- http://msdn.microsoft.com/en-us/VS2010TrainingCourse.

    Finally, if you’re using the training kit or if you have feedback on the content, the team would love to hear from you.   Please drop them an email at vskitfdbk@microsoft.com

  • Andrew Coates ::: MSFT

    AlphaJax Wins Onya Award

    • 0 Comments

    Hi, my name’s Andrew and I’m an AlphaJax Addict. It’s been 15 minutes since I last played and that’s only because I’m waiting for my 15 opponents to get of their lazy backsides and have their turn.

    On the upside, AlphaJax has led to this comment from my anti-smartphone wife:

    Wow, this isn’t nearly as bad as I thought it would be!

    I just spotted Nigel Parker’s update to his “Road to 100 Apps” post announcing that AlphaJax had won the 2011 ONYAS award.

    AlphaJax - Windows Phone 7 Word Game

    If you have a Windows Phone 7 and you haven’t played AlphaJax, do yourself a favour and download it now.

Page 6 of 47 (470 items) «45678»