Show status window from Windows Service - c#

I have a Windows service written in .NET with C#. I know from here: Launching GUI App from Windows Service - Window Does Not Appear. that I can allow the service to interact with the desktop. From Windows 7, however, I just get a dialog telling me "A program running on this computer is trying to display a message". The service is an update service (think Windows update) I wanted to pop up a dialog telling the user that an update is taking place and informing them of the progress.
1) Can I display a window from a service in Windows 7?
2) Can I detect from within the service whether it can interact with the desktop?
Thanks,
Scott

You can't display UI from a service.
The normal approach to this problem is to run a standard app in the user's desktop and have the service communicate with that app using your preferred form of IPC.

Check out .NET Remoting.

Related

How do I create a tray-only windows service controller using .NET Core?

I want to make a windows service worker, as described in this walkthrough: https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service.
I also want the user to see a tray icon to manipulate the service. To do this, I will create a second executable which runs in the user context and communicates with the service.
How should the app communicate with the service to perform things like checking the service status, restarting the service, etc.?
Apparently this could be done with .NET Framework by using a ServiceController in a user-run app to talk to the service (which I guess used to be a ServiceBase instead of a BackgroundService).
What is the equivalent "ServiceController" class, when using the newer BackgroundService/service worker model of .NET Core? Does ServiceController still work?
A typical pattern is to have two apps. You can't really do this. as services run in a different window station than the logged in user, so you can't have a system tray icon for those users. This is from the Microsoft docs https://learn.microsoft.com/en-us/dotnet/framework/windows-services/introduction-to-windows-service-applications:
Windows Service applications run in a different window station than
the interactive station of the logged-on user. A window station is a
secure object that contains a Clipboard, a set of global atoms, and a
group of desktop objects. Because the station of the Windows service
is not an interactive station, dialog boxes raised from within a
Windows service application will not be seen and may cause your
program to stop responding. Similarly, error messages should be logged
in the Windows event log rather than raised in the user interface.
The Windows service classes supported by the .NET Framework do not
support interaction with interactive stations, that is, the logged-on
user. The .NET Framework also does not include classes that represent
stations and desktops. If your Windows service must interact with
other stations, you will need to access the unmanaged Windows API. For
more information, see the Windows SDK documentation.
The interaction of the Windows service with the user or other stations
must be carefully designed to include scenarios such as there being no
logged on user, or the user having an unexpected set of desktop
objects. In some cases, it may be more appropriate to write a Windows
application that runs under the control of the user.
Here are a couple of links about how to write to the system tray I found on internet and other post. You'll need another application to interface with the service, since the service can't directly have an icon in the system tray for windows..
How can I make a .NET Windows Forms application that only runs in the System Tray?
and
http://msdotnetsupport.blogspot.com/2008/02/cnet-application-windows-system-tray.html
Way to communicate with the windows service could be as follows:
-Socket communications (TCP, HTTP, Websocket or other):
-Named pipes: this is a good option for communication between processes running in the same node:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx
-shared memory: this is the fastest
Other higher level, library like SignalR which uses
sockets

How to show bubble notification on status change (Start or stop) of windows service in windows10 in C#

I want to display bubble notification in system tray when my windows service start or stops in windows-10 , but after windows vista, there is no provision for the windows service to be interactive with the GUI or desktop, so how can I achieve this in C#??
Because a windows services cannot interact with the user-desktop, you should create a separate application (with autostart), that implements the bubble-notifications you like. I would create a simple WCF-Service in the Windows-Service so that your GUI can control the service an receive notifications.

Display Message box and windows form in Windows Service c#

I need to display Message Box and Windows Forms through windows service by using c#. Anyone Please help me. Thanks in advance.
You cannot (easily) do this directly from the service's process. As descibed here, there is a way to create an interactive service, that is able to send/process windows messages and display windows.
But: Since Windows Vista, all services run in a separate user session, named "session 0". Thus, all windows displayed by services, are displayed in that session. It is theoretically possible (I have even done that once, just for fun), to switch to this session and view these windows, but this would hardly be of use in real life.
My advice would be to create a separate gui application (maybe one with a nice tray icon), that communicates with your service via e.g. TCP/IP or a database. This application can then handle any required user interaction and do the appropriate interaction with the service's process.

show a windows form from a window service

