Introduction to the Live Framework

Technorati Tags: Mesh,Live Framework

So I have just come off of a project and I’ve got some bench time… and as there are so many wonderful things out there to play with I thought I have plenty of things to do.

Mesh and the Live Framework

First off I have downloaded the Live Framework SDK from Developer Live and also took a look at some of the walkthroughs.

Lots of them are for developing mesh applications, but some are to create a client application using the live framework.

After working through the project it appears extremely easy to use existing mesh objects (files/folders, devices, people etc.) as well as creating custom objects for the mesh (i.e. a “meshage board”… a meshed message board).

Firstly to create the class couldn’t be simpler – create a new class library and and references to

· Microsoft.LiveFX.Client.dll

· Microsoft.LiveFX.ResourceModel.dll

· Microsoft.Web.dll

provided in the sdk (default install at “C:\program files\Microsoft SDKs\Live Framework SDK\v0.9\Libraries\.Net Library")

next specify the using statements

 using Microsoft.LiveFX.Client;
using Microsoft.LiveFX.ResourceModel;

using System.Collections.ObjectModel;

Then create define the public static class which it will be called:

 public static class MeshageBoard

Now you’re set to start creating Mesh objects…

For example, one of the first things may be to create a Meshage board:

 public static MeshObject CreateMeshageBoard(LiveOperatingEnvironment env, string BoardTitle)
{
   MeshObject messageBoard = new MeshObject(BoardTitle);
   messageBoard.Resource.Type = "MeshageBoard";
   messageBoard.Resource.Title = BoardTitle;
   env.Mesh.MeshObjects.Add(ref messageBoard);
   DataFeed newDataFeed = new DataFeed();
   newDataFeed.Resource.Type = "MeshageBoard_DataFeed";
   messageBoard.DataFeeds.Add(ref newDataFeed);
   return messageBoard;
}

you will notice that this method takes a LiveOperatingEnvironment which it adds a this object to… This will be the Mesh environment for the user.

The walkthrough recommends that you create a Console Application which you can but you can equally create a WPF application or whatever you feel suits the needs of the project best.

Personally I created a Console Application for ease… and nothing says cool quite like white text on a black background :)

Again add references to the Live Framework dll’s in the live framework (see the walkthrough for some further detail) and add using statements for:

 using Microsoft.LiveFX;
using Microsoft.LiveFX.Client;

using Microsoft.LiveFX.ResourceModel;

using System.Net;

using Microsoft.Web;

using Microsoft.Web.Clients;
using System.IO;   
using System.Collections.ObjectModel;

And of course the Class Library Project which is going to do most of the leg work.

The tutorial suggests creating a resources file to put the Cloud URI, Address and AppId in (I found that it would be better not to put the address i.e. someone@hotmail.com in the resources file, so that you can ask the user for a user name… or not to hardcode the value) also don’t panic if you get to this stage without an AppId (I didn’t get one and the project doesn’t really need it unless it is published as a mesh application (i.e. application you can use from the live desktop), as this is going to be a client we can ignore this for now.

Now to programmatically connect to our mesh :)

Inside the program’s class (probably called Program) we need some members for the console specifically and the LiveOperatingEnvironment.

 System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int SetConsoleMode(IntPtr hConsoleHandle, int dwMode);

[System.Runtime.InteropServices.DllImport("kernel32")]

private static extern int GetConsoleMode(IntPtr hConsoleHandle, ref int dwMode);

private const int ENABLE_LINE_INPUT = 2;

private const int ENABLE_ECHO_INPUT = 4;

private const int CONIN = 3;
private static LiveOperatingEnvironment env;

