Open Opened 12 years ago Updated 5 months ago

# Firefox only combines with pinned taskbar icon if taskbar icon is named "Mozilla Firefox"

4.0 Branch
x86
Windows 7
P5

UNCONFIRMED

## Attachments

### (1 file)

 33.27 KB, application/x-xpinstall Details
User-Agent:       Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Build Identifier: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0

Pretty much the summary,

Try pinning a shortcut named "Firefox 1" and then use it, firefox will partially seperate itself from the icon leaving the icon in the W7 taskbar AND adding a window of firefox.

Especially undesirable if like me, you use 3 instances of firefox. (2 of which run -no-remote -p profile1( and profile2 and profile3) but irritating even with a single instance...

Worked fine in Firefox 3.5(Possibly newer pre4.0, I forget exactly what I was updated to but I've been doing this since 3.0), a shortcut named "Mozilla Firefox 1" would stay bonded to the firefox instance it started if pinned.

Reproducible: Always

Steps to Reproduce:
1. Make shortcut named anything other than Mozilla Firefox that starts firefox
2. Drag to Windows 7 taskbar to pin.
3. left-click said pinned item, watch the wrongness
Actual Results:
Firefox starts, but creates a new taskbar item instead of replacing the pinned item, leaving a pinned item laying around.

Expected Results:
The pinned icon should have expanded into a window-taskbar item.

Running default theme. Happens even running a single instance, just is more irritating if running multiple.
I can't pin on my taskbar tow shortcuts with a different name as the only diference.

If I pin the default firefox shortcut and one containing the "-no-remote -p profile1" option, the "-no-remote -p profile1" shortcut, if opened, finally becomes only firefox.exe which is the other shortcut "default" one and it is recognized by the taskbar as that shortcut(default).

I personally think it is a windows problem not firefox
(In reply to comment #1)
> I can't pin on my taskbar tow shortcuts with a different name as the only
> diference.
>
>
> If I pin the default firefox shortcut and one containing the "-no-remote -p
> profile1" option, the "-no-remote -p profile1" shortcut, if opened, finally
> becomes only firefox.exe which is the other shortcut "default" one and it is
> recognized by the taskbar as that shortcut(default).
>
>
> I personally think it is a windows problem not firefox

Except earlier versions of firefox work fine in this regard as long as the names of the shortcuts are different. Besides, you don't even need a "-no-remote -p profile1" second instance to hit this bug. As I noted.
Gah. Comments really need editability.

I'm fairly certain whats happening is that Firefox 4 windows are not taking on the title of the shortcut that starts them. Prevous versions did this. W7 combines task-bar items in part based on this from what I can tell.
Shortcuts have an internal ID associated with them for the taskbar. Without that set on the shortcut you pin, grouping won't work. This is by design via win7. If you want to do this, copy a shortcut we create through the installer, rename it, and pin it. Grouping will work correctly.
Version: unspecified → 4.0 Branch
After updating 4.0 to 4.0.1, I pinned the original shortcut "Mozilla Firefox" to the taskbar. Now it is acting the same. After launching the pinned one, one more icon appears which is apparently the running one.

Now if I pin the running Firefox icon. I could see in %appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar, there are two items:

Firefox - this is the one which is running all the time (Modified date: the day I updated to 4.0.1)
Mozilla Firefox - this is the one I pinned earlier and which now merely acts a launcher (Modified date: the day I insntalled 4.0)

As a side note: If someone has already pinned the shortcut taskbar and then updates to 4.0.1. The Mozilla Firefox icon reappears in the "Start menu's Recent Programs List" which shouldn't happen if an item is pinned to taskbar.
https://bugzilla.mozilla.org/show_bug.cgi?id=653633
Summary: Firefox only combines with pinned taskbar icon if taskbar icon is named "Monzilla Firefox" → Firefox only combines with pinned taskbar icon if taskbar icon is named "Mozilla Firefox"
> Shortcuts have an internal ID associated with them for the taskbar. Without that set on the shortcut you pin, grouping won't work. This is by design via win7. If you want to do this, copy a shortcut we create through the installer, rename it, and pin it. Grouping will work correctly.

That's not my experience.

Using Chrome as an example.

I start it from some other mechanism.
While it is running, I right click and Pin it.
Subsequent chrome window now get stacked with the icon.
And it opens properly from the icon.
(In reply to Michael Kaply (mkaply) from comment #6)
> It's not on my taskbar.
> I start it from some other mechanism.
> While it is running, I right click and Pin it.
> Subsequent chrome window now get stacked with the icon.
> And it opens properly from the icon.

This should work just fine for any running instance of fx version 10+.

STR:

1) unpin all fx icons from the taskbar
2) launch an install
3) right click the fx taskbar icon and select pin

That icon will now launch that particular install.

If you have multiple installs, you can pin each and they will group individually.
So how do you get in a scenario where you have a pinned icon and when you click on it, it opens a different icon (see bug 729930).

I'm in that state right now and I don't want to mess with anything just in case there's something that can be debugged.
(In reply to Michael Kaply (mkaply) from comment #8)
> So how do you get in a scenario where you have a pinned icon and when you
> click on it, it opens a different icon (see bug 729930).
>
> I'm in that state right now and I don't want to mess with anything just in
> case there's something that can be debugged.

The shortcut you have pinned doesn't have the right id. I would suggest you just unpin that, launch fx, and repin the running instance.
> The shortcut you have pinned doesn't have the right id. I would suggest you just unpin that, launch fx, and repin the running instance.

So does each Firefox.exe have a unique ID?

How do upgrades work since the firefox.exe is a different EXE? Does it have to be removed and readded?
(In reply to Michael Kaply (mkaply) from comment #10)
> > The shortcut you have pinned doesn't have the right id. I would suggest you just unpin that, launch fx, and repin the running instance.
>
> So does each Firefox.exe have a unique ID?
>
> How do upgrades work since the firefox.exe is a different EXE? Does it have
> to be removed and readded?

Versions prior to 10 had ids that were based on the release version and the installer would update this id on each upgrade. In 10, we switched to a hash of the install directory for the id, which remains constant and never needs to be updated. We set this id on every install shortcut we create *except* the desktop shortcut the installer creates.
Bug 577867 encompassed the changes in 10.
Wow. No offence? But the pinning behavior in 10 is ~bad~. It worked, as far as I could tell, perfectly waaay back in 3.5 and I think up until 3.6. (Even if it may have been *implemented* wrong, it worked right...)

Pinning my active firefox run from a shortcut called "Firefox A" doesn't retain the run settings from "Firefox A" in this case -P "Firefox1" it instead runs  the default profile. This pin *does* combine with a running instance of firefox...
Directly dragging and pinning the "Firefox A" shortcut does succeed in pinning the shortcut itself, but does not combine with the running instance itself O.o...
More strange, I can pin the active instance. I can simultaneously pin my shortcut "Firefox A", but another shortcut called "Firefox B" with the settings -p "Firefox2" -no-remote cannot be pinned at the same time as "Firefox A".

These are both brand new shortcuts, made by going to the firefox.exe itself, right clicking, and selecting create shortcut(and, well, renaming and adding the settings to them of course.)

The better functional behavior was *way* back on Firefox 3.5, where Firefox A and Firefox B would both have pinned as "separate programs"(either by dragging the shortcut *or* telling it to pin the running task-bar object) and would combine with each of their respective pinnings. Firefox 4-10 (Not sure about 3.6-3.9ish, skipped right over them. I think 3.6 behaves the same as 3.5) behave horribly in this respect...

It sounds like that if I bother to make multiple separate Firefox installs my shortcuts *might* behave correctly now as of 10. I don't mind this too much, but that it was unnecessary in a previous version is... interesting. Backwards progress isn't exactly a great thing.
Just clarifying, on the first scenario I listed I ran the shortcut, then pinned by right clicking the running program on the taskbar. Somewhat clear if you pay attention to the second scenario but... yeah.

Summary:
The bug that multiple INSTALLS identify as the same? Sounds fixed, though I haven't confirmed. Nifty I suppose.

The bug that pinnings from active copies don't retain settings such as non-default profile? Meep, that's a new one I think... And kinda bad.

The bug that multiple differently configured shortcuts cannot be pinned and act in a logical and normal behavior? Still there. (But worked fine in 3.5...)
You can add command line parameters to pinned shortcuts by editing the shortcut file -

As for grouping by profile instead of install location, we added an option for that in Bug 577867. Add a boolean pref named |taskbar.grouping.useprofile| and set it to true.
(In reply to Jim Mathies [:jimm] from comment #15)
> You can add command line parameters to pinned shortcuts by editing the
> shortcut file -
>
Hmmm. I had tried that once and it caused it to unpin, though retrying it it seems to work ok for the most part.
> As for grouping by profile instead of install location, we added an option
> for that in Bug 577867. Add a boolean pref named
> |taskbar.grouping.useprofile| and set it to true.
Well that's nice to know. It'd still make more sense for it to do so by BOTH profile and install location.
But again. Good to know. Only problem with that is knowing that said exists... Well ;P yeah.

Appreciating the warmer welcome than when I first reported problems in 4.0 tho! Suppose ya guys are more used to the super-wonkyness of pinning in W7 now :P

It's still bad that pinning the wrong way causes it to not remember the options it was run with. I know it remembered said in 3.5, but if plus or minus a setting that's all that is left of this bug really. Progress!
Having tried the aforementioned |taskbar.grouping.useprofile| theres one notable caviat. To actually make it work one has to pin the RUNNING copies of firefox... and THEN go to C:\Users\username\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar and edit them to have the appopriate -p profile and -no-remote which. Is rather counter-intuitive.

Still not up to par with Firefox 3.5's behavior where shortcuts could be pinned outright, retained their settings, and bunched accordingly(all on their own!).
Especially since in 3.5, each pin retained the shortcuts name. I can't see any simple way to rename them given this... roundabout solution.

An improvement though! Certainly!
AH! Apparently they'll... somewhat update names if renamed in the userpinned taskbar folder apon restart/relog to the bar. Though some odd behaviors there. But those are more... *windows* bugs I suspect. Not your deal.

Still. Getting back the intuitive and logical behavior of 3.5 would be nice. It seems to be slowly returning.
Update on this bug. Using Win7: I created a shortcut to firefox.exe and gave it command line options -P unn -no-remote because I want it to launch my profile straight away. I also changed the icon.So it does this. And I pinned it. However if its pinned, all the windows open in a seperate group. Its weird. See image please: http://img.photobucket.com/albums/v135/noitidart/bugzilla20showing20the20separate20l_zps8dd5419d.png
Good luck man, far more major features have been disregarded lately. This little quirk... is unlikely to be fixed.
Ever.
Ironically worked perfectly, under what I ascertain to be the "incorrect" implementation.... (3.5 and earlier)
(In reply to Jim Mathies [:jimm] from comment #15)
> You can add command line parameters to pinned shortcuts by editing the
> shortcut file -
>
>
> As for grouping by profile instead of install location, we added an option
> for that in Bug 577867. Add a boolean pref named
> |taskbar.grouping.useprofile| and set it to true.

I went to about:config created "taskbar.grouping.useprofile" and set it to true. I use WinXP, will it seperate the instances by profile? It doesn't seem to be working.
btw i set that preference in all my firefox profiles
Setting the pref taskbar.grouping.userprofile in all profiles and restarting all browsers of profiles it works in Win7. HOWEVER if firefox.exe was pinned before i started creating that pref that that pinned one always sits there and all profile windows will never be in it. The proflie marked as Default=1 in profiles.ini should not use a different defaultGroupId (Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar).defaultGroupId), this would fix the issue.
I'm asking for help on how to get defaultGroupId of the firefox.exe before the pref is set from a profile which has the pref set: http://stackoverflow.com/questions/24102520/get-defaultgroupid-of-firefox-exe-win7
Also a curious thing:
"For win8 metro builds, we can't set this. The value is static"

I hope that in Win8 that profiles are seperate, I can't test Win8, does anyone know if setting this param to true will make the profile windows be grouped seperately (like mac os)?
(In reply to noitidart from comment #25)
> Also a curious thing:
> cpp#245
> "For win8 metro builds, we can't set this. The value is static"
>
> I hope that in Win8 that profiles are seperate, I can't test Win8, does
> anyone know if setting this param to true will make the profile windows be
> grouped seperately (like mac os)?

I don't think that applies - we are no longer working on a "metro" build for windows 8.
Ah cool ok thanks man!
It looks like no one is going to take this. So Ill take it and deploy it via addon.

Its hardcore js-ctypes so os dependent. I don't know C or C++ and have been bugging a guy on stackoverflow but I feel like I'm annoying him.

I got all the ground work done, as in I got the C code, i even converted it all to ctypes to the best i can which is pretty dang buggy. Is there anyone that can help me out with the c to ctypes conversion, basically they just have to look at my js-ctypes conversion and fix that please.

Anyone available?
Btw if anyone wants to actually fix this in the firefox codebase you would set the RelaunchCommand property: http://blogs.msdn.com/b/oldnewthing/archive/2011/06/01/10170113.aspx

Im doing that via js-ctypes and need help.
(In reply to noitidart from comment #21)
> true. I use WinXP, will it seperate the instances by profile? It doesn't
> seem to be working.

Taskbar grouping relies on Win7 operating system features to work, WinXP will ignore this stuff. Sorry :/

(In reply to noitidart from comment #25)
> Also a curious thing:
> cpp#245
> "For win8 metro builds, we can't set this. The value is static"
>
> I hope that in Win8 that profiles are seperate, I can't test Win8, does
> anyone know if setting this param to true will make the profile windows be
> grouped seperately (like mac os)?

Win8 should work just like Win7 when you're running the desktop app.

Note though the profile chooser window is created early in startup before the profile opens and will rely on Windows default behavior for grouping. Testing locally the profile chooser groups with my default shortcut, which seems right to me.

(In reply to noitidart from comment #28)
> It looks like no one is going to take this. So Ill take it and deploy it via
>
> But I need help please.
> Its hardcore js-ctypes so os dependent. I don't know C or C++ and have been
> bugging a guy on stackoverflow but I feel like I'm annoying him.
>
>
> I got all the ground work done, as in I got the C code, i even converted it
> all to ctypes to the best i can which is pretty dang buggy. Is there anyone
> that can help me out with the c to ctypes conversion, basically they just
> have to look at my js-ctypes conversion and fix that please.
>
> Anyone available?

I don't understand what you're trying to fix here. Could you provide a summary or maybe some steps to reproduce the issue you are seeing?
Hi Jim! Thanks so much for the reply I'm real excited. :P

Yep no worries I did all the research and already started on a WinXP solution to seperate groups. I'm in process of converting this here: http://w-shadow.com/blog/2006/10/01/manipulating-taskbar-buttons/comment-page-2/#comment-467865

This is what I have so far for xp: https://gist.github.com/Noitidart/1fc56b28be82d45a245d

For Win7 I'm working on RelaunchCommand so when I open the new profile, if the user pins it, it will pin with command line arguments. (http://stackoverflow.com/questions/24377859/make-window-think-its-exe-file-is-something-else-trying-to-pin-with-command-li)

This is what I have so far on js-cytpes conversion: https://gist.github.com/yajd/862832b07a1d46caef8b

For all os'es im working on bonus of allowing user to badge their icons you can see image of my progress here, right now just xp and win7+ (i dont have vista so i cant test on it)
https://github.com/Noitidart/Profilist/issues/18#issuecomment-46795390

:)
So basically on those gists i linked above, I'm having the hardest time converting code to js-ctypes because I'm trying to read and convert from C++ code samples, incredibly hard for me. Nmaier is helping me but I pester him too much :(

a bunch of topics here: http://stackoverflow.com/questions/tagged/jsctypes

and some in the winapi section but the winapi SO users are not as friendly as nmaier :(
http://stackoverflow.com/questions/tagged/winapi
(In reply to Jim Mathies [:jimm] from comment #30)
> I don't understand what you're trying to fix here. Could you provide a
> summary or maybe some steps to reproduce the issue you are seeing?

If you want to see the original bug of this post. Install Firefox 3.5, set up for multiple instances, give each a different profile.
Each profile will properly group with its own pin, and combine with said pin when run. And so on. Occasionally an update would break the fingerprint and the pins would need to be remade I think, but that was about it.

For some reason in FF3.7, the implementation was changed to be ?"more correct"?, and pretty much completely broke this intuitive function. It's been tweaked with a few times since, but pinning multiple different firefox configs is pretty painful, unintuitive, and irritating now. And as far as I can tell, only one pin will ever combine, out of multiple firefoxes now. Multiple usually causes the pin to un-combine...

Nice to see someone attacking this as a plugin I guess, real pity the base function was ?intentionally broken?...

Those of us running multiple instances are a fringe group. I suppose. But still.
Oh yeah. And it frequently breaks with a single one after 3.5 too ;P that was definitely part of it.
I've been working on it for the past 24 days lol. Struggling real hard. But almost got Windows covered. Then I'll cover mac then linux. But I need help converting to js-ctypes :(
Hey guys I got stuck, it looks like in js-ctypes i can't do IPropertyStore interface. If anyone is willing to fix this I can talk you through what needs to be done.

Basically the issue right now are many. If you want me to list I can. But here's the solution:

http://blogs.msdn.com/b/oldnewthing/archive/2011/06/01/10170113.aspx

To each window in a profile (i think, maybe can just do on the process id im not sure) do the following:

because we are setting RelaunchIconResource we have to set the RelaunchDisplayNameResource. But just keep RelaunchDisplayNameResource as "Firefox".

Also the GroupID of the default profile should remain at what is default given to firefox, before setting the about:config preference of taskbar.grouping.useprofile. If defaut profile is currently running, and while its running users change the default profile then this currently running profiles group id should be updated away from the default groupID of Firefox. THIS fixes the issue if a user had pinned firefox to the taskbar before setting taskbar.grouping.useprofile to true. Otherwise after setting this to true users have this useless firefox logo pinned to the taskbar.

Also is it possible to make taskbar.grouping.useprofile restartless?

Why isn't this taskbar.grouping.useprofile pref set to true by default?
I messed up the code in previous post for setting RelaunchIconResource anyways it should be set to whatever is the most common icon across the windows of the profile.

Also you can detect when a user changes the default profile by using file watcher (which is in dev) here: https://bugzilla.mozilla.org/show_bug.cgi?id=958280
Feedback from users showing that if we fix this bug it will be consistent with Mac OS. This feedback here shows how it works in Mac OS:
https://github.com/evacchi/firefox-custom-badge/issues/1#issuecomment-44571081
I had this problem too (Win 8.1) and solved it by;
-removing all pinned shortcuts
-starting firefox
-right click the running icon in the taskbar and select to pin it
-right click some empty space on the taskbar, select properties, and choose always combine taskbar buttons.
>> new instances all combine under the original pinned icon

I'm not sure if this is a generalised solution, but hope it's some help.
Thanks Brad for sharing. Our hope of this topic is that things work straightforward for a non hacky user. So the average just right clicks to pin. So we need to change the RelaunchCommand via IPropertyStore interface. So you don't have to do any weird things.

Also @Brad try doing Ctrl+N, will new windows group in that pinned icon? Or are they all lumping into another icon on the taskbar?
I would just like to note. The behaviors (In reply to Brad from comment #39)
> I had this problem too (Win 8.1) and solved it by;
> -removing all pinned shortcuts
> -starting firefox
> -right click the running icon in the taskbar and select to pin it
> -right click some empty space on the taskbar, select properties, and choose
> >> new instances all combine under the original pinned icon
>
> I'm not sure if this is a generalised solution, but hope it's some help.
I find this unlikely, if you're talking about actual seperate instances rather than just separate windows. As the original report was about. But just to be sure...

Last I checked. Pins will only work for one such. Period. Back in 3.5, we could have multiple setup as noted below, and each have a separate pin it would combine into.

Are you running multiple processes of firefox simultaneously? Because doing so breaks the grouping function horribly post-3.5 still I would bet. (This entails setting up shortcuts with separate profiles, and -no-remote on all but one or all of them. To be fair not a common configuration.)

Sounds more like you're talking about the grouping with a single pin breaking--which yeah that happens too and requires resetting the pin. Something that should really be a higher priority bug as it effects normal users not using advanced configurations... But not the bug in this report.
Yes sorry, it is a different situation to the OP (I'm also using Win 8.1 not Win 7).

To expand on/clarify my situation a bit, after what I describe above, if I open FF (31.0) from cmd.exe [top left in screenshot], open another from cmd.exe with -no-remote -P [top right] and then do Ctrl-N [bottom right] they all still appear under one icon in the taskbar. The first and second copies have different PIDs.

Here a screenshot, hovering over the icon for preview
http://i57.tinypic.com/2nba63o.png

I should point out at all of this was (infuriatingly) broken for a long time, before I chanced upon where I am now.
There's a workaround for it. I prefer this bug to fix it so we don't need work around.

But this is what you do: In each of your profiles go to about:config and set taskbar.grouping.useprofile to true. Then restart the browsers. They should seperate. Now you can pin them after they have seperated.
Yes, a bug. I agree.

Additionally the update to FF 32.0, just broke it again.

Fixed by going through the steps again.
I'm extremely close to solving this with js-ctypes:

the code is all correct and copied from C here:  http://blogs.msdn.com/b/oldnewthing/archive/2011/06/01/10170113.aspx

My code right now is trying to mimic nsIWintTaskBar.setGroupIdForWindow as soon as that works then I'll move to modifying RelaunchCommand and RelaunchIconResource which will fix this bugzilla topic.

So anyways the issue: my code is trying to does exactly what nsIWinTaskbar.setGroupIdForWindow ( i shared snippet below), my code is not erroring, but result is not same as setGroupIdForWindow, my IPropretyStore :: SetValue function is evening returning a good hr value.

I'm trying to review the code and figure out why it's not working, would appreciate if someone that knows jctypes and IPropertyStore http://msdn.microsoft.com/en-us/library/windows/desktop/bb761475%28v=vs.85%29.aspx

that could help out.

Does anyone know who wrote this code here on MXR:

68 SetWindowAppUserModelProp(nsIDOMWindow *aParent,
69                           const nsString & aIdentifier) {
70   NS_ENSURE_ARG_POINTER(aParent);
71
72   if (aIdentifier.IsEmpty())
73     return NS_ERROR_INVALID_ARG;
74
75   HWND toplevelHWND = ::GetAncestor(GetHWNDFromDOMWindow(aParent), GA_ROOT);
76
77   if (!toplevelHWND)
78     return NS_ERROR_INVALID_ARG;
79
80   typedef HRESULT (WINAPI * SHGetPropertyStoreForWindowPtr)
81                     (HWND hwnd, REFIID riid, void** ppv);
82   SHGetPropertyStoreForWindowPtr funcGetProStore = nullptr;
83
85   funcGetProStore = (SHGetPropertyStoreForWindowPtr)
87
88   if (!funcGetProStore) {
89     FreeLibrary(hDLL);
90     return NS_ERROR_NO_INTERFACE;
91   }
92
93   IPropertyStore* pPropStore;
94   if (FAILED(funcGetProStore(toplevelHWND,
95                              IID_PPV_ARGS(&pPropStore)))) {
96     FreeLibrary(hDLL);
97     return NS_ERROR_INVALID_ARG;
98   }
99
100   PROPVARIANT pv;
101   if (FAILED(InitPropVariantFromString(aIdentifier.get(), &pv))) {
102     pPropStore->Release();
103     FreeLibrary(hDLL);
104     return NS_ERROR_UNEXPECTED;
105   }
106
107   nsresult rv = NS_OK;
108   if (FAILED(pPropStore->SetValue(PKEY_AppUserModel_ID, pv)) ||
109       FAILED(pPropStore->Commit())) {
110     rv = NS_ERROR_FAILURE;
111   }
112
113   PropVariantClear(&pv);
114   pPropStore->Release();
115   FreeLibrary(hDLL);
116
117   return rv;
118 }

He's the guy that if I talked to it would help A TON A TON. Because I'm doing the same thing, changing System.AppUserModel properties.
Alright all SOLVED!!!!!!

Ok make sure you set the pref first:

2) Set taskbar.grouping.useprofile to true (cretae pref if its not there)
3) Then restart browser
4) Enable developer preferences so you can run browser context code from scratchpad (see here:
6) Go to menu toolbar of scratchpad called "Environment" and then click "Browser".
7) Copy paste into scratchpad the code at end of this poast
8) Hit "Run" button in scratchpad
9) You can now right click on the icon in the taskbar and pin it
10) Close firefox and click the icon you just pinned, it will launch your profile

bonus) Click on the shortcut you had that launched your profile, it will open all of them in this tab group. However dont drag your shortcut to the taskbar to pin it, ill release an addon that detects if the tile is draged from a shortcut and then it will change the System.UserModel.ID on the shortcut too so shortcuts stay togather.

Here is the code to paste:
-------------------

Cu.import('resource://gre/modules/ctypes.jsm')

var wintypesInit = function() {
// BASIC TYPES (ones that arent equal to something predefined by me)
this.BOOL = ctypes.int;
this.BOOLEAN = ctypes.char; // http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx // not used in this jsctypes code but just putting it here as i may need in future search as i have the documentation around this (the blog) in my mind right now and commented it here
this.DWORD = ctypes.unsigned_long;
this.HRESULT = ctypes.long;
this.HWND = ctypes.voidptr_t;
this.INT = ctypes.int;
this.PCWSTR = new ctypes.PointerType(ctypes.jschar); // https://github.com/FunkMonkey/Loomo/blob/06a5881a4f520ede092059a4115bf117568b914f/Loomo/chrome/content/modules/Utils/COM/COM.jsm#L35
this.UINT = ctypes.unsigned_int;
this.ULONG = ctypes.unsigned_long;
this.VARIANT_BOOL = ctypes.short; //http://msdn.microsoft.com/en-us/library/cc235510.aspx // http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx
this.VARTYPE = ctypes.unsigned_short;
this.VOID = ctypes.void_t;
this.VOIDPTR = ctypes.voidptr_t
this.WCHAR = ctypes.jschar;
this.WIN32_FIND_DATA = ctypes.voidptr_t;
this.WINOLEAPI = ctypes.voidptr_t; // i guessed on this one
this.WORD = ctypes.unsigned_short;

// ADVANCED TYPES (ones that are based on the basic types)
this.LPTSTR = new ctypes.PointerType(this.WCHAR);
this.LPCTSTR = this.LPTSTR;
this.LPWSTR = new ctypes.PointerType(this.WCHAR);
this.LPCWSTR = this.LPWSTR;
this.LPOLESTR = this.LPWSTR;
this.LPCOLESTR = this.LPOLESTR;

// BASIC STRUCTURES
this.GUID = ctypes.StructType('GUID', [ // http://msdn.microsoft.com/en-us/library/ff718266%28v=prot.10%29.aspx
{ 'Data1': ctypes.unsigned_long },
{ 'Data2': ctypes.unsigned_short },
{ 'Data3': ctypes.unsigned_short },
{ 'Data4': ctypes.char.array(8) }
]);

this.IID = this.GUID; // http://msdn.microsoft.com/en-us/library/cc237652%28v=prot.13%29.aspx
this.REFIID = new ctypes.PointerType(this.IID); // http://msdn.microsoft.com/en-us/library/cc237816%28v=prot.13%29.aspx

this.REFCLSID = new ctypes.PointerType(this.CLSID); // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L53

/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb773381%28v=vs.85%29.aspx
* typedef struct {
*   GUID  fmtid;
*   DWORD pid;
* } PROPERTYKEY;
*/
this.PROPERTYKEY = new ctypes.StructType('PROPERTYKEY', [
{ 'fmtid': this.GUID },
{ 'pid': this.DWORD }
]);
this.REFPROPERTYKEY = new ctypes.PointerType(this.PROPERTYKEY);	// note: if you use any REF... (like this.REFPROPERTYKEY) as an arg to a declare, that arg expects a ptr. this is basically like

/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb773381%28v=vs.85%29.aspx
* typedef struct PROPVARIANT {
*   VARTYPE vt;
*   WORD    wReserved1;
*   WORD    wReserved2;
*   WORD    wReserved3;
*   union {
*     CHAR              cVal;
*     UCHAR             bVal;
*     SHORT             iVal;
*     USHORT            uiVal;
*     LONG              lVal;
*     ULONG             ulVal;
*     INT               intVal;
*     UINT              uintVal;
*     LARGE_INTEGER     hVal;
*     ULARGE_INTEGER    uhVal;
*     FLOAT             fltVal;
*     DOUBLE            dblVal;
*     VARIANT_BOOL      boolVal;
*     SCODE             scode;
*     CY                cyVal;
*     DATE              date;
*     FILETIME          filetime;
*     CLSID             *puuid;
*     CLIPDATA          *pclipdata;
*     BSTR              bstrVal;
*     BSTRBLOB          bstrblobVal;
*     BLOB              blob;
*     LPSTR             pszVal;
*     LPWSTR            pwszVal;
*     IUnknown          *punkVal;
*     IDispatch         *pdispVal;
*     IStream           *pStream;
*     IStorage          *pStorage;
*     LPVERSIONEDSTREAM pVersionedStream;
*     LPSAFEARRAY       parray;
*     CAC               cac;
*     CAUB              caub;
*     CAI               cai;
*     CAUI              caui;
*     CAL               cal;
*     CAUL              caul;
*     CAH               cah;
*     CAUH              cauh;
*     CAFLT             caflt;
*     CABOOL            cabool;
*     CASCODE           cascode;
*     CACY              cacy;
*     CAFILETIME        cafiletime;
*     CACLSID           cauuid;
*     CACLIPDATA        caclipdata;
*     CABSTR            cabstr;
*     CABSTRBLOB        cabstrblob;
*     CALPSTR           calpstr;
*     CALPWSTR          calpwstr;
*     CAPROPVARIANT     capropvar;
*     CHAR              *pcVal;
*     UCHAR             *pbVal;
*     SHORT             *piVal;
*     USHORT            *puiVal;
*     LONG              *plVal;
*     ULONG             *pulVal;
*     INT               *pintVal;
*     UINT              *puintVal;
*     FLOAT             *pfltVal;
*     DOUBLE            *pdblVal;
*     VARIANT_BOOL      *pboolVal;
*     DECIMAL           *pdecVal;
*     SCODE             *pscode;
*     CY                *pcyVal;
*     DATE              *pdate;
*     BSTR              *pbstrVal;
*     IUnknown          **ppunkVal;
*     IDispatch         **ppdispVal;
*     LPSAFEARRAY       *pparray;
*     PROPVARIANT       *pvarVal;
*   };
* } PROPVARIANT;
*/
this.PROPVARIANT = new ctypes.StructType('PROPVARIANT', [
{'vt': this.VARTYPE},		// constants for this are available at MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/aa380072%28v=vs.85%29.aspx
{'wReserved1': this.WORD},
{'wReserved2': this.WORD},
{'wReserved3': this.WORD},
// union not supported by js-ctypes
// https://bugzilla.mozilla.org/show_bug.cgi?id=535378 "You can always
// typecast pointers, at least as long as you know which type is the biggest"
//note: important: pick one of the below and comment out the others: (because js-ctypes doesnt support union)
{ 'pwszVal': this.LPWSTR } // for InitPropVariantFromString // when using this see notes on MSDN doc page chat of PROPVARIANT ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa380072%28v=vs.85%29.aspx )this guy says: "VT_LPWSTR must be allocated with CoTaskMemAlloc :: (Presumably this also applies to VT_LPSTR) VT_LPWSTR is described as being a string pointer with no information on how it is allocated. You might then assume that the PROPVARIANT doesn't own the string and just has a pointer to it, but you'd be wrong. In fact, the string stored in a VT_LPWSTR PROPVARIANT must be allocated using CoTaskMemAlloc and be freed using CoTaskMemFree. Evidence for this: Look at what the inline InitPropVariantFromString function does: It sets a VT_LPWSTR using SHStrDupW, which in turn allocates the string using CoTaskMemAlloc. Knowing that, it's obvious that PropVariantClear is expected to free the string using CoTaskMemFree. I can't find this explicitly documented anywhere, which is a shame, but step through this code in a debugger and you can confirm that the string is freed by PropVariantClear: #include <Propvarutil.h>	int wmain(int argc, TCHAR *lpszArgv[])	{	PROPVARIANT pv;	InitPropVariantFromString(L"Moo", &pv);	::PropVariantClear(&pv);	}  If  you put some other kind of string pointer into a VT_LPWSTR PROPVARIANT your program is probably going to crash."
//{ 'boolVal:', this.VARIANT_BOOL } // for use with InitPropVariantFromBoolean
]);
this.REFPROPVARIANT = new ctypes.PointerType(this.PROPVARIANT);

// VTABLE's
var IPropertyStoreVtbl = new ctypes.StructType('IPropertyStoreVtbl');
var IPropertyStore = new ctypes.StructType('IPropertyStore', [{
'lpVtbl': IPropertyStoreVtbl.ptr
}]);
this.IPropertyStorePtr = new ctypes.PointerType(IPropertyStore);

IPropertyStoreVtbl.define(
[{ //start inherit from IUnknown
'QueryInterface': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.REFIID,	// riid
this.VOIDPTR	// **ppvObject
]).ptr
}, {
this.ULONG, [
IPropertyStore.ptr
]).ptr
}, {
'Release': ctypes.FunctionType(ctypes.stdcall_abi,
this.ULONG, [
IPropertyStore.ptr
]).ptr
}, { //end inherit from IUnknown //start IPropertyStore
'GetCount': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.DWORD.ptr	// *cProps
]).ptr
}, {
'GetAt': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.DWORD,				// iProp
this.PROPERTYKEY.ptr	//*pkey
]).ptr
}, {
'GetValue': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.REFPROPERTYKEY,	// key
this.PROPVARIANT.ptr	// *pv
]).ptr
}, {
'SetValue': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr,
this.REFPROPERTYKEY,	// key
this.REFPROPVARIANT		// propvar
]).ptr
}, {
'Commit': ctypes.FunctionType(ctypes.stdcall_abi,
this.HRESULT, [
IPropertyStore.ptr
]).ptr
}]
);

