It started with an annoying day for Logitech updates:

I installed GHub a while back because it was the new upgrade from Logitech Gaming Software, but had found it just didn't work as well as the old software. My main bugbear was that the button on the bottom of the mouse, which typically switches between profiles, wasn't bindable in the app, despite what their manual says:

These arrow buttons (that flip the mouse so you can bind the bottom buttons) don't appear for my G903

This meant I could only switch between my "desktop" and "gaming" profiles by opening the app and clicking around, which is too slow for something done so regularly. So, I'd ended up sticking with the onboard profiles, retained on the device from the previous software. Not ideal, but functional, and the profile-switch button worked.

Then this morning came a firmware update and, when I installed it, the onboard profiles were lost. My mouse was back to factory settings, and I had no way to reinstate the bindings so my button worked! I was about to reinstall LGS, but decided to have a poke first.

The SysInternals ProcMon tool helped me find the file that contains my profile. It's only written to when the app window closes, and it's written to by a different process (lghub_agent) but I found it in the end! It's a json file, and it lives here: C:\Users\<user>\AppData\Local\LGHUB\settings.json

Hurrah for ProcMon!

Inside that file, all the button bindings are clearly visible in an array under profiles[x].assignments, and have a consistent form:

{
    "cardId": "0f82f693-5b78-4cf5-867e-080100000000",
    "slotId": "g900_g4_m1"
}

slotId refers to the physical button, but what's cardId? I could find no reference to map this value to a function. Then, back in the app, I noticed this:

In onboard mode, pressing the button on the base of the mouse still switches profiles. Could this be why?

I pasted settings.json into one side of a BeyondCompare text compare, then bound one of the available buttons (G4) to "Onboard Profile Cycle", and compared the updated settings.json. The g900_g4_m1 entry was updated in the file, and it was the same cardId as the g900_g12 button entries. Looked like I was in business: the bottom button is "G12" and the bindings are in the config file!

From here it's pretty straightfoward: I bound the thumb button to the "G Hub Profile Cycle" and noted the new cardId from the updated settings file: 0f82f693-5b78-4cf5-867e-080100000000. This is the one I needed!

I shut down GHub completely so I could hand-edit the settings, and replaced all g900_g12 button bindings with the new guid (there's a prompt in the GHub app that suggests the button has to be bound in all profiles for some reason). Restarting the software I found that, finally, my underside button switches profiles on my mouse again!

... and it only took an hour to work it all out. If this comes up again, or for anyone else, hopefully this post will save some time!

UPDATE: Logitech replied to my tweet and, and apparently this isn't supposed to work. It seems they're as confused as anyone...