Tag: crash

Windows Phone: Don’t write to the InstalledLocation Folder

Crashes that occur not during development, but only after the application is installed by the Windows Phone store are among the most difficult to troubleshoot. This is one of those bugs.

Windows Phone 8 expanded the file storage APIs to include the StorageFile class support for parity with Windows 8. This class gives you access to ‘special folders’ including the folder where the application is installed. You can get to this folder as follows:

Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;

During development you can read and write from this folder, however after installing from the Windows Phone store, any write attempts to this folder will result in a file exception being thrown. Again, this bug will not occur if the app is sideloaded, only when the app is installed from the store. Most likely this is a security precaution to prevent any tampering with the installed files. 

This type of scenario, makes a strong argument for using the beta testing feature of Dev Center that allows you to test the store presentation and installation experience of your app to a specific list of users. By looking at the Dev Center generated crash logs (yes these are generated for beta apps as well as production), you can find the cause of the crash. 

Instead if using the InstalledLocation, you can read and write to the Local Folder. See here for more information.

Thanks,

Mike

Windows Phone: Don’t call LaunchForTest in Release

Calling ScheduledActionService.LaunchForTest is great for forcing a background task to run. This is important when you are developing and you need to debug your background agent. You may even want to call this in response to user action. You should not do this. The main reason is in Windows Phone 8 calling LaunchForTest, will throw an InvalidOperation exception. You may say that, ‘this works on my machine’, and you’d be right. This is because this exception is thrown only if the application is installed via the Windows Phone store. This does not occur if you sideload the app. Fortunately most of these scenarios are caught during certification testing. However, the Windows Phone certification team will report to you that that app crashes immediately after installation – without much more explanation. You will have a frustrating experience trying to reproduce this bug.

This type of scenario, makes a strong argument for using the beta testing feature of Dev Center that allows you to test the store presentation and installation experience of your app. In fact, by looking at the Dev Center generated crash logs, we found the cause of this crash. 

Frame

Image

Function

Offset

0

coredll.dll

xxx_RaiseException

19

1

mscoree3_7.dll

WatsonUnhandledManagedException

296

2

mscoree3_7.dll

Dbg_NotifyManagedException

93

3

mscoree3_7.dll

FirstPassException

1044

4

 

TransitionStub

0

5

 

Microsoft.Phone.Scheduler.SystemNotificationInterop.CheckHr

600

6

 

Microsoft.Phone.Scheduler.SystemNotificationInterop.LaunchNotification

128

7

 

Microsoft.Phone.Scheduler.ScheduledActionService.LaunchForTest

368

8

 

BritCo.App.Register_BackGroundAgent_ForLiveTile

240

9

 

BritCo.App..ctor

124

10

mscoree3_7.dll

IL_CallManaged

884

11

mscoree3_7.dll

BCL_System_Reflection_Invoke

1371

12

mscoree3_7.dll

BCL_System_Reflection_RTMI_Invoke

167

13

mscoree3_7.dll

BCL_System_Reflection_RTCI_Invoke

107

14

 

System.Reflection.RuntimeConstructorInfo.InternalInvoke

104

15

 

System.Reflection.RuntimeConstructorInfo.InternalInvoke

1240

16

 

System.Reflection.ConstructorInfo.Invoke

104

17

 

.__c__DisplayClass30._GetCreateObjectDelegate_b__2a

92

18

 

MS.Internal.TypeProxy.CreateInstance

100

19

 

MS.Internal.FrameworkCallbacks.CreateKnownObject

512

It turns our that the Windows Phone team added this exception to prevent the explicit launching of background agents in store deployed apps.  Why? Doing this can cause excessive battery drain and goes against the design of background agents.

Another common reason for wanting to call this API is that you may have code in the background agent you want explicitly triggered by user action. See Shawn Wildermuth’s blog post Confusion Around WP7.1 Periodic Agents for a discussion of this issue and how to code for it.

Thanks,

Mike

The Starbucks Wi-Fi Login Scenario: Why does this crash?

University of Arizona Starbucks

Developer Scenario: You have written your app to make sure there is a network connection prior to downloading data and populating the app. You have thoroughly tested you app at work with wired internet, in your car with 2, 3, 4 and no G (no connection) cellular connections. You also diligently tested your app with your home Wi-Fi and it works GREAT! You publish your app to the marketplace and find you are getting a few bad reviews (app is crashing). In reviewing your analytics, you see that these crashes are occurring when connected to Wi-Fi. You take your app to your favorite internet café and notice that the Windows Phone navigates to the web browser after connecting to the Wi-Fi access point. Wondering what will happen if you do NOT agree to the ‘terms-of-service’ you fire up your app and BOOM it crashes! 🙁 You start your debugger and find that your app is in fact downloading data, but instead of being in XML format:

<?xml version="1.0" encoding="utf-8"?>
<breakfast_menu>
  <food>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
  </food>
</breakfast_menu>

its in the form of:

<!DOCTYPE html>
<html class=" " lang="en-US">
  <head>
    <title>Starbucks Coffee Company</title>
. . .
Your app proceeds to deserialize the incoming data and quickly crashes since it is not in the expected format.

Detecting and Mitigating this scenario

The best way to protect against this scenario, is to validate the data. You don’t need to validate the entire response stream, just enough to know that its XML (or JSON, or whatever) and NOT HTML. You can the very quickly check a very small portion of the returned data to determine if the data you are receiving is the expected data. You can also validate against a response header. Here are the two methods (assume you are downloading xml):

        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

        {

            string res = e.Result.ToString(); // make sure returned data is not Café’s login page.

            if (res.Contains("<?xml"))

                result = "Connected!";

            else

                result = "Not Connected!";

        }

 

        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

        {

            var t = (sender as WebClient).ResponseHeaders[HttpRequestHeader.ContentType];

 

            if (res.Contains("text/xml")) // make sure returned data is xml and not Café’s (html) login page.

                result = "Connected!";

            else

                result = "Not Connected!";

 

            }

        }

Thanks,

Mike