Repository: nvaccess/nvda

Issue:
Windows Store apps: use app title as product name instead of wwahost
**Reported by nvdakor on 2014-07-07 13:10**
Hi,
Currently, when invoking appModule.productName for a Windows Store app, NVDA says "Windows operating system". Although this is fine for built-in apps such as Bing Weather and Windows Store, this may confuse users and developers when they are testing accessibility of Store apps (both existing ones and apps to be created in the future). As a way of providing actual product name for debugging purposes and for people to tell us which app they are having issues with, I propose using app title for productName.
Before:
1. Go to Windows Store app such as Weather.
2. Once the app opens, press NVDA+F1 to show developer info. Look under appModule.productName.
After:
1. Open any Windows Store app.
2. Press NVDA+F1 to open developer info. appModule.productName tells you the title of the app.
Implementation:
1. In appModules.wwahost.py, override _get_productName to return the title (api.getForegroundObject().name).
2. wwahost.AppModule.productName will contain the actual title of the app.
Thanks.

**Blocked by #4569**

Load specific app modules for apps hosted by wwahost.exe
**Reported by jteh on 2014-10-23 07:35**
wwahost.exe hosts many Windows Store apps (though it seems some do have their own executables). To allow for application specific customisation, we should identify the specific application in the app module name.

I think we can use GetApplicationUserModelId (in kernel32) for this purpose. This includes a "!" character, so we'll need to check whether Python will cope with this and replace if not.
**Blocked by #4360**
**Blocking #4259**



Discussion:
Comment 1 by jteh on 2014-07-08 04:19
Are you certain that the foreground title of these apps can never change? What if the app opens a dialog or other secondary main window? This certainly changes the title for desktop apps, but perhaps it doesn't for Store apps. We'd need to be very certain of this before considering using the foreground title.

Comment 2 by nvdakor on 2014-07-08 06:01
Hi,
Some examples of apps which pops up a dialog include Skype, People and so forth when launched from local user account. However, when I press Alt+Tab to switch between programs, the name of the program with the pop-up dialog is announced before NVDA presents the pop-up dialog.
One way to get around this would be looking up GUID (global unique identifier) for each app in the app store, but the big issue is what if the user is not connected to the Internet.
Thanks.

Comment 3 by jteh on 2014-07-08 06:33
When one of these dialogs open, what does NVDA+t report: the app name or the dialog name?

Comment 4 by nvdakor on 2014-07-08 06:38
Hi,
The dialog I've seen reports the name of the dialog in question. I should add that these dialogs (user account ones) uses a different executable name (useraccountbroker.exe); I still need to find an app that opens its own pop-up dialog with the executable name of wwahost.exe so we canverify that the title is indded the name of the app in question.
Thanks.

Comment 5 by jteh on 2014-10-23 07:41
We'll need to access the app package info, which will require some of the code for #4569.

cc @josephsl
Hi, hopefully we should do something about it, as there are folks still using Windows 8.x and they might encounter hoste3d apps. Thanks.

 