Now for the Main method (unfortunately it uses some goto’s which some people may not like, but this is in the walkthrough so I’m going to leave this in for completion):

 static void Main(string[] args)
{
   Start:
   LiveItemAccessOptions miao = new LiveItemAccessOptions(true);
   try
   {
      string address = Resources.Address;
      string appId = Resources.AppId;
      Console.Write("Please enter your password:\r\n>");
      string password = GetPassword();
      Console.Clear();
      Console.WriteLine("Connecting to the Mesh...");
      foreach (string line in meshImage)
      {
         Console.WriteLine(line);
      }
      Uri cloudURL = new Uri(Resources.CloudURI);
      NetworkCredential creds = new NetworkCredential(address, password);
      env = new LiveOperatingEnvironment();
      env.Connect(creds);
      Console.Clear();
      Console.Write("You are now connected. \r\n");
   }
   catch (Exception ex)
   {
      Console.Clear();
      Console.WriteLine("Caught exception trying to connect: " + ex.Message);
      Console.WriteLine("Would you like to re-enter your password? (y/n)");
      string yesOrNo = Console.ReadLine();
      if (yesOrNo.ToLower() == "y")
         goto Start;
      else
      {
         Console.WriteLine("Press any key to exit");
         Console.Read();
         return;
      }
   }
   HandleUserInput();
}

Of course remembering the code snippit for static void Main in Visual Studio “svm” [tab] (I still don’t know how I coded for so long without some of these)