// CONSTANTS
this.CLSCTX_INPROC_SERVER = 0x1;
this.GA_ROOT = 2;
this.S_OK = new this.HRESULT(0); // http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx
this.S_FALSE = new this.HRESULT(1); // http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx
this.VARIANT_FALSE = this.VARIANT_BOOL(0); //http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx
this.VARIANT_TRUE = this.VARIANT_BOOL(-1); //http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx // im not doing new this.VARIANT_BOOL becuase as we see in this shortcut js-ctypes they simply do HRESULT(value) ( https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L389 )
this.VT_BOOL = 0x000B; // 11
this.VT_LPWSTR = 0x001F; // 31
}
var ostypes = new wintypesInit();

// start - skeleton, shouldn't have to edit
var lib = {};
function _lib(path) {
//ensures path is in lib, if its in lib then its open, if its not then it adds it to lib and opens it. returns lib
//path is path to open library
//returns lib so can use straight away

if (!(path in lib)) {
//need to open the library
//default it opens the path, but some things are special like libc in mac is different then linux or like x11 needs to be located based on linux version
switch (path) {
case 'x11':
try {
lib[path] = ctypes.open('libX11.so.6');
} catch (e) {
try {
var libName = ctypes.libraryName('X11');
} catch (e) {
console.error('Integration Level 1: Could not get libX11 name; not activating', 'e:' + e);
throw new Error('Integration Level 1: Could not get libX11 name; not activating, e:' + e);
}

try {
lib[path] = ctypes.open(libName);
} catch (e) {
console.error('Integration Level 2: Could not get libX11 name; not activating', 'e:' + e);
throw new Error('Integration Level 2: Could not get libX11 name; not activating, e:' + e);
}
}
break;
default:
try {
lib[path] = ctypes.open(path);
} catch (e) {
console.error('Integration Level 1: Could not get open path:', path, 'e:' + e);
throw new Error('Integration Level 1: Could not get open path:"' + path + '" e: "' + e + '"');
}
}
}
return lib[path];
}

