Some windows store apps crash when they are launched by ActivateApplication

I’m heard from the developers that some windows store
applications downloaded from Windows store may crash when they are launched by IApplicationActivationManager::ActivateApplication API. Bubble Birds 1.0 is such a sample. Sometimes it shows black screen when it’s launched by this API and then report following exception:


 

ActivateApplication is used to activate the specified Windows Store app for the generic launch contract (Windows.Launch) in the current session. Generally we use this API to do automation test. The code is like that:

int _tmain(int argc, _TCHAR* argv[])

{

       LPCWSTR appId = L"<Use your app id>";

       CoInitialize(NULL);

       IApplicationActivationManager* paam = NULL;

       HRESULT hr = S_OK;

       hr = CoCreateInstance(CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&paam));

       if (SUCCEEDED(hr))

       {

              hr =CoAllowSetForegroundWindow(paam, NULL);

              if (SUCCEEDED(hr))

              {

                     DWORD pid = 0;

                     hr =paam->ActivateApplication(appId, nullptr, AO_NONE, &pid);

              }

       }

       CoUninitialize();

       return hr;

}

This API works well when the widows store application is first launched. But if there is an instance in the memory with Suspended state, re-launching the application using ActivateApplication can cause above exception. That’s because the behavior of calling ActivateApplication to launching the application is actually different from clicking the application tile in the start screen.

When the use clicks the application tile to launch the store application which is in Suspended state, it will resume from the memory directly without calling OnLaunched function. But if the user uses ActivateApplication API to active the application and the application is in in Suspended state, it’s resumed and OnLaunched function will still be called. If the windows store application doesn’t expect it and do some special code logic here, it may raise unexpected problem. For Bubble Birds case, it causes black screen and succeeding exception.  I don’t own the source code of Bubble Birds. But from the reflection of binary, it looks like that the application didn’t set the visibility of the Main page correctly which cause the black screen. And the exception is caused by the share violation of the file “datastore.dat”. The event handler Current_VisibilityChanged is invoked twice. In Current_VisibilityChanged function, it saves the configuration to datastore.dat as following.

private async void Current_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
{

    if (!e.get_Visible())
    {
        if (App._TheGame != null)
        {
            App._TheGame.Paused= true;
        }
        await this.SaveDataAsync();
    }
}

public async Task SaveDataAsync()
{
    StorageFolder localFolder = ApplicationData.get_Current().get_LocalFolder();
    StorageFile storageFile = await localFolder.CreateFileAsync("datastore.dat", 1);
    await FileIO.WriteTextAsync(storageFile, JsonConvert.SerializeObject(App._TheGame.Serialize()));
    storageFile = await localFolder.CreateFileAsync("scoreboard.dat", 1);
    await FileIO.WriteTextAsync(storageFile, JsonConvert.SerializeObject(App._Scoreboard));
    ApplicationDataContainer localSettings =ApplicationData.get_Current().get_LocalSettings();
    localSettings.get_Values()["GameSettings"] = JsonConvert.SerializeObject(App._TheSettings);
}

If this function is called concurrently, the latter calling can raise ShareViolation error because the file handle is exclusively held by the former calling. This can be confirmed from the process monitor log:

11:54:55.9410468 AM  XIMAD.BubbleBirds8.exe     7016   CreateFile   C:\Users\hanxia\AppData\Local\Packages\XIMADINC.BubbleBirds_np8fj6akx2czy\LocalState\datastore.dat       SUCCESS       Desired Access: Generic Read/Write, Disposition: Open, Options: Non-Directory File, Disallow Exclusive, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened

11:54:55.9416659 AM  XIMAD.BubbleBirds8.exe     7016   CreateFile   C:\Users\hanxia\AppData\Local\Packages\XIMADINC.BubbleBirds_np8fj6akx2czy\LocalState\datastore.dat       SHARING VIOLATION    Desired Access: Generic Read/Write, Disposition: Open, Options: Non-Directory File, Disallow Exclusive, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a

11:54:55.9426178 AM  XIMAD.BubbleBirds8.exe     7016   CloseFile   C:\Users\hanxia\AppData\Local\Packages\XIMADINC.BubbleBirds_np8fj6akx2czy\LocalState\datastore.dat       SUCCESS      

So far we don’t provide any API to just resume an application. The only workaround is that you should make sure that there isn’t any windows store application instance before you want to use ActivateApplication to launch it.