From: Leonard de Ruijter [mailto:notifications@github.com] 
Sent: Friday, February 9, 2018 10:41 AM
To: nvaccess/nvda <nvda@noreply.github.com>
Cc: Joseph Lee <joseph.lee22590@gmail.com>; Mention <mention@noreply.github.com>
Subject: Re: [nvaccess/nvda] Windows Store apps: use app title as product name instead of wwahost (#4259)

 

cc @josephsl <https://github.com/josephsl> 

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <https://github.com/nvaccess/nvda/issues/4259#issuecomment-364520844> , or mute the thread <https://github.com/notifications/unsubscribe-auth/AHgLkAuEb6RyKnk66ENfr10VE8asH0Dmks5tTJFDgaJpZM4SAW78> .


@josephsl, @michaelDCurran, @jcsteh any update on this issue? I think the priority for Windows 8 store apps is quite low. in favour o0f Windows 10. Right?
Is this issue occuring also on Windows 10?
Hi,

Not by much, as most apps do come with their own executables (including converted desktop apps). I'm leaving this open in case we can find a solution for wwahost issue. Thanks.
Hi,

And I found one: kernel32::GetPackageFullName. This function returns a serialized representation of an app package info, including name, version, architecture, and family. Each part is separated by an underscore, which makes it easy to parse this (index 0 is publisher.name, index 1 is version).

I'll come up with a pull request in the next few hours.

Thanks.
Comment 1 by jteh on 2014-10-23 07:36
[GetApplicationUserModelId in MSDN](http://msdn.microsoft.com/en-us/library/windows/desktop/hh920917%28v=vs.85%29.aspx)

Comment 4 by nvdakor on 2015-01-02 09:46
Hi,
Looking at how to work on this...
It turns out wwahost.exe is similar to javaw - uses command-line arguments to decide which app to host. If you try the following in Python Console (after obtaining the PID for the app in question):

```
import appModuleHandler
x = appModuleHandler.getWmiProcessInfo(PID)x.CommandLine
```

The argument of interest is:

``````
-ServerName:appName.wwa```
For apps such as Calendar, a unique name will be shown, with some showing app.wwa (such as Bing Weather). However, wwa names can change, so it's not quite reliable, but at least getting the wwa name via command-line is possible (for those who don't know, there exists a ticket that requests locating names of apps hosted by wwahost); if I can figure out how to read buffer in Python, I'll do some research on the application model function and getting the package info (if it works, should this be added to winKernel?).
For OS, I put Windows 8, as wwahost (and WinRT in general) is available on Windows 8 and higher (including 8.1). Thanks.
``````

Comment 5 by nvdakor on 2015-01-02 10:41
Hi Jamie,
At least on Cygwin, when I attempt to import a module with exclamation point in the middle of the name, I get a syntax error. Also, GetApplicationUserModelId does return the name of the app when I test this against Bing News, Weather, Mail and others.
Since the function itself returns a buffer and might be used in many Windows Store apps, should this be part of winKernel? If so, I'm willing to create a branch that adds this function (by the way, OpenProcess is defined twice in winKernel).
Thanks.

Comment 6 by jteh (in reply to comment 5) on 2015-01-06 07:41
Replying to [nvdakor](comment:5):

> At least on Cygwin, when I attempt to import a module with exclamation point in the middle of the name, I get a syntax error.

What about when you do it via `__import__` (which is how NVDA does it for app modules)?

> Since the function itself returns a buffer and might be used in many Windows Store apps, should this be part of winKernel?

I'd probably just call it directly in the wwahost app module, as I don't think we'll need to call it elsewhere.

cc @josephsl
Hi,

This issue mainly affects Windows 8.x, as Windows 10 do come with apps which have their own executables. Note that appPath property from another pull request might help out if needed.

Thanks.
Hi,

Import test: test fails - files with an exclamation mark in the middle of the name isn't imported.

I'd go for command line version (see the example code fragment above), as it can be passed onto app module handler string replacement patch. I'll send a pull request soon.

Thanks.
Hi,

An unexpected case showed up on Windows 10: The Twitter PWA (progressive web app) that is hosted inside WWAHost.exe. If PWA's are hosted inside wwahost, then this boosts priority of this issue, as more PWA's may show up on Microsoft Store.

Thanks.
Hi,

Actually, GetApplicationUserModelId is way faster than command line method, validating @JcSTeh's hunch.

Thanks.

Resolving patch:
diff --git a/source/appModules/wwahost.py b/source/appModules/wwahost.py
--- a/source/appModules/wwahost.py
+++ b/source/appModules/wwahost.py
@@ -1,26 +1,40 @@
-#A part of NonVisual Desktop Access (NVDA)
-#This file is covered by the GNU General Public License.
-#See the file COPYING for more details.
-#Copyright (C) 2012 NV Access Limited
+# A part of NonVisual Desktop Access (NVDA)
+# This file is covered by the GNU General Public License.
+# See the file COPYING for more details.
+# Copyright (C) 2012-2020 NV Access Limited, Joseph Lee
 
-from comtypes import COMError
-import IAccessibleHandler
-from NVDAObjects.IAccessible.MSHTML import Body
+"""App module host for Windows 8.x and 10 apps hosted by wwahost.exe.
+In Windows 8, apps written in Javascript are executed inside WWAHost, including some WinRT apps.
+In Windows 10, progressive web apps (PWA) and friends are hosted inside this process.
+App modules wishing to support apps hosted inside this process must subclass the AppModule class.
+"""
+
+import ctypes
 import appModuleHandler
-import controlTypes
-import winUser
+import winKernel
+
+
+def getAppNameFromHost(processId):
+	# Some apps that come with Windows 8 and 8.1 are hosted by wwahost.exe.
+	# App modules for these are named after the hosted app name.
+	processHandle = winKernel.openProcess(
+		winKernel.SYNCHRONIZE | winKernel.PROCESS_QUERY_INFORMATION, False, processId
+	)
+	length = ctypes.c_uint()
+	winKernel.kernel32.GetApplicationUserModelId(processHandle, ctypes.byref(length), None)
+	appModel = ctypes.create_unicode_buffer(length.value)
+	winKernel.kernel32.GetApplicationUserModelId(processHandle, ctypes.byref(length), appModel)
+	winKernel.closeHandle(processHandle)
+	# Sometimes app model might be empty, so raise errors and fall back to wwahost.
+	if not appModel.value:
+		raise LookupError
+	# App model is shown as familyName!appName,
+	# and importing files with the exclamation point in the middle of the name isn't supported.
+	# Therefore return only the app name portion.
+	# Convert this into lowercase to make the file name consistent with other NVDA app modules.
+	return appModel.value.split("!")[-1].lower()
 
 class AppModule(appModuleHandler.AppModule):
 
-	def event_NVDAObject_init(self,obj):
-		#The root document of HTML Metro Apps must be treeted as an application. 
-		if isinstance(obj,Body) and obj.windowClassName=="Internet Explorer_Server":
-			try:
-				paccParent=obj.IAccessibleObject.accParent.accParent
-				identity=IAccessibleHandler.getIAccIdentity(paccParent,0)
-			except (COMError,AttributeError):
-				identity=None
-			if identity:
-				windowHandle=identity.get('windowHandle')
-				if windowHandle and winUser.getClassName(windowHandle)=="Web Platform Embedding":
-					obj.role=controlTypes.ROLE_APPLICATION
+	# WWAHost app content is treated as part of an app, not a browse mode document.
+	disableBrowseModeByDefault = True


Test patch: