Balloon Tooltip using Windows Service C# - c#

I want to open a balloon tooltip using windows service.
I can do it in Windows Forms. Is it possible using windows service ?

I have implemented this service before and used a named pipe. Basically you create two applications.
A windows service projects which acts as the Named Pipe Server
A winforms application with a tray icon, a balloon and a Named Pipe Client
The windows service pushes messages towards the clients that are connected, could be multiple users on the systems running the winforms app.
The winforms app listens to messages on the pipe. Once the message comes in you can make the balloon pop up.
Here is a cool test project: https://www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes
Happy coding!

Not directly. A windows service does not run in the user's session, it runs in its own special "Service Session". Tooltips that show up in that session don't show up on the users desktop.
The way to get around this normally is to have a 2nd program that starts with the user's login and is not visible in the taskbar. That program uses some form of IPC (for example WCF) to talk to the service, the service can then tell the helper program to show a notification as needed.

Related

Proper way to handle Windows Service Tray App / NotifyIcon startup

For the record, I want to point out two things:
I know how to create a Windows Service, I know how to create Tray applications and how to communicate with my Windows Service
I have read countless articles on this subject, almost all of them suggest hacks, putting applications in the Startup menu, (old) interactive desktop services, startup scripts etc. I also found very resources for the subject dated after 2010 (aka light years in the world of technology)
What I'm looking for is the proper way to make sure that when my service is installed, every user gets a nice icon in his tray whenever he/she logs on to his/her computer. This is slightly more complex than it seems, and most of the hackish solutions won't work anyway (not that I'd want to use them anyway).
What I want to achieve is twofold. I want to know how to:
Start the Tray application WITHOUT modifying any user settings. This means not adding anything to the user startup, not modifying the registry, no startup-scripts or whatever. My company doesn't have fixed seats in almost all of its departments. Any user can log on to nearly every workstation at every time. Ideally the Tray application would be launched from the service detecting a user logging on or the shell being started, and then spawning an instance of the tray application for that user.
I'm also looking for a way to handle the startup of the service. For example, when I start up the service and multiple users are logged on to a single machine (which is entirely possible), the service should spawn a tray application instance for each of the users with an interactive logon. This is especially important should the service need to recover. The same goes for when the service is stopped or restarted.
Just to give you an idea, the application I'm writing consists out of a Windows Service, a Tray application that gives feedback to users via notifications and allows them to start op a configuration program that also contains additional information for them, and finally said configuration program that communicates with the service via named pipes. It's all very simple.

A Windows Service should load a form at startup

How can I load a 'login form' in OnStart event of windows Service?! I know windows service is incompatible with UI. but I need to do this without using windows startup..
Is it possible? and how?
Thanks a lot.
How can I load a 'login form' in OnStart event of windows Service?
You cannot do this, because Windows services cannot display a user interface.
I know windows service is incompatible with UI.
Oh. You already knew that. Good.
but I need to do this without using windows startup..
This does not change the fact that it is not supported and will not work.
Is it possible? and how?
No, because:
windows service is incompatible with UI.
So what do I do!?!
The real answer here is that your design is wrong.
If you need someone to log in to your application, you should not be creating a service.
Just make a standard Windows application (e.g., using Windows Forms or WPF) and set it to start automatically when any user logs on to the computer. This can be accomplished easily by adding a shortcut to it to the All Users "Startup" folder.
Then, when your app runs, you can display whatever UI you need to, without the limitations of a service.
If you need to combine UI interaction with a service, you ought to write two programs - the service, which exposes some kind of API, and a client program that interacts with that API (using whatever IPC mechanism you want to choose)
Just remember that multiple users can log onto the same machine, so you ought to write everything to cope with multiple instances of the client program running at the same time.

Can you run WebBrowser under a WCF service?

I'm currently trying to move over a screen-scraping program (c# forms application) to a WCF service.
The screen-scraping program uses WebBrowser to grab info off several pages for which there is no API. I would like to know if you can run WebBrowser in a service let alone a form. I'm currently developing on XP to be release on Server 2003.
Currently when running unit test, I can only see the WebBrowser if it was made on the "Unit Test" side and even then I need to manually pop up MessageBox'es to get WebBrowser to stop from not navigating with a blank screen.
The program is being moved and split up since we are having multi-threading issues.
You would be better off using a headless browser like Phantom.js: http://www.phantomjs.org/. It offers significant features and has no problem being executed wherever you need like a regular command - line program.
In thinking about this, realize that each instance of the WebBrowser control is actually an instance of Internet Explorer. Your question then becomes one of having a service start multiple instances of Internet Explorer.
But Internet Explorer is an interactive application. It expects to control the keyboard and mouse when it has the focus.
Which keyboard and mouse do you want it to control when running in the server?
How many keyboards and mice does your server have?
You could find some way for the service to launch a Remote Desktop connection and start up your Windows Forms application. You could then have your Windows Forms application host a WCF service, and the two services could talk to each other. I have seen this sort of thing done when it was necessary to automate a specialized interactive program which could not be made into a service.

Implications of Minimizing to System Tray

I have an UI application that serves several functions (<800KB). I wanted to allow minimizing it to the system tray, and continue to decode data coming from the serial port and sending network messages.
Can I simply hide the main form and create a NotifyIcon in the system tray, or are there other considerations for system tray applications? Does the application use less resources while hidden? Or is it best to make a light version of the application for the system tray (with duplication of code)?
My application does what 2 different applications do (related functions). I'm trying to foresee the implications before I finish coding it.
I've written a couple apps that use NotifyIcon. Putting it in the notification area (system tray) isn't anything special. It's just not visible on the toolbar anymore.
IMO best way in your case is to make windows service that will decode data from serial port and send messages. And other winforms app that will only set preferences and watch service state, that one can go to tray. Maybe you don't really need this tray app, just windows service, you can set preferences trough config file and watch state trough EventLog.
Of course if is possible to run from windows service, eg. your serial port and network code doesn't need logged user or desktop.

Windows services with windows forms in the same process

I have a c# application that runs as a windows service controlling socket connections and other things.
Also, there is another windows forms application to control and configure this service (systray with start, stop, show form with configuration parameters).
I'm using .net remoting to do the IPC and that was fine, but now I want to show some real traffic and other reports and remoting will not meet my performance requirements. So I want to combine both applications in one.
Here is the problem:
When I started the form from the windows service, nothing happened. Googling around I've found that I have to right click the service, go to Log on and check the "Allow service to interact with desktop" option. Since I don't want to ask my users to do that, I got some code googling again to set this option in the user's regedit during installation time. The problem is that even setting this option, it doesn't work. I have to open the Log On options of the service (it is checked), uncheck and check again.
So, how to solve that? How is the best way to have a windows service with a systray control in the same process, available to any user logging in?
UPDATE: Thanks for the comments so far, guys. I agree it is better to use IPC and I know that it is bad to mix windows services and user interfaces. Even though, I want to know how to do that.
Two separate processes that communicate using your technology of choice. Services with UI is a bad idea. Don't go down this road - you'll regret it.
I've had very good results having service communication through a simple socket connection - document your service protocol well, keep it as simple as possible, and it'll be easier than you think.
In practice you should not couple your service with the management UI.
I agree with Greg. Perhaps you could examine a different IPC mechanism. Perhaps use sockets and your own protocol. Or, if your service control app can only control the service on the local machine, you can use named pipes (even faster).
Here is a way mixing up Services and Forms
http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx
I figured out how to do this from this article (click on the "Change" link in the Methods table).
string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
object[] parameters = new object[11];
parameters[5] = true; // Enable desktop interaction
service.InvokeMethod("Change", parameters);
}
I have the solution in a few steps, this is the plan
we are not going to create a service project with a a windows form, instead we are going to create a visual studio solution that contains a windows service project, a windows form project and a setup project.
The idea is to have a database or a file or anything you are comfortable with storing data in which you would store the parameters your windows service will always use to run. So your windows service and your windows form application should be able to modify and retrieve data from it.
To the Main Form Of Your Windows Application drag and drop a NotifyIcon on the form, in the properties tab, browse and select an .ico image(You can sreate one in visual studio but that is another topic you can get on google or contact me) That it will display in the system tray when you run the application and the main form is active or shown, try it, run the application.
Add both of them as outputs in the setup project of the solution. To Add a project to a setup project they must be in the same solution. Right click the setup project in the solution explorer, highlight add and then select project output, add the windows service and the windows form outputs and you will see them in the solution explorer under the setup project.
adding a windows service goes further than this but that also is another topic google it
Creating shortcut for the windows application and adding it to the startup folder is also another topic google or contact me.
NOTE Program your form in such a way that the close button doesn't show and the form goes Me.visible = false and double clicking the icon in the system tray is the only way to set me.visible=true.that way anytime the computer starts up, your windows form application is also started and visible is immediately set to false but since it has a notifyicon with an icon image, it will show in the system tray and double clicking it makes the form visible to edit the settings that you are storing for the service, the service also starts automatically since you would have set it in setting up the service in the setup project.
my mail is iamjavademon#gmail.com for a better illustration using screen shots And explain in full
It is very simply - your need to create one thread for perform application events.
Like this( source code for C++ with CLR, but your can make this in C#):
ref class RunWindow{
public:
static void MakeWindow(Object^ data)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew TMainForm());
};
};
And create thread in main
int main(array<System::String ^> ^args)
{
bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");
if (bService)
{
System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
thread->Start();
ServiceBase::Run(gcnew simpleWinService());
Application::Exit();
}
else
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew TMainForm());
}
return 0;
}
The main problems with interactive services are:
Security - other process could send it messages through its message pump, thereby gaining access to a SYSTEM/LOCAL process.
Incompleteness - an interactive service never sees shell messages, hence it can't interact with Notification Area icons.
We regularly use TCP and UDP connections to pass info from services to other exes, and, in some cases, MSMQ.

Categories

Resources