I am writing a windows service to process emails on a daily basis. This service includes a App.Config file, which has several parameters for the service to work accordingly.
Every time, the admin user has to go and change / add / delete the pair inside the section using a text editor.
I am planning to include a windows form to load all the pair from the section and thinking of doing any modification through the form.
All I would like to know is whether it's possible to have a winform inside a windows service and open it when ever the configuration needs to be changed? I know we can have a seperated windows application and load the App.Config file of the windows service. I just want to avoid having a seperate app for this.
If you have done something very similar to this, please share your thoughts!
Regards,
Sriram
That sounds like a security issue if nothing else.
A Windows service runs in a different context and account and cannot interact with the desktop unless specifically allowed when installing the service. This is not enough of course so you'd also have to have the service running under the same account that is running the desktop - this in itself is really bad design and not something I would recommend.
You could also have the service executable decide what to do during launch, a common pattern is to have it spawn as a console application when debugging to simplify development. But then you'd have to stop the service and launch the service executable manually interactively to get the UI behaviour.
In any way, a separate configuration tool is the way to go.
Related
I have a Windows Forms Application which runs on a server. I need this Application to always start automatically. Even if the Server just gets restartet and nobody logs into it the Application should run.
So the solutions with Registry don´t work here. I than read into Windows Services but it seems like I can´t start a WinForm Application with it.
Does anyone have an idea how I can achieve this automatic Start on Server startup?
The way we do things like that is that we create a Windows Service which runs without the need to have anyone logged in, and then if there is a need we have a separate GUI application (WinForms in your case) which interacts with the service, when needed.
The communication between the GUI application and the Windows Service is usually done by means of named pipes, but if you can get away with something simpler, like the GUI application saving a configuration file for the service to pick up, you might make it easier for you.
I’m working on a windows app composed of two parts:
An agent, running in the background.
A main application with a window to start/stop the agent and configure it.
What I understand is that I should use a “windows service” for the agent.
But I’m not sure how this is supposed to be packaged? (Can I have these two parts in the same .exe?)
And how the agent and the main application can communicate (should I use a shared file? Can my agent have a private folder to work in?)
I’m looking for some architecture advices basically
Running the agent as a service is probably the best way to go. It'll run without anyone needing to be logged in to run it, and Windows provides extensive monitoring support for services. You can use the sc command to install, start and stop a service, and it even supports controlling services on other machines if you've got the appropriate permissions.
In order to have your gui communicate with it you could look at using WCF. It will allow you to define your interactions with the service as C# classes and will save you having to worry about checking shared directories or looking into a shared file etc. This approach will also make it easy to support multiple clients at the same time, whilst something like a shared folder approach will make this difficult.
You will need to have to separate .exe files, one for the service and one for the windows application. You can package these are two separate MSIs within Visual Studio, the benefit here is that if you need to move the service (for whatever reason) you are not then also packaging up the Windows App and leaving it where ever you install the service.
There are different ways you can have them communicate without getting massively complex. you could read from a text file, as you've suggested, but this could cause locking problems. When I've had to do similar I created a simple database in SQL (or any brand of database you wish), and have the Windows App insert / update configuration options to a table, and the service then reads the table to get its settings.
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.
What are some best practices for being able to deploy a Windows service that will have to be updated?
I have a Windows service that I will be deploying but might require some debugging and new versions during the beta process. What is the best way to handle that? Ideally, I'd like to find a ClickOnce-style deployment solution for Windows services but my understanding is that this does not exist. What is the closest I can get to ClickOnce for a Windows service?
A simple solution that I use is to merely stop the service and x-copy the files from my bin folder into the service folder.
A batch file to stop the service then copy the files should be easy to throw together.
Net stop myService
xcopy \\myServerWithFiles\*.* c:\WhereverTheServiceFilesAre
net start myService
I have a system we use at work here that seems to function pretty well with services. Our deployed system has around 20-30 services at any given time. At work we use a product called TopShelf you can find it here http://topshelf-project.com/
Basically TopShelf handles a lot of the service related stuff. Installing, Uninstalling etc all from the cmd line of the service. One of the very useful features is the ability to run as console for debugging. You build one service, and with a different cmd line start you can run it as a console to see the output of the service. We added one custom feature to this software that lets us configure profiles in advance. Basically our profiles configure a few things like logging, resource locations etc so that we can control all that without having to republish any code. All we do is run a command like
D:\Services\ServiceName.exe Core.Profiles.Debug or
D:\Services\ServiceName.exe Core.Profiles.Production
to get different logging configurations.
Our build script creates install.cmd and uninstall.cmd scripts for each of our services all we do is copy the files to the server and run the script. If we want to see debug output we stop the service and double click the exe and we get a console to read all the output.
One more thing that topshelf has which we don't use because its not necessary is the concept of shelving (there is documentation on this website for this). This allows you to update the service without having to "restart" but you still need to copy the files manually unless you build an automated system for that.
However, my suggestion if you need 100% service availability is to have a redundant system. No matter how you configure your service for updates you cannot avoid hardware failure causing downtime without an automated failover system. If said system was in place my recommended update strategy would be to turn off 1 node, update, test, turn on turn off the other node, update, test and turn the 2nd node back on. You can do this all of course with a simple script. This may be a more complicated system than you need but if you can't take a service offline for a simple restart that takes 5 seconds then you really need some system in place to deal with hardware issues because I can guarantee it will happen eventually.
Since a service is long-running anyway, using ClickOnce style deployment might not be viable - because ClickOnce only updates when you launch the app. A service will typically only be launched when the machine is rebooted.
If you need automatic update of a service then your best bet might be to hand-code something into the service, but I'd forsee problems with almost any solution: most install processes will require some level of user interaction (if only to get around UAC), so I can't imagine this would lead an answer that doesn't involve getting a logged-on user in front of the screen at some point.
One idea that might just work is active-directory deployment (or some similar equivalent). If your service is deployed via a standard MSI-type installer, AD allows you to update the application silently as part of the computer policy. I suspect you'd have to force the server to refresh the AD policy (by rebooting or using gpupdate from the console), but other than that it should be a hands-off deployment.
I would suggest using the "plugin" approach on this, that is, using the Proxy Design Pattern.
While using this pattern, an independant thread may verify over a folder for updates. You will need to use ShadowCopy over your assembly deployment. When your service update-thread encounters a new version of your service, it shall unload the current production assembly and load the new version, without stopping the service itself. Even more! Your service should never notice the difference, if there is no breaking code within your assembly.
I would suggest to create a normal setup project, and add the windows service project output in that setup project.
For more information please refer to http://support.microsoft.com/kb/816169.
I have a Windows service which I want to periodically execute an external program. I'm currently doing this the usual way
Process program = Process.Start(#"C:\mpewatch\db_parameters\DBParameters.exe");
This doesn't seem to be working. I'm executing this from a separate thread which is started in my service's OnStart handler. Is there any conceptual problem with this? Is it not possible to execute external programs from a service like this?
You can execute external programs from a service, but there are security issues. For example, your service may be running under an account which does not have read access to the folder where the external program resides, even if your interactive account does have that access.
For test purposes, try to configure the service to run under your interactive account. If the program is invoked as expected, then the problem with the original account is that it does not have sufficient privileges to run the program.
Your question didn't indicate the operating system.
On Windows XP, you can configure your Windows service to interact with the desktop by opening the service control panel, double-clicking your service, selecting the Log On tab, configuring the service to run as local system, and checking the checkbox. It's pretty straightforward. You might try testing with something like Notepad.exe just to see if you can get it working.
On Vista (and presumably Windows 7), however, you may be out of luck. I have read that the ability for Windows services to interact with the desktop has been removed in Vista. I forget what the terminology is, but basically services will run in "shell 0," whereas users will occupy "shell 1". User applications will be able to communicate with services and vice versa using technology like WCF, but services will not be able to communicate directly with the desktop. For example, any error boxes that pop up will have to be dealt with by swapping to "shell 0." Again, this is based on something I read a few months ago, and I haven't gone looking at it again. For me, I've structured my Windows service to be configured using WCF via a front-end app.
I'm sorry I don't have a link for you, but if your service will eventually have to migrate to a newer OS (or you are already there), this is something to check on.
Another critical consideration with Windows Services is that there is no GUI. Technically, there is an option to allow the service to interact with a local GUI, but you will not see it. This is due to services running as the Local System user.
Within a service, any modal dialog box (OK, Cancel, etc) is considered an error.