The above Main method also assumes that there is a resources which has the address in (easily taken out by replicating the “GetPassword” section, and not turning the characters into *’s.

The GetPassword I have updated to be a little better and allow backspaces (I know how many times I have been annoyed by typing in my password only to put 1 too many characters and not having the delete functionality)  I believe I have got this working over multiple lines but please let me know if you see a bug…

 private static string GetPassword()
{
   IntPtr hStdIn = new IntPtr(CONIN);
   int mode = 0;
   char inputChar;
   StringBuilder password = new StringBuilder();
   // Read a character at a time and do not echo input
   GetConsoleMode(hStdIn, ref mode);
   mode = (mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
   SetConsoleMode(hStdIn, mode);
   // Read the password a character at a time
   do
   {
      inputChar = (char)Console.Read();
      if (inputChar >= 32)
      {
         // Echo character with password mask
         password.Append(inputChar);
         Console.Write("*");
      }
      else
      {
         if (inputChar == '\b') // backspace
         {
            if (password.Length > 0)
            {
               password.Length--;
               if (Console.CursorLeft != 0)
               {
                  Console.CursorLeft--;
                  Console.Write(" ");
                  Console.CursorLeft--;
               }
               else
               {
                  Console.CursorLeft = Console.BufferWidth-1;
                  Console.CursorTop--;
                  Console.Write(" ");
                  Console.CursorLeft = Console.BufferWidth-1;
                  Console.CursorTop--;
               }
            }
         }
      }
   }while (inputChar != '\r');  // Enter pressed end of password.
   // Set console back to line input mode
   mode = (mode | (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
   SetConsoleMode(hStdIn, mode);
   return password.ToString();
}
// Provide a way to exit the program.

private static void GetOut()
{
   Console.WriteLine("Press any key to exit.");
   ConsoleKeyInfo cki = Console.ReadKey(true);
   if (cki != null)
      return;
}
 private static void HandleUserInput()
{
Input:
      Console.WriteLine("");
      Console.WriteLine("1: Create a New MeshageBoard.");
      Console.WriteLine("2: List All MeshageBoards.");
      Console.WriteLine("3: Make a Posting.");
      Console.WriteLine("4: List All Postings for a MeshageBoard.");
      Console.WriteLine("5: Invite Members to a MeshageBoard.");
      Console.WriteLine("6: Reset the demo.");
      Console.WriteLine("7: Remove a MeshageBoard");
      Console.WriteLine("8: Exit the program.");
      Console.Write(">");
      string input = Console.ReadLine();
      switch (input)
      {
         case "1":
            CreateNewMeshageBoard();
            break;
         case "2":
            ListAllMeshageBoards();
            break;
         case "3":
            //MakeAPosting();
            break;
         case "4":
            //PrintMessages();
            break;
         case "5":
            //InviteMembers();
            break;
         case "6":
            //ResetAll();
            break;
         case "7":
            RemoveMeshageBoard();
            break;
         case "8":
            return;
         default:
            Console.WriteLine("Please enter a valid value.");
            goto Input;
      }
}

and finally create the method to create a mesh board in our program (to call our class library)

 private static void CreateNewMeshageBoard()
{
   Start:
      Console.Write("Please enter the name for your MeshageBoard: ");
      string input = Console.ReadLine();
      MeshageBoard.CreateMeshageBoard(env, input);
      Console.Write("Would you like to create another? (y/n): ");
      string yesOrNo = Console.ReadLine();
      if (yesOrNo.ToLower() == "y")
         goto Start;
      else
         HandleUserInput(); ;
}

Now things should be all set to play around with the mesh.

(You may notice that some items are commented out, and if you are following the walkthrough I have added a Remove on option 7)

With the addition removal of the “List all Meshage Boards” and “Remove Meshage Boards” this will now work and you can create meshage boards!

To view these add the following method in the main program:

 private static void ListAllMeshageBoards()
{
   ObservableCollection<MeshObjectResource> meshBoardList = new ObservableCollection<MeshObjectResource>();
   meshBoardList = MeshageBoard.GetAllMeshageBoard(env);
   foreach (MeshObjectResource resource in meshBoardList)
   {
      Console.WriteLine(resource.Title);
   }
   HandleUserInput();
}

and in the class library the method:

 public static ObservableCollection<MeshObjectResource> GetAllMeshageBoard(LiveOperatingEnvironment env)
{
   if (!env.Mesh.MeshObjects.IsLoaded)
      env.Mesh.MeshObjects.Load();
   ObservableCollection<MeshObjectResource> listAllMeshBoard = new ObservableCollection<MeshObjectResource>();
   var meshObjects = from i in env.Mesh.MeshObjects.Entries
                 where String.Equals(i.Resource.Type, "MeshageBoard")
                 select i;
   foreach (MeshObject meshObject in meshObjects)
   {
      listAllMeshBoard.Add(meshObject.Resource);
   }
   return listAllMeshBoard;
}

Uncommenting the Case 2 option “ListAllMeshageBoards()” will allow you to list the meshage boards you have created.

Notice that these returns all entries and uses LINQ to query the Resource.Type of each mesh object entry to see if it is of the type we are looking for.

Next to remove a meshage board (doing a similar thing to listing all meshage boards…

in the main program:

 private static void RemoveMeshageBoard()
{
   Console.Write("Please enter the name of the MeshageBoard you wish to remove: ");
   string input = Console.ReadLine();
   MeshageBoard.RemoveMeshageBoard(env, input);
   HandleUserInput();
}

Finally in the class library:

 public static void RemoveMeshageBoard(LiveOperatingEnvironment env, string boardTitle)
{
   var meshObjects = from i in env.Mesh.MeshObjects.Entries
                 where String.Equals(i.Resource.Type, "MeshageBoard")
                 select i;
   foreach (MeshObject meshObject in meshObjects)
   {
      if (meshObject.Resource.Title == boardTitle)
      {
         Console.WriteLine("Remove Mesh Object: " + meshObject.Resource.Id + "? (y/n) ");
         string yesOrNo = Console.ReadLine();
         if (yesOrNo.ToLower() == "y")
         {
            env.Mesh.MeshObjects.Remove(meshObject);
            Console.WriteLine("Mesh Object " + meshObject.Resource.Title + " with ID: " + meshObject.Resource.Id + " removed.");
         }
      }
   }
}

Uncommenting option 7 “RemoveMeshageBoard()” in the HandleInput method will now allow you to remove a Meshage board.

It is my understanding that you may also dynamically add or remove devices from the mesh (not sure how it would work with the client) using the

 env.Mesh.Devices.Add

method where env is the LiveOperatingEnvironment and passing it a MeshDevice object.  Similar with News and Users, so there can be lots of fun with collaboration tool in the future possibly…

Well that’s a pretty long post and isn’t quite complete, so as I work through some more cool mesh stuff I’ll be sure to post it… There are some other things I have been working with for a future post.

Please let me know if you have anything to add/comments

(post back to original blog https://blogs.msdn.com/davethompson/)