Archive for the ‘Tips’ Category.

Running the Windows Azure Tools & SDK on the Windows Developer Preview

Now that we can get our hands on the Windows Developer Preview of Windows 8, I’m sure everyone is excited to start building applications! For many of us, this means that we’ll want to install all of the great Windows Azure tools on our Windows Developer Preview machine – especially if we plan to take advantage of the new Windows Azure Toolkit for Windows 8. However, there are a few things we’ll need to do in order to get things to work.

Quickly let me explain the three challenges you’ll run into:

  1. The current Windows Azure Tools for Visual Studio do not yet support Dev11 – you’ll have to install Visual Studio 2010.
  2. There are a few quirks getting dependencies for IIS installed on Windows 8 using the Web Platform Installer.
  3. After Visual Studio 2010 and the Windows Azure Tools for Visual Studio are installed on a machine with Dev11, the Windows Azure tools will grab an environmental path variable that points to 11.0 instead of 10.0.

Fortunately, these things are pretty easy to resolve and will certainly get addressed in later builds.

Here’s what you’ll have to do to get the tools and SDK working with the Windows Developer Preview:

  1. Install Microsoft .NET Framework 3.5.1. Easiest way is to type “Windows Features”, select Settings, and select Turn Windows features on or off. Then simply check the checkbox. Click OK to install.
    Step 1 - .NET 3.5.1
  2. Next we need to correctly configure IIS. Typically we’d do this through the Web Platform Installer, but this doesn’t work correctly on Windows 8. From Turn Windows features on or off you’ll need to do the following, then click OK to install.
    • Check Internet Information Services.
    • Expand Internet Information Services and World Wide Web Services.
    • Expand Application Development Features and check ASP.NET 2.0, ASP.NET 4.5, and CGI.
    • Expand Common HTTP Features and check HTTP Redirection.
    • Expand Health and Diagnostics and check Logging Tools, Request Monitor, and Tracing.
  3. Install the Web Platform Installer (WebPI).
  4. Install Visual Web Developer 2010 Express through WebPI. (You can use a different version of Visual Studio 2010, so long as it’s supported by the Windows Azure Tools for Visual Studio.)
  5. Install Windows Azure Tools for Microsoft Visual Studio 2010 – September 2011 through WebPI.

Okay, now you have everything installed. However, before you trying running Visual Studio, you have to create a script to launch Visual Studio 2010. This is because the Windows Azure tools use an environmental variable that’s incorrectly pointing to version 11.0, and we’ll need to change it right before we launch to version 10.0 (for Visual Studio 2010).

@ECHO OFF

SET VisualStudioVersion=10.0

SET VisualStudioPath="%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE"
IF NOT EXIST %WINDIR%\SysWow64 SET VisualStudioPath="%ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE"

CD /D %VisualStudioPath%

VWDExpress.exe

As you can see, the script changes the VisualStudioVersion to 10.0 then launches Visual Web Developer Express (there’s a little extra code to set the path correctly regardless of 32- or 64-bit versions of Windows).

Save the above script as a CMD file (i.e. OpenVisualStudio2010.cmd) and then make sure to right-click and Run as administrator! If you forget to run the script as administrator then Visual Studio won’t have the permissions needed to run the Windows Azure tools correctly.

Running Instance

Look, it’s working!

NOTE: I found myself having to reboot Windows 8 in order to resolve a problem where the debugger wouldn’t attach. Not sure if this occurs every time, but in case you have a similar issue just try rebooting.

I hope this helps!

Using the Expression Encoder SDK to encode lots of videos

I spent a good deal of time this weekend importing hours and hours family videos off our Mini DV cassettes.  Lots of fun, and LOTS of video!  Based on the size of these files, I was quite close to running out of room on my Windows Media Center.  So, I decided to encode the files as WMVs.  Huge size reduction with very little quality loss.

I decided to use Microsoft Expression Encoder 3 – a great tool.  The best part is that there’s an SDK and set of assemblies that you can use in your own applications.

Note: if you are using a 64-bit machine, be sure to set the platform target of your application to x86, or else you will get compilation errors from the Encoder assemblies.

Below you’ll find the application I wrote.  Let me explain my goals:

  • Multi-thread the application to encode more than one video at a time.
  • Leverage the multitude of cores in my machine.
  • Limit the number of threads (I chose the core count as a baseline).
  • Use source video and audio source to reduce quality lose.

In order to do this, I had to do two things: 1) find a way to pass in the file name into thread, and 2) keep track of the number of threads and limit them to the number of cores in the machine.