var dec = {};
function _dec(declaration) { // it means ensureDeclared and return declare. if its not declared it declares it. else it returns the previously declared.
if (!(declaration in dec)) {
dec[declaration] = preDec[declaration](); //if declaration is not in preDec then dev messed up
}
return dec[declaration];
}
// end - skeleton, shouldn't have to edit

// start - predefine your declares here
var preDec = { //stands for pre-declare (so its just lazy stuff) //this must be pre-populated by dev // do it alphabateized by key so its ez to look through
CLSIDFromString: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms680589%28v=vs.85%29.aspx
* HRESULT CLSIDFromString(
*   __in_ LPCOLESTR lpsz,
*   __out_ LPCLSID pclsid
* );
*/
return _lib('Ole32.dll').declare('CLSIDFromString', ctypes.winapi_abi,
ostypes.HRESULT,	// return
ostypes.LPCOLESTR,	// lpsz
ostypes.GUID.ptr	// pclsid
);
},
CoCreateInstance: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms686615%28v=vs.85%29.aspx
* HRESULT CoCreateInstance(
*   __in_   REFCLSID rclsid,
*   __in_   LPUNKNOWN pUnkOuter,
*   __in_   DWORD dwClsContext,
*   __in_   REFIID riid,
*   __out_  LPVOID *ppv
* );
*/
return _lib('Ole32.dll').declare('CoCreateInstance', ctypes.winapi_abi,
ostypes.HRESULT,	// return
ostypes.REFCLSID,	// rclsid
ostypes.LPUNKNOWN,	// pUnkOuter
ostypes.DWORD,		// dwClsContext
ostypes.REFIID,		// riid
ostypes.LPVOID		// *ppv
);
},
CoInitializeEx: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms695279%28v=vs.85%29.aspx
* HRESULT CoInitializeEx(
*   __in_opt_  LPVOID pvReserved,
*   __in_      DWORD dwCoInit
* );
*/
return _lib('Ole32.dll').declare('CoInitializeEx', ctypes.winapi_abi,
ostypes.HRESULT,	// result
ostypes.LPVOID,		// pvReserved
ostypes.DWORD		// dwCoInit
);
},
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms680722%28v=vs.85%29.aspx
*   __in_opt_  LPVOID pv
* );
*/
ostypes.LPVOID	// pv
);
},
CoUninitialize: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms688715%28v=vs.85%29.aspx
* void CoUninitialize(void);
*/
return _lib('Ole32.dll').declare('CoUninitialize', ctypes.winapi_abi,
ostypes.VOID	// return
);
},
GetAncestor: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633502%28v=vs.85%29.aspx
* HWND WINAPI GetAncestor(
*   __in_ HWND hwnd,
*   __in_ UINT gaFlags
* );
*/
return _lib('user32').declare('GetAncestor', ctypes.winapi_abi,
ostypes.HWND,	// return
ostypes.HWND,	// hwnd
ostypes.UINT	// gaFlags
);
},
PropVariantClear: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa380073%28v=vs.85%29.aspx
* WINOLEAPI PropVariantClear(
* __in_ PROPVARIANT *pvar
* );
*/
return _lib('Ole32.dll').declare('PropVariantClear', ctypes.winapi_abi,
ostypes.WINOLEAPI,			// return
ostypes.PROPVARIANT.ptr		// *pvar
);
},
SHGetPropertyStoreForWindow: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/dd378430%28v=vs.85%29.aspx
* HRESULT SHGetPropertyStoreForWindow(
* __in_ HWND hwnd,
* __in_ REFIID riid,
* __out_ void **ppv
* );
*/
return _lib('shell32').declare('SHGetPropertyStoreForWindow', ctypes.winapi_abi,
ostypes.HRESULT,	// return
ostypes.HWND,		// hwnd
ostypes.REFIID,		// riid
ostypes.VOIDPTR		// **ppv // arai on irc 1/11/2015 // 01:21	noida	hey arrai capella would void** be ctypes.voidptr_t? or ctypes.voidptr_t.ptr? // 01:23	arai	I think they are totally different types, and it should be ctypes.voidptr_t.ptr
// actually scratch what arai said, like SHGetPropertyStoreForWindow third argument is out void** the QueryInterface also has out argument void** and he used ctypes.voidptr_t (https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L74)
);
},
SHStrDup: function() {
/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb759924%28v=vs.85%29.aspx
* HRESULT SHStrDup(
* __in_ LPCTSTR pszSource,
* __out_ LPTSTR *ppwsz
* );
*/
return _lib('Shlwapi.dll').declare('SHStrDupW', ctypes.winapi_abi,
ostypes.HRESULT,	// return
ostypes.LPCTSTR,	// pszSource	// old val from old Gist of mine RelunchCommand@yajd ctypes.voidptr_t and the notes from then: // can possibly also make this ctypes.char.ptr // im trying to pass PCWSTR here, i am making it as ctypes.jschar.array()('blah blah').address()
ostypes.LPTSTR.ptr	// *ppwsz	 	// old val from old Gist of mine RelunchCommand@yajd ctypes.voidptr_t and the notes from then: // can possibly also make this ctypes.char.ptr
);
}
}
// end - predefine your declares here

// start - helper functions
function checkHRESULT(hr, funcName) {
if(hr < 0) {
throw 'HRESULT ' + hr + ' returned from function ' + funcName;
}
}

/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb762305%28v=vs.85%29.aspx
* NOTE1: I have to write my own InitPropVariantFromString because its not in a dll its defined in a header
* I looked at wine's implementation ( https://github.com/wine-mirror/wine/blob/master/include/propvarutil.h#L88 ) and compared
* it to the usage example on MSDN doc page linked here, and Raymond's example of "I set the PROP­VARIANT manually instead of using Init­Prop­Variant­From­Boolean just to emphasize that the boolVal must be VARIANT_TRUE and not TRUE." ( http://blogs.msdn.com/b/oldnewthing/archive/2011/06/01/10170113.aspx )
* HRESULT InitPropVariantFromString(
*   __in_   BOOL fVal,
*   __out_  PROPVARIANT *ppropvar
* );
*/
function InitPropVariantFromBoolean(fVal/*jsbool*/, ppropvar/*ostypes.PROPVARIANT.ptr*/) {
// returns ostypes.HRESULT
ppropvar.vt = ostypes.VT_BOOL;
ppropvar.boolVal = fVal ? ostypes.VARIANT_TRUE : ostypes.VARIANT_FALSE;
return ostypes.S_OK;
}

