In Windows 7 we have the concept of ApplicationID, which allows (among other things) to group several icons in the task bar.
How can I change the ApplicationID of a running process from c#? I'm trying to make my WinForm app's icon group with another application.
I've tried using Windows API Code Pack Library, sticking the following code in my Load event... but it didn't work. Suggestions?
TaskbarManager.Instance.ApplicationId = "MyAppID";
Process[] p = Process.GetProcessesByName("OtherProcess");
TaskbarManager.Instance.SetApplicationIdForSpecificWindow(p[0].MainWindowHandle, "MyAppID");
I repro this. I think the SDK docs are wrong and the XML docs for the SetApplicationIdForSpecificWindow() method are correct:
AppId specifies a unique Application
User Model ID (AppID) for the
application or individual top-level
window whose taskbar button will hold
the custom JumpList built through the
methods class.
By setting an appId for a specific
window, the window will NOT be grouped
with it's parent window/application.
Instead it will have it's own taskbar
button.
I emphasized NOT.
A (somewhat) obvious solution is to set both of the windows' Application IDs you want grouped together to the same ID.
Example:
TaskbarManager.Instance.SetApplicationIdForSpecificWindow(win1.MainWindowHandle, "W00T");
TaskbarManager.Instance.SetApplicationIdForSpecificWindow(win2.MainWindowHandle, "W00T");
Aaaaand both the windows will be grouped together.
Related
In more recent versions of Windows the taskbar will combine two buttons together when I open the same application twice. What can I do to avoid that (not counting changing the Windows settings, because I want it for my application only, not all applications).
Raymond Chen has detailed how to do this a while ago on his blog: How do I customize how my application windows are grouped in the Taskbar?:
All the information in this article came from the article Application User Model IDs (AppUserModelIDs) in MSDN.
Okay, so suppose your application is really a runtime for other applications. What you need to do is assign a different AppID to each of the applications you are hosting. The mechanism for this is up to you. Your applications might explicitly provide a unique ID, or you may be able to infer one. For example, if you are Internet Explorer and your "applications" are pinned Web sites, you can use the URL of the site being pinned as the unique ID.
You then get to take your unique IDs and create AppIDs for them. The format of an AppID is
CompanyName.ProductName.SubProduct.VersionInformation
where the SubProduct is optional, and the VersionInformation is present only if you want different versions of your app to be treated as distinct. (If you want an upgraded version to be a replacement for the old version, then omit the VersionInformation so that the old and new versions use the same AppID.)
You then assign this AppID to every window associated with the "application". You can do this for an entire process by calling SetCurrentProcessExplicitAppUserModelID, or you can do it on a window-by-window basis by setting the PKEY_AppUserModel_ID property.
I have two applications. One is the main application and the other is the updater.
A user launches with the updater - if an update is available it will download and extract, otherwise it will just launch the main application. I used two applications for this so that I am able to overwrite the main applcation.
The issue is that the users have pinned the "Launcher" application on their taskbar, but when the main application launches it is not grouped under that icon and very confusing for them.
Is there any way around this?
You should be able to do that using Windows API Code Pack.
You need to use Microsoft.WindowsAPICodePack.Taskbar namespace from the Microsoft.WindowsAPICodePack.Shell assembly.
Call TaskbarManager.Instance.SetApplicationIdForSpecificWindow( window, string appId ); method. You can specify either an IntPtr windows handle if you're using WinForms, or a Window instance if you're using WPF.
Do this step in both your processes immediately after launch, and specify the same appId for both.
you can refer [ How to group my apps in windows taskbar? ] of George's answer,
by forcefully make two process share the same APP_ID(string)
simply by calling shell32!SetCurrentProcessExplicitAppUserModelID at each process's main()
It was already mentioned to set the Application user Model ID.
But then you still have the problem that when the Application is pinned, it will not pin to the Launcher. But there is also a solution for this, that the Launcher/Updater is pinned instead of the Application: Pinning to the taskbar a "chained process"
I noticed for a few updates of Skype now that if you start 2 or 3 instances of Skype, in the windows taskbar they appear as separate windows and you can drag them individually as opposed to other applications when they are "glued" together and you can drag them all at once.
My question is how can I implement the individual appearance in my application and is it possible from C# or through winapi?
The shell groups windows in the taskbar using each window's Application User Model ID (AppUserModelID).
By default, every window generated by a given EXE (even in different processes) shares a system-generated AppUserModelID.
You can give each process its own AppUserModelID by calling SetCurrentProcessExplicitAppUserModelID. From your description this is probably what Skype is doing, though I haven't checked.
You can give each window its own AppUserModelID by setting a different PKEY_AppUserModel_ID property on the windows.
Note that these IDs are required to have a particular format:
CompanyName.ProductName.SubProduct.VersionInformation
Raymond Chen wrote an article about this, and it's also worth reading the documentation I linked to.
I'm not aware of WinForms having explicit support for this, but you could certainly use interop to call the Win32 API directly.
I'm developing a piece of software to inset some text in a rich edit of another program the code goes like this:
atlfe = FindWindowEx(wtlsplitterwindow, 0, "atl:0087d7a8" , null);
This is only one line: this works fine, problem is with every release of the program number atl:0087d7a8 changes so i have to use spy++ to get the new one and change it in the code.
The question is, is there is any way I can get that number from code?
By the way I'm using C#, VS2010.
I suggest you use UI Automation instead of raw Windows API. You should start with the UI Spy tool to determine the UI hierarchy of your app, it will be more resilient to change.
See some articles on this subject on SO:
Retrieve current URL from C# windows forms application
How to get the word under the cursor in Windows?
Been a while since I messed with some of these windows API's. I think this may be of value though.
http://msdn.microsoft.com/en-us/magazine/cc163617.aspx
If the Title is always the same, use it instead of class name
atlfe = FindWindowEx(wtlsplitterwindow, 0, null, "Title");
More info on MSDN.
Clearly if the sub-window has not title and its classname is different every time you have but one method remaining.
You are first going to have to find the top level window of this app using either EnumWindows or FindWindowEx, the latter if you can identify it by class name and/or window title.
Once you have the top level window you can walk through the children to locate the sub-window that you are looking for. Presumably you already know the relationships between the top level window and the sub-window you are targetting. In any case Spy++ can tell you this.
I have created a couple of WPF apps but when right clicking them in the Windows 7 Taskbar I just get a Close Windows Option, usually there is a Pin to Taskbar option, I don't know where this has gone, is there anything that needs to be enabled or anything.
I am using:
VS2010 + Blend 4 with .NET Framework 3.5SP1
Your shortcut for the WPF Application requires an AppUserModelID. This is a property that can be set on any .lnk shortcut. Once Windows knows the AppUserModelID it provides the new features of the Taskbar to the app, including taskbar icon glomming which groups several open windows of the same app together. If you use MSI to install your apps you can use the MsiShortcutProperty table and set AppIDProperty for your app's shortcut. The value takes the following form:
For your MsiShortcutProperty table, add the following values to the table:
Columns/values:
MsiShortcutProperty/AppIDProperty
Shortcut_/MyShortcut.<guid>
PropertyKey/System.AppUserModel.ID
PropVariantValue/<YourCompanyName.ProductName.SubProduct.VersionInformation>
You can also look at the following article which explains how the ID is used and can be set on a shortcut programmatically: http://msdn.microsoft.com/en-us/library/dd378459%28VS.85%29.aspx#where
I think you need to look into this http://code.msdn.microsoft.com/Windows7Taskbar