i am creating a window service. my requirement is to display window form from window NT service on particular interval. For testing purpose , i just want to display the form on service start:
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("In OnStart -before form show");
Messager_Form obj = new Messager_Form();
obj.Show();
// System.Diagnostics.Process.Start("calc.exe");
eventLog1.WriteEntry("In OnStart -after form show");
// timer1.Start();
}
it not working. Neither form is showing nor calc process is running. i have found some links
showing pop up , but most of them suggesting WCF. isn't it possible without wcf. can anybody show me the way to achieve this.
Cant be done*. In later Operating Systems that won't work as Windows Services are disallowed from interacting with the Desktop - instead UI presented by Windows Services is shown in Session 0, a special logon session which is not normally visible to the end user.
What you should instead do is write a separate Windows Forms application which is always running, but not always visible (possibly have that application run at startup and have an icon in the notification area) and communicates with the Windows Service using some form of IPC
When the Windows Service wishes to display some UI to the user it sends a message to the application, which in turns shows the desired UI to the end user.
*or at least it definitely shouldn't be done
I am just referring to the answer given in another link in StackOverflow
How to communicate with a windows service from an application that interacts with the desktop?
Answer is :
Be aware that if you are planning to eventually deploy on Windows Vista or Windows Server 2008, many ways that this can be done today will not work. This is because of the introduction of a new security feature called "Session 0 Isolation".
Most windows services have been moved to run in Session 0 now in order to properly isolate them from the rest of the system. An extension of this is that the first user to login to the system no longer is placed in Session #0, they are placed in Session 1. And hence, the isolation will break code that does certain types of communication between services and desktop applications.
The best way to write code today that will work on Vista and Server 2008 going forward when doing communication between services and applications is to use a proper cross-process API like RPC, Named Pipes, etc. Do not use SendMessage/PostMessage as that will fail under Session 0 Isolation.
http://www.microsoft.com/whdc/system/vista/services.mspx
Now, given your requirements, you are going to be in a bit of a pickle. For the cross-platform concerns, I'm not sure if Remoting would be supported. You may have to drop down and go all the way back to sockets: http://msdn.microsoft.com/en-us/library/system.net.sockets.aspx
Checking the "Interact with desktop" box will work on Windows NT, 2000, XP and 2003 but thanks to Session 0 Isolation that setting no longer works as you may expect in Windows Vista and beyond. You want to think very carefully before developing an interactive service...

How to do things within a windows service?

I have an application, written by me in C#.net 2.0 - when the application is opened, a timer will check every 3 seconds for x. If x happens, it shows a warning in a windows form.
Is there a possibility to install this timer and the windows form call in a windows-service? So that the timer ticks every time a system is up and shows the message then?
No, it is not possible to have a service display a form. This is by design, since a service is supposed to run without a user interface
You can have a regular application that communicates with your service and displays the warning, but I don't know how exactly this is done.
IMO, you don't need a service, just create a regular application without a main form that runs in the background, performs your check, and displays a warning when necessary. You can add that application to the Run section of HKLM or HKCU, so that it is always started when a user logs on to the system.
Windows Forms cannot be displayed from a Windows Service. A Service runs only in the background.
You can have a separate Windows application that communicates with the Windows service and display warnings, information, etc.
To do this, the service runs on the LocalSystem account, and you have to enable the property for the service to interact with the desktop.
Services are forbidden from interacting with the desktop, including displaying windows or forms. In windows 2003 and XP you could work around the issue by marking the service 'interactive' and this would allow the service to display on the user session, but as of Windows 2008 and Vista this is enforced and services can no longer interact in any fashion with the user.
When services need to display anything, the solution is to split the logic into two separate processes, one being the service and one being a normal user process. The user process runs launched by the user, in its session (it can be launched automatically at session start up) and it connects to the service via some IPC channel (shared memory, named pipes, sockets etc). The service can then display anything it wishes to the user by asking the user process half of the application to display what it needs to display.
As others have said, remember that a windows service is supposed to be a background, never-interacting-with-the-user program. Many services run even when the user is not logged on -- how would they go about displaying a form when there's no desktop for them to display it on?
That said, it shounds like you're trying to shoehorn something into a service that shouldn't be a service. If you want something that runs in the background and still interacts with the user, look into making a lightweight system try application. In fact... here's a helpful tutorial:
Lightweight System Tray Application (NotifyIcon Based)

Categories