/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb762305%28v=vs.85%29.aspx
* NOTE1: I have to write my own InitPropVariantFromString because its not in a dll its defined in a header
* NOTE2: When using this see notes on MSDN doc page chat of PROPVARIANT ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa380072%28v=vs.85%29.aspx )this guy says: "VT_LPWSTR must be allocated with CoTaskMemAlloc :: (Presumably this also applies to VT_LPSTR) VT_LPWSTR is described as being a string pointer with no information on how it is allocated. You might then assume that the PROPVARIANT doesn't own the string and just has a pointer to it, but you'd be wrong. In fact, the string stored in a VT_LPWSTR PROPVARIANT must be allocated using CoTaskMemAlloc and be freed using CoTaskMemFree. Evidence for this: Look at what the inline InitPropVariantFromString function does: It sets a VT_LPWSTR using SHStrDupW, which in turn allocates the string using CoTaskMemAlloc. Knowing that, it's obvious that PropVariantClear is expected to free the string using CoTaskMemFree. I can't find this explicitly documented anywhere, which is a shame, but step through this code in a debugger and you can confirm that the string is freed by PropVariantClear: #include <Propvarutil.h>	int wmain(int argc, TCHAR *lpszArgv[])	{	PROPVARIANT pv;	InitPropVariantFromString(L"Moo", &pv);	::PropVariantClear(&pv);	}  If  you put some other kind of string pointer into a VT_LPWSTR PROPVARIANT your program is probably going to crash."
* HRESULT InitPropVariantFromString(
*   __in_   PCWSTR psz,
*   __out_  PROPVARIANT *ppropvar
* );
*/
function InitPropVariantFromString(psz/*ostypes.PCWSTR*/, ppropvar/*ostypes.PROPVARIANT.ptr*/) {
//console.log('propvarPtr.contents.pwszVal', propvarPtr.contents.pwszVal, propvarPtr.contents.pwszVal.toSource(), uneval(propvarPtr.contents.pwszVal));
//console.log('propvarPtr', propvarPtr);
// console.log('propvarPtr.contents.pwszVal', propvarPtr.contents.pwszVal);

var hr_SHStrDup = _dec('SHStrDup')(psz, ppropvar.contents.pwszVal.address()); //note in PROPVARIANT defintion pwszVal is defined as LPWSTR and SHStrDup expects second arg as LPTSTR.ptr but both LPTSTR and LPWSTR are defined the same with ctypes.jschar so this should be no problem
console.info('hr_SHStrDup:', hr_SHStrDup, hr_SHStrDup.toString(), uneval(hr_SHStrDup));

// console.log('propvarPtr.contents.pwszVal', propvarPtr.contents.pwszVal);
checkHRESULT(hr_SHStrDup, 'InitPropVariantFromString -> hr_SHStrDup'); // this will throw if HRESULT is bad

ppropvar.contents.vt = ostypes.VT_LPWSTR;

return hr_SHStrDup;
}

