Thursday, November 1, 2012

WACK ARM

If you are developing Windows 8 Store apps you should really test those on low-powered x86 and ARM devices. The difference to your high-end x64 developer machine can be dramatically, esp. if you use a non-default design.
Testing on ARM is important and Tim Heuer wrote a nice post which shows how to remotely deploy, debug and profile on ARM devices right from Visual Studio 2012. Another nice thing which performs a couple of automated tests is the Windows App Certification Kit (WACK). Unfortunately is the WACK tool for ARM hidden inside the Windows 8 SDK, but here's how to find it:

  1. Download the Windows 8 SDK web setup from here and run it.
  2. Choose to download the SDK files for offline usage.
  3. On the "Select the features you want to download" screen it's enough if you only select the "Windows App Certification Kit" checkbox.
  4. After the download is finished, you will find an "Installers" subfolder in the download target folder.
  5. Copy the "Windows App Certification Kit arm-arm_en-us.msi" from the "Installers" folder to an USB key or SkyDrive.
  6. Open the "Windows App Certification Kit arm-arm_en-us.msi" on your ARM device and install the WACK on it. 
  7. Search for "Windows App Cert Kit" on your ARM device using the Search Charm and run the WACK.

Tuesday, October 30, 2012

Faster! - WriteableBitmapEx for Windows Phone 8 and WinRT Updated

The Windows Phone 8 SDK is now available and with that WriteableBitmapEx was updated too. The performance of the WinRT XAML version was also improved dramatically and an update is highly recommended.
WriteableBitmapEx is available for 4 platforms: Windows Phone 8 and 7, WPF, Silverlight and Windows Store WinRT .NET XAML.
You can download the binaries here or via the NuGet packageThe packages contain the WriteableBitmapEx binaries. As usual all samples and the source code can be found in the repository.

Sunday, October 28, 2012

Know Your Users - Windows 8 Store App System Info

This is just a quick a post to provide a little class for Windows 8 Store app development. The SystemInformation class gathers some useful information about the current system and can dump those as a string. I usually have such a class for all the platforms I work on and it's very helpful for logging and error analysis, but it also serves as a list of all available system information which are scattered in different APIs. The info can also be used to dynamically adapt the app, etc.

Here's the code I have so far, you can also download the complete class here.

public static async Task Dump(bool shouldDumpCompleteDeviceInfos = false)
{
   var builder = new StringBuilder();
   var packageId = Windows.ApplicationModel.Package.Current.Id;
   var clientDeviceInformation = new EasClientDeviceInformation();
    
   // Get hardware Id
   var token = HardwareIdentification.GetPackageSpecificToken(null);
   var stream = token.Id.AsStream();
   string hardwareId;
   using (var reader = new BinaryReader(stream))
   {
      var bytes = reader.ReadBytes((int)stream.Length);
      hardwareId = BitConverter.ToString(bytes);
   }

   builder.AppendLine("***** System Infos *****");
   builder.AppendLine();
#if DEBUG
   builder.AppendLine("DEBUG");
   builder.AppendLine();
#endif
   builder.AppendFormat("Time: {0}", DateTime.Now.ToUniversalTime().ToString("r"));
   builder.AppendLine();
   builder.AppendFormat("App Name: {0}", packageId.Name);
   builder.AppendLine();
   builder.AppendFormat("App Version: {0}.{1}.{2}.{3}", packageId.Version.Major, packageId.Version.Minor, packageId.Version.Build, packageId.Version.Revision);
   builder.AppendLine();
   builder.AppendFormat("App Publisher: {0}", packageId.Publisher);
   builder.AppendLine();
   builder.AppendFormat("Supported Package Architecture: {0}", packageId.Architecture);
   builder.AppendLine();
   builder.AppendFormat("Installed Location: {0}", Windows.ApplicationModel.Package.Current.InstalledLocation.Path);
   builder.AppendLine();
   builder.AppendFormat("Store App Id: {0}", CurrentApp.AppId);
   builder.AppendLine();
   if (CurrentApp.LicenseInformation.IsActive)
   {
      var listingInformation = await CurrentApp.LoadListingInformationAsync();
      builder.AppendFormat("Store Current Market: {0}", listingInformation.CurrentMarket);
      builder.AppendLine();
   }
   builder.AppendFormat("Culture: {0}", CultureInfo.CurrentCulture);
   builder.AppendLine();
   builder.AppendFormat("OS: {0}", clientDeviceInformation.OperatingSystem);
   builder.AppendLine(); 
   builder.AppendFormat("System Manufacturer: {0}", clientDeviceInformation.SystemManufacturer);
   builder.AppendLine();
   builder.AppendFormat("System Product Name: {0}", clientDeviceInformation.SystemProductName);
   builder.AppendLine();
   builder.AppendFormat("System Sku: {0}", clientDeviceInformation.SystemSku);
   builder.AppendLine();
   builder.AppendFormat("System Name: {0}", clientDeviceInformation.FriendlyName);
   builder.AppendLine();
   builder.AppendFormat("System ID: {0}", clientDeviceInformation.Id);
   builder.AppendLine();
   builder.AppendFormat("Hardware ID: {0}", hardwareId);
   builder.AppendLine();
   builder.AppendFormat("User Display Name: {0}", await UserInformation.GetDisplayNameAsync());
   builder.AppendLine();
   builder.AppendFormat("Window Bounds w x h: {0} x {1}", Window.Current.Bounds.Width, Window.Current.Bounds.Height);
   builder.AppendLine();
   builder.AppendFormat("Current Orientation: {0}", DisplayProperties.CurrentOrientation);
   builder.AppendLine();
   builder.AppendFormat("Native Orientation: {0}", DisplayProperties.NativeOrientation);
   builder.AppendLine();
   builder.AppendFormat("Logical DPI: {0}", DisplayProperties.LogicalDpi);
   builder.AppendLine();
   builder.AppendFormat("Resolution Scale: {0}", DisplayProperties.ResolutionScale);
   builder.AppendLine();
   builder.AppendFormat("Is Stereo Enabled: {0}", DisplayProperties.StereoEnabled);
   builder.AppendLine();
   builder.AppendFormat("Supports Keyboard: {0}", IsKeyboardPresent());
   builder.AppendLine();
   builder.AppendFormat("Supports Mouse: {0}", IsMousePresent());
   builder.AppendLine();
   builder.AppendFormat("Supports Touch (contacts): {0} ({1})", IsTouchPresent(), new TouchCapabilities().Contacts);
   builder.AppendLine();
   builder.AppendFormat("Is Network Available: {0}", NetworkInterface.GetIsNetworkAvailable());
   builder.AppendLine();
   builder.AppendFormat("Is Internet Connection Available: {0}", NetworkInformation.GetInternetConnectionProfile() != null);
   builder.AppendLine();
   builder.AppendFormat("Network Host Names: ");
   foreach (var hostName in NetworkInformation.GetHostNames())
   {
      builder.AppendFormat("{0} ({1}), ", hostName.DisplayName, hostName.Type);
   }
   builder.AppendLine();
   builder.AppendFormat("Current Memory Usage: {0:f3} MB", GC.GetTotalMemory(false) / 1024f / 1024f);
   builder.AppendLine();
   builder.AppendFormat("App Temp  Folder: {0}", ApplicationData.Current.TemporaryFolder.Path);
   builder.AppendLine();
   builder.AppendFormat("App Local Folder: {0}", ApplicationData.Current.LocalFolder.Path);
   builder.AppendLine();
   builder.AppendFormat("App Roam  Folder: {0}", ApplicationData.Current.RoamingFolder.Path);
   builder.AppendLine();
   builder.AppendLine();

   if (shouldDumpCompleteDeviceInfos)
   {
      var devInfos = await DeviceInformation.FindAllAsync();
      builder.AppendLine();
      builder.AppendLine("Complete Device Infos:");
      foreach (var devInfo in devInfos)
      {
         builder.AppendFormat("Name: {0} Id: {1} - Properties: ", devInfo.Name, devInfo.Id);
         foreach (var pair in devInfo.Properties)
         {
            builder.AppendFormat("{0} = {1}, ", pair.Key, pair.Value);
         }
         builder.AppendLine();
      }
   }

   return builder.ToString();
}

public static bool IsTouchPresent()
{
 return new TouchCapabilities().TouchPresent == 1;
}

public static bool IsMousePresent()
{
 return new MouseCapabilities().MousePresent == 1;
}

public static bool IsKeyboardPresent()
{
 return new KeyboardCapabilities().KeyboardPresent == 1;
}


On my system it provides the following info (anonymized):
***** System Infos *****

DEBUG

Time: Sun, 28 Oct 2012 07:51:11 GMT
App Name: MyApp
App Version: 1.0.0.5
App Publisher: CN=A8E2F0B1-4749-48AE-AE18-C7FFB5B30272
Supported Package Architecture: Neutral
Installed Location: D:\Development\MyApp\bin\Debug\AppX
Store App Id: 00000000-0000-0000-0000-000000000000
Culture: en-US
OS: WINDOWS
System Manufacturer: Dell Inc.
System Product Name: Precision M6600
System Sku: 
System Name: MYLAPTOP
System ID: 18a2e8c6-cc7d-8546-1e9e-56a12ffb32fd
Hardware ID: 03-00-D2-41-03-00-AA-72-08-00-EF-AD-05-AA-B6-4F-06-00-01-01-04-00-31-1B-04-00-0C-48-04-00-D2-55-04-00-D3-66-01-00-0E-D6-02-00-E4-7F-09-00-56-47
User Display Name: Rene Schulte
Window Bounds w x h: 1920 x 1080
Current Orientation: Landscape
Native Orientation: Landscape
Logical DPI: 96
Resolution Scale: Scale100Percent
Is Stereo Enabled: False
Supports Keyboard: True
Supports Mouse: True
Supports Touch (contacts): False (0)
Is Network Available: True
Is Internet Connection Available: True
Network Host Names: mylaptop (DomainName), mylaptop.local (DomainName), 169.254.85.85 (Ipv4), 192.168.2.148 (Ipv4), 
Current Memory Usage: 0.451 MB
App Temp  Folder: C:\Users\Rene\AppData\Local\Packages\MyApp\TempState
App Local Folder: C:\Users\Rene\AppData\Local\Packages\MyApp\LocalState
App Roam  Folder: C:\Users\Rene\AppData\Local\Packages\MyApp\RoamingState

If you know more system information Windows 8 APIs that listing is missing, please add a comment.

Wednesday, August 29, 2012

Update WriteableBitmapEx for WinRT RTM, WPF, Windows Phone and Silverlight


The RTM version of Windows 8 is now available and with that WriteableBitmapEx was updated too. WriteableBitmapEx is now available for 4 platforms: WPF, Silverlight, Silverlight for Windows Phone and Windows Store Style WinRT .NET.
You can download the binaries here or via the NuGet packageThe packages contain the WriteableBitmapEx binaries. As usual all samples and the source code can be found in the repository.



Since the last WinRT release preview version, a couple of bugs were fixed and a new FromStrean method was added which loads an image stream into a WriteableBitmap. The project was also updated for the Windows 8 RTM version. Please read this blog post for more details about the WinRT version.

Tuesday, June 19, 2012

Moving on

Today was my last day at Schleupen AG. I worked there for 5 years as an enterprise developer mainly on back end and algorithmic topics, but also on the front end with .NET, Silverlight and more. We developed some really nice things there and I'm esp. proud of the parallel data processing pipeline which even works with .NET 2.
My co-workers were a great bunch of people, some became my friends and even the godfather of my youngest daughter and I became a godfather too. I thank them all for what I've learned and the great time we had. I wish them nothing less than the best for their future.

I started at Schleupen AG right after my studies and my diploma thesis "Parallelization and Optimization of an OpenGL CAD / CAM Application". I was always a computer graphics aficionado and passionate about physical simulation, image processing, computer vision, real-time computer graphics in general and interactive UIs with a great UX. Just for fun I started to work on some side projects, like this open source OpenGL fluid simulation in 2007, created a few open source libraries and also developed quite popular  Windows Phone apps such as Pictures Lab, Funny Faces, Helium Voice, Cloud Recorder and more. 

It's an exciting time to be a developer with so much things happening in this industry at the moment. Microsoft's own Surface tablets is just one piece we as software developers can leverage to shape the future. For me it's good fun to use these great new technologies like Windows Phone, Windows 8, WinRT, .NET, DirectX, XBox, Kinect, etc. to create nice experiences and I love to work on this all the time.
few months ago I got an offer from IdentityMine and if you know their work, you can imagine that it was a no-brainer to accept this nice offer they made meI'm really looking forward to work with state of the art technologies on exciting projects with experts like Laurent Bugnion and more great people. Another nice aspect of my new gig: I will work from my home office and will be closer to my 3 lovely daughters and wife. I will also be here during the last phase of my wife's pregnancy and can hopefully support her better. And yes, we're expecting our fourth child in September. :-)


Now I will enjoy a couple of days off with my family until I start my new job as Senior Interactive Developer at IdentityMine on July 2nd.