I spent a bit of time looking for a good approach.  In the end, I chose to use the delegate ParameterizedThreadStart, which takes a parameter of type object.  This way, I can create a thread using an instance of this delegate instead of just ThreadStart, and the overload to Thread.Start allows me to specify a value that is passed to this new thread.  (Be careful, though, as it only accepts a single parameter (although it can be a collection) and isn’t type-safe.)  Additionally, with this approach I was able to leverage a counter, and sleep whenever the counter is going to exceed the number of cores in my machine.

Here’s all the code.  For this to function, I imported the following assemblies (yes, you need Expression Encoder 3):

  • Microsoft.Expression.Encoder
  • Microsoft.Expression.Encoder.Types
  • Microsoft.Expression.Encoder.Utilities
  • WindowsBase
// This method is used to look-up the core the thread is using
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentProcessorNumber();
 
static string inputFolder = @"C:tempVideos";
static string outputFolder = @"C:tempOutputVideo";
static int count;
static int maxNum;
 
static void Main(string[] args)
{
    // Start the counter at zero
    count = 0;
    // Grab the processor count
    maxNum = Environment.ProcessorCount;
    // Iterate through the AVI files
    foreach (var fileName in System.IO.Directory.GetFiles(inputFolder, "*.avi"))
    {
        // Sleep/wait for a core to free up
        while (count > (maxNum - 1))
        {
            Thread.Sleep(500);
        }
        // Increment the counter
        count++;
        // Create the thread with the delegate
        Thread t = new Thread(new ParameterizedThreadStart(EncodeFile));
        // Start the thread, passing in the file name
        t.Start(fileName);
    }
}
 
public static void EncodeFile(object ofileName)
{
    string fileName = (string)ofileName;
    MediaItem mediaItem = new MediaItem(fileName);
    mediaItem.OutputFormat = new WindowsMediaOutputFormat();
    // Use source video profile if available
    if (mediaItem.SourceVideoProfile != null)
    {
        mediaItem.OutputFormat.VideoProfile = mediaItem.SourceVideoProfile;
    }
    else
    {
        mediaItem.OutputFormat.VideoProfile = new AdvancedVC1VideoProfile()
        {
            Size = mediaItem.MainMediaFile.VideoStreams[0].VideoSize,
            Bitrate = new ConstantBitrate(1000)
        };
    }
    // Use source audio profile if available
    if (mediaItem.SourceAudioProfile != null)
    {
        mediaItem.OutputFormat.AudioProfile = mediaItem.SourceAudioProfile;
    }
    else
    {
        mediaItem.OutputFormat.AudioProfile = new WmaAudioProfile();
    }
    // Create a job and the media item for the video we wish to encode.
    Job job = new Job();
    job.MediaItems.Add(mediaItem);
    // Set up the progress callback function
    job.EncodeProgress
        += new EventHandler<EncodeProgressEventArgs>(OnProgress);
    // Set up the completed callback function
    job.EncodeCompleted
        += new EventHandler<EncodeCompletedEventArgs>(job_EncodeCompleted);
    // Set the output directory and encode
    job.OutputDirectory = outputFolder;
    // Do not create a job subfolder
    job.CreateSubfolder = false;
    // Encode
    job.Encode();
}
 
static void job_EncodeCompleted(object sender, EncodeCompletedEventArgs e)
{
    // Decrement the counter
    count--;
}
 
static void OnProgress(object sender, EncodeProgressEventArgs e)
{
    // Write out information
    Console.WriteLine(
        count.ToString() + " : " +
        GetCurrentProcessorNumber().ToString() + " : " +
        System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " : " +
        e.Progress + " : " +
        e.CurrentItem.ActualOutputFileName);
}

 

Good stuff.

I’m running it from the console, so you will have to make some modifications if you want it to run in a more sophisticated application.  Works for me, though – I just start it up at the end of the day.  Here you can see the information that’s written out to the console (note the variety of cores leveraged):

Console Output

It’s fun to see my machine working this hard.  Every core is pegged.

Pegged Cores

Hope someone finds this useful.  Anyone see a better way to approach this?

Jon Box on the Capabilities of Internet Explorer 8

At MIX10, Jon Box – a Senior Architect Evangelist with Microsoft – spoke with SocialWendy about Internet Explorer 8.  In addition to highlighting the fact that IE8 makes the Internet easier, safer, and faster, Jon talks about three unique capabilities found in IE8:

Furthermore, Jon highlighted how a web slice allows a user to subscribe to a piece of content on a web page, and also explain how a user can leverage an accelerator – such as Walmart’s accelerator – to make it easier to search for information and goods on the Internet.

If you’d like more information on how to do this yourself for your own web pages, take a look at the following resources:

Also, if you want to take a look at some great web slices, try out the following:

Happy web slicing!