// from: http://blogs.msdn.com/b/oldnewthing/archive/2011/06/01/10170113.aspx
function IPropertyStore_SetValue(vtblPpsPtr, pps/*IPropertyStore*/, pkey/*ostypes.REFPROPERTYKEY*/, pszValue/*ostypes.PCWSTR*/) { // i introduced vtblPpsPtr as i need it for js-ctypes
// returns hr of SetValue, but if hr of it failed it will throw, so i dont have to check the return value

var ppropvar = ostypes.PROPVARIANT();

checkHRESULT(hr_InitPropVariantFromString, 'failed InitPropVariantFromString'); //this will throw if HRESULT is bad

console.info('pps.SetValue', pps.SetValue);
var hr_SetValue = pps.SetValue(vtblPpsPtr, pkey, ppropvar.address());
checkHRESULT(hr_SetValue, 'IPropertyStore_SetValue');

console.info('rez_PropVariantClear:', rez_PropVariantClear, rez_PropVariantClear.toString(), uneval(rez_PropVariantClear));

return hr_SetValue;
}

function IPropertyStore_GetValue(vtblPpsPtr, pps/*IPropertyStore*/, pkey/*ostypes.REFPROPERTYKEY*/, ppropvar /*ostypes.PROPVARIANT*/ /* OR NULL if you want jsstr returned */) {
// currently setup for String propvariants only, meaning  key pwszVal is populated
// returns hr of GetValue if a ostypes.PROPVARIANT() is supplied as ppropvar arg
// returns jsstr if ppropvar arg is not supplied (creates a temp propvariant and clears it for function use)

var ret_js = false;
if (!ppropvar) {
ppropvar = ostypes.PROPVARIANT();
ret_js = true;
}

console.info('pps.GetValue', pps.GetValue);
var hr_GetValue = pps.GetValue(vtblPpsPtr, pkey, ppropvar.address());
checkHRESULT(hr_GetValue, 'IPropertyStore_GetValue');

console.info('ppropvar:', ppropvar, ppropvar.toString(), uneval(ppropvar));

if (ret_js) {
console.info('ppropvar.pwszVal:', ppropvar.pwszVal, ppropvar.pwszVal.toString(), uneval(ppropvar.pwszVal));

console.info('rez_PropVariantClear:', rez_PropVariantClear, rez_PropVariantClear.toString(), uneval(rez_PropVariantClear));

return jsstr;
} else {
console.warn('remember to clear the PROPVARIANT yourself then');
return hr_GetValue;
}
}
// end - helper functions

