How to get a non-Zero parent-window value in a Native Message host application?

453 views
Skip to first unread message

Eric Lawrence

unread,
Feb 10, 2022, 2:49:52 PM2/10/22
to Chromium Extensions
Chrome only passes a non-Zero --parent-window value to the Native Message host if the host was created on a chrome-extension page. If the host was created by a background script in the extension, the value is 0.

Is there any recommended approach to work around this? The only workaround I presently see is pretty hacky ("Get the current tab's title and pass that to the app, and have the app do a FindWindowEx call").

thanks for any pointers!

wOxxOm

unread,
Feb 11, 2022, 10:48:03 AM2/11/22
to Chromium Extensions, eri...@microsoft.com
Apparently there's no proper solution.

When using the title hack, the only(?) problem I see is that there may be several matching windows in the system, which is rare but possible, especially for a new tab (NTP).

A more reliable workaround may be to use a low-level system API in your host app to get the PID of chrome process that launched your host app. There may be intermediate processes like cmd.exe or py.exe or node.exe, so you'll walk upwards until you find chrome. Then you enumerate its visible windows (in WINAPI it's probably EnumThreadWindows).

hrg...@gmail.com

unread,
Feb 11, 2022, 11:21:40 AM2/11/22
to Chromium Extensions, wOxxOm, eri...@microsoft.com
Also don't forget that users can set a custom name for a browser window via the "Name window..." option. If this is the case, then the active tab title will be useless.

To make things even more difficult, all Chrome windows are created by the same process, even if those windows belong to different browser profiles. So, enumerating the windows of that process will give you literally all Chrome windows currently open.

wOxxOm

unread,
Feb 11, 2022, 12:06:31 PM2/11/22
to Chromium Extensions, hrg...@gmail.com, wOxxOm, eri...@microsoft.com
> all Chrome windows are created by the same process, even if those windows belong to different browser profiles

Pretty bad, indeed, but at least in Windows OS it's possible to find the window's profile by reading its associated app model id. The id looks like Chrome.UserData.Profile7 in non-primary profiles.

Eric Lawrence

unread,
Feb 11, 2022, 1:16:02 PM2/11/22
to Chromium Extensions, wOxxOm, hrg...@gmail.com, Eric Lawrence
From the Chrome side, is there a fix we/I should make for this scenario? E.g. if there's no |native_view| passed into NativeProcessLauncher::CreateDefault, should we just try to use some heuristic to identify the most likely window handle (e.g. the handle of the Chrome window that had the most recent user gesture)? 

Or perhaps the window.tabs API should be able to return an identifier that is visible externally (e.g. either the HWND, or something exposed via UIA Accessibility APIs or the like), such that the extension can send that ID after the native host is spawned?

Eric Lawrence

unread,
Feb 11, 2022, 1:22:59 PM2/11/22
to Chromium Extensions, Eric Lawrence, wOxxOm, hrg...@gmail.com
I guess perhaps one additional approach would be to have the extension use the chrome.windows API to find the location and dimensions of the window containing the tab for which the background script is doing work, and use that as a further filter into which HWNDs are candidates. While less direct than getting an explicit HWND off of a window object, it could narrow the possibility of guessing the wrong window.

Simeon Vincent

unread,
Feb 12, 2022, 1:14:58 AM2/12/22
to Eric Lawrence, Chromium Extensions, wOxxOm, hrg...@gmail.com
IMO it's worth opening a new issue on crbug.com to discuss the challenges the current behavior poses for extension developers. The issue referenced in the StackOverflow link Eric mentioned in the original post (crbug.com/354597) was closed in 2015; seven years seems like enough time to revisit that decision. 

Simeon - @dotproto
Chrome Extensions DevRel


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/f026c5cb-9033-4a23-9676-f175872d2714n%40chromium.org.

hrg...@gmail.com

unread,
Feb 12, 2022, 5:33:49 AM2/12/22
to Chromium Extensions, Simeon Vincent, Chromium Extensions, wOxxOm, hrg...@gmail.com, eri...@microsoft.com
I kind of agree with the decision to close crbug.com/354597 because the extensions API should be independent from the operating system internal details.
It makes much more sense to me to solve the problem in the opposite way, i.e. to expose Chrome's window IDs to the native host via some interface that the underlying OS already has.
For example, the Accesibility API is more or less standard across OSs. All windows have an Accessibility object with several properties. Two of those properties are "Name" and "Value". The name is the window title and the value is always null in the case of Chrome.
This "value" property could contain Chrome's window ID.
Alternatively, an new property could be added to the object, called "chromeID" or something.

If the Accesibility API is deemed is too "heavy" or difficult to use, there are other OS interfaces such the GetProp and SetProp functions in the Win32 API, which could also be a good way to expose Chrome's windows ID natively.

Eric Lawrence

unread,
Feb 14, 2022, 4:50:26 PM2/14/22
to Chromium Extensions, hrg...@gmail.com, Simeon Vincent, Chromium Extensions, wOxxOm, Eric Lawrence
Thanks, Simeon; I've filed https://crbug.com/1297287 to track consideration of this use-case.

While I recognize the desire to split the extension API's view of the world from that of the host OS, the entire point of Native Messaging is to provide a bridge between the two worlds. Presently, that bridge includes the native window handle getting passed on the command line, but that doesn't always work.

Perhaps the simplest approach would be to enhance the chrome.runtime.connectNative and sendNativeMessage APIs with an optional second (connectNative) / fourth parameter (sendNativeMessage), the window object which should be used for calculation of the --parent-window HWND? This seems like it should be a pretty small code change, would not expose window handles into extension-land, and would mean that we don't need to change the contract for how the Native Host behaves.
Reply all
Reply to author
Forward
0 new messages