Open
Bug 644914
Opened 12 years ago
Updated 5 months ago
Firefox only combines with pinned taskbar icon if taskbar icon is named "Mozilla Firefox"
Categories
(Firefox :: General, defect, P5)
Tracking
()
UNCONFIRMED
People
(Reporter: roguethunderbird, Unassigned)
Details
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.
Comment 1•12 years ago
|
||
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
Reporter | ||
Comment 2•12 years ago
|
||
(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.
Reporter | ||
Comment 3•12 years ago
|
||
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.
![]() |
||
Comment 4•12 years ago
|
||
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.
Updated•12 years ago
|
Version: unspecified → 4.0 Branch
Comment 5•12 years ago
|
||
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
Updated•12 years ago
|
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"
Comment 6•11 years ago
|
||
> 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.
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.
![]() |
||
Comment 7•11 years ago
|
||
(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.
Comment 8•11 years ago
|
||
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.
![]() |
||
Comment 9•11 years ago
|
||
(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.
Comment 10•11 years ago
|
||
> 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?
![]() |
||
Comment 11•11 years ago
|
||
(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.
![]() |
||
Comment 12•11 years ago
|
||
Bug 577867 encompassed the changes in 10.
Reporter | ||
Comment 13•11 years ago
|
||
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.
Reporter | ||
Comment 14•11 years ago
|
||
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...)
![]() |
||
Comment 15•11 years ago
|
||
You can add command line parameters to pinned shortcuts by editing the shortcut file - C:\Users\(username)\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar 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.
Reporter | ||
Comment 16•11 years ago
|
||
(In reply to Jim Mathies [:jimm] from comment #15) > You can add command line parameters to pinned shortcuts by editing the > shortcut file - > > C:\Users\(username)\AppData\Roaming\Microsoft\Internet Explorer\Quick > Launch\User Pinned\TaskBar 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!
Reporter | ||
Comment 17•11 years ago
|
||
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!
Reporter | ||
Comment 18•11 years ago
|
||
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.
Comment 19•9 years ago
|
||
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
Reporter | ||
Comment 20•9 years ago
|
||
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)
Comment 21•9 years ago
|
||
(In reply to Jim Mathies [:jimm] from comment #15) > You can add command line parameters to pinned shortcuts by editing the > shortcut file - > > C:\Users\(username)\AppData\Roaming\Microsoft\Internet Explorer\Quick > Launch\User Pinned\TaskBar > > 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.
Comment 22•9 years ago
|
||
btw i set that preference in all my firefox profiles
Comment 23•9 years ago
|
||
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.
Comment 24•9 years ago
|
||
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
Comment 25•9 years ago
|
||
Also a curious thing: http://mxr.mozilla.org/mozilla-central/source/widget/windows/WinTaskbar.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)?
Comment 26•9 years ago
|
||
(In reply to noitidart from comment #25) > Also a curious thing: > http://mxr.mozilla.org/mozilla-central/source/widget/windows/WinTaskbar. > 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.
Comment 27•9 years ago
|
||
Ah cool ok thanks man!
Comment 28•9 years ago
|
||
It looks like no one is going to take this. So Ill take it and deploy it via addon. 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?
Comment 29•9 years ago
|
||
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.
![]() |
||
Comment 30•9 years ago
|
||
(In reply to noitidart from comment #21) > 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. 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: > http://mxr.mozilla.org/mozilla-central/source/widget/windows/WinTaskbar. > 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 > addon. > > 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?
Comment 31•9 years ago
|
||
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 :)
Comment 32•9 years ago
|
||
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 :( http://stackoverflow.com/questions/24350386/address-to-wchar-t-to-pass-to-readprocessmemory/ https://ask.mozilla.org/question/781/sendmessage-with-tb_getbutton-pointer-crashes-explorerexe-winxp/ 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
Reporter | ||
Comment 33•9 years ago
|
||
(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.
Reporter | ||
Comment 34•9 years ago
|
||
Oh yeah. And it frequently breaks with a single one after 3.5 too ;P that was definitely part of it.
Comment 35•9 years ago
|
||
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 :(
Comment 36•9 years ago
|
||
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: IPropertyStore_SetValue(pps, PKEY_AppUserModel_RelaunchCommand, L"notepad.exe %windir%\\system.ini"); IPropertyStore_SetValue(pps, PKEY_AppUserModel_RelaunchIconResource, L"notepad.exe %windir%\\system.ini"); 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?
Comment 37•9 years ago
|
||
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
Comment 38•9 years ago
|
||
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
Comment 39•9 years ago
|
||
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.
Comment 40•9 years ago
|
||
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?
Reporter | ||
Comment 41•9 years ago
|
||
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 > 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. 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.
Comment 42•9 years ago
|
||
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.
Comment 43•9 years ago
|
||
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.
Comment 44•9 years ago
|
||
Yes, a bug. I agree. Additionally the update to FF 32.0, just broke it again. Fixed by going through the steps again.
Comment 45•8 years ago
|
||
I'm extremely close to solving this with js-ctypes: my code: https://github.com/Noitidart/_scratchpad/blob/master/IPropertyStore%20COM%20jsctypes.js the code is all correct and copied from C here: http://blogs.msdn.com/b/oldnewthing/archive/2011/06/01/10170113.aspx and Firefox does the same thing with nsIWintTaskBar.setGroupIdForWindow: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWinTaskbar?redirectlocale=en-US&redirectslug=nsIWinTaskbar#setGroupIdForWindow%28%29 MXR for this: http://mxr.mozilla.org/mozilla-release/source/widget/windows/WinTaskbar.cpp#101 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 84 HMODULE hDLL = ::LoadLibraryW(kShellLibraryName); 85 funcGetProStore = (SHGetPropertyStoreForWindowPtr) 86 GetProcAddress(hDLL, "SHGetPropertyStoreForWindow"); 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.
Comment 46•8 years ago
|
||
Alright all SOLVED!!!!!! Ok make sure you set the pref first: 1) Go to about:config 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: 5) Open scratchpad 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.LPUNKNOWN = ctypes.voidptr_t; // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm this.LPVOID = ctypes.voidptr_t; // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm this.PCIDLIST_ABSOLUTE = ctypes.voidptr_t; // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L115 this.PCWSTR = new ctypes.PointerType(ctypes.jschar); // https://github.com/FunkMonkey/Loomo/blob/06a5881a4f520ede092059a4115bf117568b914f/Loomo/chrome/content/modules/Utils/COM/COM.jsm#L35 this.PIDLIST_ABSOLUTE = ctypes.voidptr_t; // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L106 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) } ]); // ADVANCED STRUCTURES 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.CLSID = this.GUID; // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L52 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; * CADBL cadbl; * CABOOL cabool; * CASCODE cascode; * CACY cacy; * CADATE cadate; * 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 }, { 'AddRef': ctypes.FunctionType(ctypes.stdcall_abi, 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.COINIT_APARTMENTTHREADED = 0x2; //https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm 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 ); }, CoTaskMemFree: function() { /* http://msdn.microsoft.com/en-us/library/windows/desktop/ms680722%28v=vs.85%29.aspx * void CoTaskMemFree( * __in_opt_ LPVOID pv * ); */ return _lib('Ole32.dll').declare('CoTaskMemFree', ctypes.winapi_abi, 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 PROPVARIANT manually instead of using InitPropVariantFromBoolean 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); // console.log('propvarPtr.contents.pwszVal.address()', propvarPtr.contents.pwszVal.address()); 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(); var hr_InitPropVariantFromString = InitPropVariantFromString(pszValue, ppropvar.address()); 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'); var rez_PropVariantClear = _dec('PropVariantClear')(ppropvar.address()); 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)); var jsstr = ppropvar.pwszVal.readString(); var rez_PropVariantClear = _dec('PropVariantClear')(ppropvar.address()); 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) .getInterface(Ci.nsIWebNavigation) .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_ID.address(), Services.prefs.getCharPref('browser.taskbar.lastgroupid')); 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_RelaunchDisplayNameResource.address(), 'Firefox - ' + Services.prefs.getCharPref('browser.taskbar.lastgroupid')); //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 //IPropertyStore_SetValue(ppsPtr, pps.address(), PKEY_AppUserModel_RelaunchDisplayNameResource, ostypes.WCHAR.array()('C:\\full\\path\\to\\scratch.exe,-1')); } 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(); }
Comment 47•8 years ago
|
||
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!!
Comment 48•8 years ago
|
||
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.
Comment 49•8 years ago
|
||
by restart i of course mean restart the specific browser. not the computer or anything else. man bugzilla needs comment edit :(
Comment 50•8 years ago
|
||
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
Comment 51•8 years ago
|
||
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)
Comment 52•7 years ago
|
||
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.
Comment 53•7 years ago
|
||
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/
Comment 54•7 years ago
|
||
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.
Comment 55•4 years ago
|
||
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
Updated•5 months ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•