function shutdown() {
// do in here what you want to do before shutdown
for (var l in lib) {
try {
lib[l].close();
} catch (ex) {
throw new Error('Failure closing "' + l + '": ' + ex);
}
}
}

function main() {
//do code here

// start - looks like something i would run in _dec or just in main
var IID_IPropertyStore = new ostypes.GUID();
var hr_CLSIDFromString_IIDIPropertyStore = _dec('CLSIDFromString')('{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}', IID_IPropertyStore.address()); // IID_IPersistFile was on the MSDN page (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687223%28v=vs.85%29.aspx) under Requirements however IID_IPropertyStore was not on its MSDN page (http://msdn.microsoft.com/en-us/library/windows/desktop/bb761474%28v=vs.85%29.aspx) so I got this from github
console.info('hr_CLSIDFromString_IIDIPropertyStore:', hr_CLSIDFromString_IIDIPropertyStore, hr_CLSIDFromString_IIDIPropertyStore.toString(), uneval(hr_CLSIDFromString_IIDIPropertyStore));
checkHRESULT(hr_CLSIDFromString_IIDIPropertyStore, 'CLSIDFromString (IID_IPropertyStore)');

var tWin = Services.wm.getMostRecentWindow('navigator:browser');
var tBaseWin = tWin.QueryInterface(Ci.nsIInterfaceRequestor)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIBaseWindow);
var tHwnd = ostypes.HWND(ctypes.UInt64(tBaseWin.nativeHandle));
console.info('tHwnd:', tHwnd, tHwnd.toString(), uneval(tHwnd));

var tTopLevelHwnd = _dec('GetAncestor')(tHwnd, ostypes.GA_ROOT); // should make sure we have topLevelHWND per MXR: http://mxr.mozilla.org/mozilla-release/source/widget/windows/WinTaskbar.cpp#75
console.info('tTopLevelHwnd:', tTopLevelHwnd, tTopLevelHwnd.toString(), uneval(tTopLevelHwnd));

try {
var ppsPtr = new ostypes.IPropertyStorePtr(); // i have to use new event though ostypes.IPropertyStorePtr is defined as new ... this is how TimAbradles did it: https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L422  this is probably because its not a new StructType but a new PointerType. probably only new StructType's dont need the new when created in js runtime stuff like this line
var hr_SHGetPropertyStoreForWindow = _dec('SHGetPropertyStoreForWindow')(tTopLevelHwnd, IID_IPropertyStore.address(), ppsPtr.address()); //I figured out IID_IPropertyStore in the calls above, CLSIDFromString, I do this in place of the IID_PPV_ARGS macro, I could just make those two lines I did above the IID_PPV_ARGS function. Also see this Stackoverflow topic about IID_PPV_ARGS: http://stackoverflow.com/questions/24542806/can-iid-ppv-args-be-skipped-in-jsctypes-win7
console.info('hr_SHGetPropertyStoreForWindow:', hr_SHGetPropertyStoreForWindow, hr_SHGetPropertyStoreForWindow.toString(), uneval(hr_SHGetPropertyStoreForWindow));
checkHRESULT(hr_SHGetPropertyStoreForWindow, 'SHGetPropertyStoreForWindow') //this throws so no need to do an if on hr brelow here are my notes from the old gist: //im not sure that was possible anyways as hr is now -2147467262 and its throwing, before thi, with my if (hr) it would continue thinking it passed

var pps = ppsPtr.contents.lpVtbl.contents;

// start get PKEY's
var fmtid_ID = fmtid_RelaunchCommand = fmtid_RelaunchDisplayNameResource = fmtid_RelaunchIconResource = new ostypes.GUID();
var hr_fmtid = _dec('CLSIDFromString')('{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}', fmtid_ID.address()); // same for guid for: ID, RelaunchCommand, RelaunchDisplayNameResourche, RelaunchIconResource, and IsDestListSeparator // source1: msdn, see links to respective msdn pages on the comment on the PKEY's below //source2: https://github.com/truonghinh/TnX/blob/260a8a623751ffbce14bad6018ea48febbc21bc6/TnX-v8/Microsoft.Windows.Shell/Standard/ShellProvider.cs#L358
checkHRESULT(hr_fmtid, 'hr_fmtid'); //this throws on error

// doing these console.info's to make sure when i do CLSIDFromString on fmtid_ID that its going to the others as reference // test is as expected, ah!
console.info('fmtid_ID:', fmtid_ID, fmtid_ID.toString(), uneval(fmtid_ID));
console.info('fmtid_RelaunchCommand:', fmtid_RelaunchCommand, fmtid_RelaunchCommand.toString(), uneval(fmtid_RelaunchCommand));

var PKEY_AppUserModel_ID = ostypes.PROPERTYKEY(fmtid_ID, 5); // guid and pid from: http://msdn.microsoft.com/en-us/library/dd391569%28v=vs.85%29.aspx
var PKEY_AppUserModel_RelaunchCommand = ostypes.PROPERTYKEY(fmtid_RelaunchCommand, 2);// guid and pid from: http://msdn.microsoft.com/en-us/library/dd391571%28v=vs.85%29.aspx
var PKEY_AppUserModel_RelaunchDisplayNameResource = ostypes.PROPERTYKEY(fmtid_RelaunchDisplayNameResource, 4); // guid and pid from: http://msdn.microsoft.com/en-us/library/dd391572%28v=vs.85%29.aspx
var PKEY_AppUserModel_RelaunchIconResource = ostypes.PROPERTYKEY(fmtid_RelaunchIconResource, 3); // guid and pid from: http://msdn.microsoft.com/en-us/library/dd391573%28v=vs.85%29.aspx

// end get PKEY's
///*
// can use ostypes.WCHAR.array()('Contoso.Scratch') or just use jsstring 'Contoso.Scratch', i verified this by finding the default id, and then setting window id to Contoso.Scratch which moved the window out, then I set the window back to default id of 'E7CF176E110C211B' and it went back to original group. THEN I moved it back out by setting to 'Contoso.Scratch' and then set it to ostypes.WCHAR.array()('E7CF176E110C211B') and it put it back into the original group // the helper function IPropertyStore_SetValue already checks hr and throws error if it fails so no need to check return value here
var hr_IPSSetValue = IPropertyStore_SetValue(ppsPtr, pps, PKEY_AppUserModel_RelaunchCommand.address(), '"' + FileUtils.getFile('XREExeF', []).path + '" -profile "' + OS.Constants.Path.profileDir + '" -no-remote');
//var hr_IPSSetValue = IPropertyStore_SetValue(ppsPtr, pps, PKEY_AppUserModel_RelaunchIconResource.address(), OS.Path.join(OS.Constants.Path.desktopDir, 'ppbeta.ico'));

/*
var hr_Commit = pps.Commit(ppsPtr);
console.info('hr_Commit:', hr_Commit, hr_Commit.toString(), uneval(hr_Commit));
checkHRESULT(hr_Commit, 'hr_Commit');
*/

//*/
/*
//var myPPV = ostypes.PROPVARIANT();
var jsstr_IPSGetValue = IPropertyStore_GetValue(ppsPtr, pps, PKEY_AppUserModel_ID.address(), null);
console.info('jsstr_IPSGetValue:', jsstr_IPSGetValue, jsstr_IPSGetValue.toString(), uneval(jsstr_IPSGetValue));
*/
//IPropertyStore_SetValue(ppsPtr, pps.address(), PKEY_AppUserModel_RelaunchCommand, ostypes.WCHAR.array()('Contoso.Scratch')); // the helper function IPropertyStore_SetValue already checks hr and throws error if it fails so no need to check return value here

} catch(ex) {
console.error(ex);
} finally {
if (pps) {
try {
pps.Release(ppsPtr);
console.log('released');
} catch (ex) {
console.error('Failure releasing pps: ', ex);
}
}
}

}

// start - globals for my main stuff

// end - globals

try {
main();
} catch(ex) {
throw ex;
} finally {
shutdown();
}
Btw my previous reply is just to share the solution. I'm releasing my addon Profilist which will have this built in and will also allow you to badge the icon (the icon will show badged in taskbar, alt+tab menu, and all windows) cool stuff :) Took only 6 months to figure out HAHAHA!!
Ok forget the copy paste code above i put it into an addon real fast.

BEFORE running this addon, make sure you create a boolean pref named taskbar.grouping.useprofile and set it to true then restart. THEN install the attached addon, then remove the addon. then right click on the icon in taskbar and pin it. now future clicks will relaunch the proper profile and shortcuts that open this profile will open into this group.
by restart i of course mean restart the specific browser. not the computer or anything else.

man bugzilla needs comment edit :(
If you guys want you can find the respective shortcut after pinning and change the name from "Firefox - ########" to be like "Firefox - My Profile Name" and you can also change the icon there. Fun stuff. The shortcuts after pinning are located here: %APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\ImplicitAppShortcuts just look through the folders till you find your matching name.

Or if you want to set the name and icon via the code, its just a couple lines:
edit name here: https://github.com/Noitidart/Bugzilla-644914-Solution/blob/master/bootstrap.js#L571
uncomment and set path to icon on this line: https://github.com/Noitidart/Bugzilla-644914-Solution/blob/master/bootstrap.js#L572
Ok I got a bit hyper there as I learned COM via js-ctypes. Anyways solution implemented with Profilist. The addon is in beta right now as OSX and Linux implementation isn't complete. Here's a screencast: https://www.youtube.com/watch?v=fKw-BNWMyQM

@rogue, you can right click on the icon running in the taskbar and click pin/unpin. And the shortcuts created from the options panel with this are pinnable to the dock or start screen (Win8+) via drag or whatever other operations.

https://github.com/Noitidart/Profilist/
Flags: needinfo?(roguethunderbird)
I have been searching for the way of pin two shortcuts for two different profiles for more than 3 days and this topic was the most useful for me so that I'll post my solution here.
So, if you want to run two instances of Firefox at the same time and you don't want to see them combined, follow my instructions.
1. Create two profiles (win+ r -> firefox -p -> and so on)
2. Create a link to your current firefox folder (for me it's C:\Program Files\Mozilla Firefox). You can do it using commandline: mklink /d "C:\Program Files\Mozilla Firefox 2" "C:\Program Files\Mozilla Firefox".
3. Instead of creating a link you can just create new folder "Firefox 2" and copy to it everything from original Firefox folder.
4. Create new application2.ini file and paste to it everything from original application.ini (this file is located in the firefox's folder).
5. Change Vendor=Mozilla Name=Firefox to Vendor=Mozilla2 Name=Firefox2 in application2.ini
6. Create two shortcuts for the firefox.exe (one from the original folder and one from the linked folder)
7. Edit the properties of first shortcut. Make sure that work folder is set to original folder and, what is the most importnat, add to the object field "-app application.ini" -p YourFirstProfile -no-remote
8. Edit the properties of second shortcut - add to the odject field "-app application2.ini" -p YourFirstProfile -no-remote
9. Pin both of the shortcuts to the taskbar.
10. Launch both instances. Each of them will run separate.
Hi teddiaps@gmail.com you can use Profilist beta, create a desktop shortcut and then drag those to the start bar - https://addons.mozilla.org/en-US/firefox/addon/profilist/
Hey guys, I got an update.
I tried to create another one profile but everything went wrong and all my profiles started to launch in new windows instead of pinned.
If you encountered this, don't panic.
At first, unpin every shortcut related to the firefox and restart your PC.
At second, make a new shortcut from original FF folder and place it somewhere.
Next, modify it - add "-app application.ini" -p YourFirstProfile -no-remote to the object field. Run Firefox using this shotcut.
A new Firefox window will open - you'll have to pin it. After that, go to shortcut folder (%appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar) and find your new pinned shortcut (it will be named like Firefox or Mozilla Firefox). Edit his properties ("-app application.ini" -p YourFirstProfile -no-remote).
Finally, reboot your PC in order to see the change of an icon of the shortcut (if you changed it before) and launch your new profile by clicking on pinned shortcut. Firefox should create a new windows using pinned shortcut.
If everything went ok, you should repeat all the steps with another profiles.
P.S. I don't know why, but the profile launched from linked " MozillaFirefox 2" folder may have some problems. So, just avoid this number and link original folder with "mozilla firefox 3", for example.

If this is still an issue, with fresh installs with the latest Firefox, it might be useful for an update and a clear description as to what the issue is and what isn't working. As it currently stands, this issue is unlikely to move forward.

Flags: needinfo?(roguethunderbird)
Priority: -- → P5
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.