5 Comments

Background

Even if your Windows Phone 7 app doesn’t require any features from the new OS and even if it runs just fine in Windows Phone 8 phones, there’s a clear benefit from creating a separate WP8 version of the app: The WP8 compiled version of the app will play nicely with phones using 720p resolution (for example HTC 8X).

To illustrate, here’s a WP7 app running on a 720p Windows Phone 8 device:

image

Here’s the same app, this time updated to WP8:

image

As you can see, the WP7 version doesn’t use the full screen. As a result, the app (especially with a colorful background) looks ugly because of the black bar.

Options

There’s many articles on how developers can use a separate project for every platform. The basic idea is:

  1. Open your Windows Phone 7 app solution
  2. Create a new WP8 project into the solution
  3. Use Visual Studio’s “Add As Link” feature to copy all the files from the original WP7 project to the new WP8 project.

This works but it adds some complexity: If you add a new file to the WP7 project, you must remember to add it also to the WP8 project.

Instead of the method described above, we’ve had good success with a solution where we create a new “startup” project for the app. The benefits from this method is that once it has been set-up, you can continue working on the main project(s). If you add a new page, you don’t have to link it anywhere. Your app’s actual code isn’t linked between the projects.

Startup Project

The idea with the startup project is to have a project with a minimum amount of code which must be kept in sync between the WP7 and the WP8 versions.The startup project only has a single page and the user actually never sees it. As soon as the user hits the page, she is automatically navigated to the actual start page of your application, which resides in a completely different project (the main project of the app).

With the startup project, the application has the following structure:

The Main project:The original project which contains the actual application, all the pages etc. Can be multiple projects too, not limited to a single project.

The Startup project: A simple startup project which automatically redirects the user to the Main Project.

Example

Given a simple Windows Phone 7 app:

image

1. Add a new startup project

image

image

image

2. Add reference from Startup project to MainProject.

3. Modify the new project’s MainPage

We don’t want the user to see the MainPage.xaml from the startup project. Instead, the user should see the MainProject’s MainPage.xaml as the first page. In order to accomplish this, modify the startup project’s page to include automatic navigation to the main project:

namespace AppStartup.wp7
{
    public partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/MainProject;component/MainPage.xaml", UriKind.Relative));
        }
    }
}

4. Remove the startup project’s page from the navigation stack

User is now automatically taken to the main project’s page. But the back button doesn’t work correctly. To fix this, the startup project’s page must be removed from the navigation stack. This can be done on the main project’s page:

namespace MainProject
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (e.NavigationMode == NavigationMode.New)
                NavigationService.RemoveBackEntry();
        }
    }
}

5. Add a new startup project for the Windows Phone 8 version

The WP7 version is ready so we just need a project for the WP8 version:

image

image

image

6. Link the files between projects

Remove Assets, Resources, App.xaml, LocalizedString.cs and MainPage.xaml from the WP8 version, leaving it blank. Or leave the Assets folder if you don’t want to play with the app’s icons:

image

Select all the files and folders from Wp7 project, press CTRL+SHIFT and drag the files to the Wp8-project. This will automatically add the files as links:

image

7. Fix the app’s icons from the WMAppManifest.xml

If you deleted the Assets folder, you’re most likely going to see an error stating that app’s icons couldn’t be found:

image

To solve this, open WMAppManifest.xaml and point the icons to correct files.

8. Solve the other issues

Now there’s just two small things to do. First, open the WP8’s startup project and set the “Startup object”:

image

Then, add a reference from the WP8 startup project to the MainProject.

That’s it.You can now start the WP8 version of the app. Even though the MainProject is a WP7 assembly, the page is shown in full size:

image

The benefit from this is that once you’ve done the setup, you can continue editing the MainProject. There’s no MainProject.wp8 or MainProject.wp7, all the new pages will automatically work on both of the versions. And it’s likely that you never have to touch the startup projects once you’ve configured them once.

Just remember to submit the Startup.wp7.xap and the Startup.wp8.xap, not the main project.

Source code

An example solution can be found from GitHub (directory wp7-wp8-Startup-project).

3 Comments

After my TechDays’ presentation I was asked why we prefer to use Azure Virtual Machines for our web site hosting instead of Azure Web Roles. Here’s a little more structured answer to that question.

Our requirements

Let’s start by going through our requirements for the web site hosting platform. The main things we hope to have are:

  • Ease of deployment
  • Support for running ASP.NET and Node.js sites
  • Support for custom certificates

The problem with Azure Web Sites

Even though the original question didn’t touch Azure Web Sites, I thought about covering that option too. The Azure Web Sites is a great platform but it has a one big glaring problem, making it unsuitable for the production usage: The lack of support for custom certificates.

Other than that, Azure Web Sites offer really fast and easy deployment options and also the Node.js is supported.

Almost there with Azure Web Roles

The Azure Web Roles provide the support for custom certificates and for Node.js, making it ready for production usage. But the platform lacks in the ease of deployment. By default, updating a site is slow and it’s hard to run multiple applications in the same Web Role. The last bit is especially true if one wants to run both Node.js and ASP.NET apps on the same role.

The Azure Web Role platform pushes the developer into the “one app, one service” direction. This causes problems when you have limited resources (money).

Flexibility with Azure Virtual Machines

If you want to combine the Azure Web Site''s’ ease of deployment with Azure Web Roles’ readiness for production usage, the Azure Virtual Machines offer a good solution. Even though it takes some time to set things up, there’s plenty of good documentation available. We’ve setup our web servers using the following tools:

  • DFSR to keep the web servers in sync
  • IIS configured to use “shared configuration” and “Centralized Certificate Store”.
  • Web Deploy enabled on one of the servers (provides the options to “Push” web sites from Visual Studio)
  • IISNode for running Node.js
  • FTP-deploy for static sites and Node.js apps
  • Load Balancing is handled by Azure’s built-in load balancer

Summary

Here’s our requirements and the hosting options collected into a single table.

Feature / PlatformAzure Web SitesAzure Web RolesAzure Virtual Machines
Ease of DeploymentXX
Node.jsXXX
Custom certificatesXX

Other options:

Windows Azure Accelerator for Web Roles

Windows Azure Accelerator for Web Roles deals with the deployment problem of the platform. Unfortunately, the original project is now deprecated. Fortunately, robdmoore’s fork of the project is been actively developed.

The Azure Web Sites Private edition

The tools for running a private Azure Web Sites platform are available from the Web Platform Installer (Windows Azure / Service Management…). It seems that these tools support custom certificates. More info about this solution is available through the Microsoft.com/hosting.

1 Comments

TechDays 2013 is held in Helsinki next week, between the 5th and 6th of March. I’m giving a “Lessons Learned” style presentation there on the Azure track. The presentation contains information about the following subjects:

  • Cloud from the startup’s perspective: Where and how to maximize the usage of slower and cheaper CPU cycles
  • Building for scalability
  • Table Storage: Optimizing for the performance
  • Using Node.js and MongoDB in a modern Azure app
  • etc

Overall the presentation will focus on our lessons learned from building the Wensus.com app analytics service. What has worked, what hasn’t. What would we do differently if we had to start now.

The presentation is in Finnish. Also, during the TechDays, you can find me from the Microsoft’s “BizSpark lounge”  where we have our own stand.

1 Comments

I’ve been processing a lot of messages through Azure Service Bus lately. During that processing I encountered a situation where Azure Management Portal reported that there were over 97 thousand messages in the queue but still the worker weren’t receiving any messages.

image

Turns out the Management Portal also reports messages in the Dead Letter Queue. Some of the messages had failed the processing few times so they had been automatically moved to the Dead Letter Queue.

Here’s a code snippet for creating a QueueClient for the DLQ, from a previously created QueueClient:

var client = QueueClient.CreateFromConnectionString(conn, queue);
...

if (deadLetter)
{
var dfQueue = QueueClient.FormatDeadLetterPath(client.Path);
var dfClient = QueueClient.CreateFromConnectionString(conn, dfQueue);
}

2 Comments

I’ve been working with an app which has both the Windows Phone 7.5 and the Windows Phone 8 versions. Both of these versions have their own project files which target the correct platform but they reference and use a background agent compiled as a 7.5 project. The problem: Background agent was working on the 8.0 version, but the 7.5 threw a System.InvalidOperationException when it tried to start the agent. Here’s the stack trace:

And here’s the agent:

image

The application correctly referenced the project and the WMAppManifest.xml contained the agent:

      <ExtendedTask Name="BackgroundTask">
        <BackgroundServiceAgent Specifier="ScheduledTaskAgent" Name="scheduled-agent-wp7" Source="scheduled-agent-wp7" Type="scheduled-agent-wp7.ScheduledAgent" />
      </ExtendedTask>

So what was the problem? The XML.

When you add a reference to the agent, it automatically creates the XML into the WMAppManifest.xml. But in this case, it generated the wrong XML.If you check screenshot of the code, you can see that the agent’s class is scheduled_agent_wp7.ScheduledAgent. But the generated XML tries to reference a class scheduled-agent-wp7.ScheduledAgent.

Manually fixing the WMAppManifest.xml helped to solve the issue.