Winforms tray application and WM_CLOSE - c#

How to write a WinForms application that would not have any visible element except from a tray icon and at the same time allow the application to be closed by Windows Installer if the file is in use? As I understand it the Windows Installer sends a WM_CLOSE message to application's main window. I assume that the "main window" is indicated by MainForm property of ApplicationContext. Also it seems to me that for this mechanism to work the form must have been shown at least once.
I found some workarounds like creating an empty form and setting its opacity to 0 (to minimize flicker) then showing and hiding, but describing this as a nasty hack would heavily underestimate its ugliness.

Windows Installer does not send any WM_CLOSE messages. This might help:
http://haishibai.blogspot.com/2010/02/complete-tutorial-patch-restart-your.html
It's a slightly different scenario but might get you started if you want Windows Installer to tell your app when it should close down.
On recent operating system versions with Restart Manager a tray app will be detected. Back on Windows XP it wasn't detected.
In the WiX world there is a CloseApplication utility custom action that will send WM_CLOSE to the app window.

Related

How to launch in system tray icons a MVC app

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.

Disable Taskbar in Windows 10

Is there any way to completely disable the taskbar in Windows 10 Home? I have a C# app that I want to display fullscreen on clients' displays without any sign of it running on Windows. It's supposed to run on startup and display a website.
I created a setup that changes most of the Windows settings via registry, like hiding desktop icons and altering logon view, but the taskbar remains visible. Auto hide doesn't satisfy me, because after the system boots the taskbar is still visible until you actually click somewhere on the desktop, and it takes a while for my app to run. I'd really appreciate some help.
When explorer is running, there taskbar will always be visible in some kind (even if it's a small border).
If you want to achieve something like a digital signage solution, you may replace the shell. Changing the shell will also provide some other benefits (most popups / balloontips won't occur anymore).
Be aware that this configuration is effective for all users on the system.
Path to the shell is available at
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell
Update:
Just to hightlight:
It is indeed possible to have custom shells per user (see comments).
This is done by specifying a custom location of the shell path that is located in the registry for a given user.
Yes, you can totally disable the taskbar in Windows 10 but it is only temporary until you hover your mouse around the taskbar area.
Here's a tutorial: how to hide the taskbar in Windows 10

tray icon doesnt appear when app is run from process.start

I have a C#/winforms application that runs minimized to the system tray. If I double click the EXE for this app it runs as it is supposed to, I see the process in task manager and the icon appears in the system tray. I also have a windows service which acts as a watchdog for the other app. If the winforms app gets closed the service restarts is using process.start
If the app is started from the service using process.start, firing off the same EXE file the process runs but the tray icon doesnt appear.
Just to be clear the winforms app puts the tray icon in place not the windows service.
Any idea why the app would react differently to a process.start than to a double click?
Edit: I may have partially answered my own question. The service is running as local system. Not sure some run as local system would be able to add an icon to my users system tray in the same manner a double click would. Does this sound like I am on the right track?
Yes, you're on the right track. Services run in a different session (session 0). If they open a window (which is highly discouraged), they are now called "interactive services". In that case, Windows pops up a dialog (see MSDN blog for a screenshot).
Similar things probably happen to the tray icon. Since you don't have a window, you don't get the popup dialog for interactive services, but the tray icon still exists in session 0, so you cannot see it.
If you're on Windows 8, interactive services have been disabled (MSDN) completely.

Main program window sometimes hides behind previous window when opening from installer

I have tried two installers - Setup2go, and Installmate Builder, and I have the same problem. At the last window of the install, I select the option to "Open program after installation finish", and sometimes (about 10% of the time?), my (Winforms) app's main window will open behind the Windows Explorer directory window I used to open the installation exe from.
The frustrating thing is - I am having trouble reproducing the problem reliably (the problem seems to occur around 10-20% of the time). I am using Windows 7 if that makes any difference. To clarify, if I open up the executable directly (rather than from the installation exe), the problem never occurs.
My knowledge on this kind of thing is limited - I recall a similar frustration happening with the MessageBox from this question
Any ideas?
It does not happen when you launch the app directly from installer because the shell allows it to “steal” the focus. When you launch it from the installer, the last interaction happens in the installer app. The system prevents the new window from stealing the focus from your installer. If installer window closes, then the explorer window which you used to start the installer is activated. Since the switch of the foreground window happened recently, the system does not allow to change the foreground window.
On the other hand, if your application window is shown before the installer window disappears from the screen, the the app will be placed below the installer in the Z-order; and when the installer window is finally hidden, the application window is activated.
So it's all related to timing between showing and hiding windows.
Although I am not expert in this area. You can use message tracers and WinAPI calls tracers like Spyxx which can give you more details on what happens in the system and why the new window of your application is placed below the Explorer window.
Make sure the window's title isn't changed, until the last possible moment. I moved the Text = "blahblah" line out of the Form_load event, and into the Form1_Shown event, and now the hidden taskbar icon problem has vanished. Also, the window doesn't flicker when it's loading.

Programming a windows service

I have started prgramming a windows service. I have added a notify icon from the toolbox.
It has the small notify icon that appears in the systray as a member of those icons.
It works so far.
So far I have a blank form. I have used the DoubleClick for the notifyIcon to bring up
the form (I will use the form for something later).
Now I have a list of things I want to accomplish to make this work like a true windows
service.
First of all, if possible, I owuld like to remove the maximize and cancel button on the form.
Most windos service apps that I have seen offer the ability to close the app by right-mouse-button clicking on the notify icon which brings up a menu of options.
I see in the properties of the form under Misc there is an CancelButton. But I do not see how do deactivate it. In the Properties of the forum I see under Window Style there is a ControlBox option that, if I turn to false, all three buttons, (minimize, maximize and cancel) go away.
These are not what i am looking for. I would not like the option for them to resize,
maximize or close the form here. I suspect people will close the box intending to
make the box go away while still wanting the app to run.
Under the "Focus" caption in Properties, there id "Deactivate". I have created my own
event/method/function for this and in debug I noticed that when you click on the x-box in the upper right corner, this function is called. The problem is that after the function is
over, the app closes anyway. How do I over-ride this function?
Secondly, how do you catch the right button click event on the notify icon in the
systray?
I can see how to create events for "Click" and "MouseClick" etc. but how so I determine
which button was click?
Using the right buton click is how such programs know when to pull up a menu. So I would
like to know how to do this as well.
Windows services should not display notification icons, nor show forms. You'll find out very soon that post Vista they are explicitly forbid from doing so.
You need to split your application into a user program that may show an icon in the notification tray and shows forms, and the service. They need to be distinct processes and communicate via IPC (shared memory, named pipes, sockets etc).
As to how to react to a righ-click on the notification icon question, you simply need to assign something in your designer to the ContextMenu property:
The menu is shown when the user
right-clicks an icon in the
notification area of the taskbar.
Shortcut menus also are known as
pop-up menus.
Standard Windows services do not run with any user interface at all. Generally speaking, your Windows service project type in Visual Studio won't contain any UI components whatsoever.
The UIs you see when working with other services are secondary applications designed to manage those services. Those may run in the system notification area ("tray"), or may run as minimized windows, may be MMC snap-ins, or may be separate applications the administrator launches on an ad-hoc basis.
As an example, SQL Server runs as a service, whether or not Management Studio or any of the other ancillary UI apps are running.
In any event, the user interface "component" of a service needs to be an entirely separate application. This is particularly important in the post-Vista world, for reasons cited by Remus Rusanu. You'll create a separate WinForms project to do this, and have it send messages to the service to control. (This may include the basics such as start, stop and restart; it usually also includes other service-specific commands.)
You may want to consider reading the following other questions here on StackOverflow for some guidance on the standard Windows Service/UI helper application pattern:
What can Services do under Windows?
What is the difference between a windows service and a regular application?
Creating a user interface for monitoring and interacting with a running windows service
Running an exe from windows service that interacts the the user’s desktop
Why do forms fail in Windows Services

Categories