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"
Related
I'm developing a MVC application using .NET 6.0. I am publishing the app with the following configuration:
The app, so far, is launched by double-clicking the .exe, it shows the classic "cmd-style" window.
Now the requirement is to start the portable app minimized into a system tray notification area in Windows (if this is not possible, I was looking for a method to deploy the app as a service which runs in background).
How can I achieve this? Thank you.
To obtain access to the system tray, you need a message pump and a target window. In other words, a regular command-line executable doesn't cut it. Basically you need to have an executable that creates a window (can be an invisible one) and then the main thread must pump Windows messages.
I'll say this much for now becuase the provided information is insufficient and explaining all possible scenarios would be too long a response.
I am writing an Add in for a Desktop Application. I do not have the access to code the Desktop app but I need to capture all windows that are related to that from within my Add in. Anything not related to app should not be captured. All windows might not be the new processes. Any idea How can i achieve this?
You could try to do the following:
Identify the desktop app's process id and any child processed it may have spawned
Build a list of all windows that belong to the process id(s) identified previously (try #Konstantin Spirin's proposed solution)
Do a screenshot of each of the windows (try out #Maurice Flanagan's solution)
Perhaps this is a silly question, however I've searched around quite a bit and not been able to find an answer related to UWP apps.
How can one trigger an instance of their app's main window to open when middle-mouse clicking the taskbar icon? Edge can do it, so I'm assuming it's possible, just not documented or frequently done.
Thanks in advance!
By default, UWP apps support only one view (window) per app at one time so when user tries to open an UWP app that is already running, system switches to the running app rather then creating a new instance.
So you have to support multiple views in your app in order to create new instance when middle-clicked on taskbar.
You can find some documentation about multiple views in UWP app on MSDN, for example in this article.
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 not going to go into details why am trying to do this, instead of making the main application do the work. I think it's currently easier for me. But I'm not going to use this technique in the future.
In my case, the main form has a button that opens another form. In the second one for you can adjust the amount, pause, resume and stop the work of the console application (sound totally useless (and maybe stupid), but, like I said, I'm not going to go into details why). This means that the application must have access to all the variables and resources of the whole program and vise versa.
I know how to launch a new form trough a main form, but I don't know how to launch a console application.
EDIT:
I forgot to mention, that the console application is a part of the solution.
Your requirement is a bit vague; "the application must have access to all the variables and resources of the whole program and vise versa". 'Variables and resources' cannot be shared across processes, you will instead need interprocess communication of some form.
If your console app merely needs to communicate back to the calling forms app that a RPC has succeeded then use exit codes in the console app, see: How do I return a value from a console application to a service in .NET?
Otherwise this has been answered before: Getting the ouput from Console window into Winform application
You'll need to either create a console emulator (time consuming and difficult to get right), or fire up cmd.exe in another process and use remote procedure calls (or another inter process communication method) to communicate between the two processes
If you want to communicate between the two processes, take a look at this library here:
https://github.com/TheCodeKing/XDMessaging.Net
It allows you to send messages from one app to the other. For example, App1 sends a message "stop" on the channel "randomkey" to ConsoleApp1, ConsoleApp1 can listen on the channel "randomkey" and intercept the "stop" message and stop its current processing.
If you wanted to just open the console window, just use System.Diagnostics.Process.Start();
You can just call Main directly. Beware of doing this on the UI thread directly though!
SomeConsoleApp.Main(new string[]{"-O", "File 1.txt", "-some-parameter"});
Or if you only have an exe, you can do:
System.Diagnostics.Process.Start("someconsoleapp.exe");