Alternative to "Allow service to interact with desktop"? - c#

I have a windows service (C#) installed on a server that launches every 10 minutes an executable file (C#) to process some images from one directory to another. No interaction is required with any user. Nevertheless, since the executable file as an output window, to make the service run I have to enable the "Allow service to interact with desktop" checkbox which is considered as an insecure and bad practice. How would I go about this problem? I like to have the executable separated from my windows service because
it makes it easier to debug and
doesn't require a full windows service redeploy.
sometimes I use the same windows
service to launch several
executable files at different
intervals (but all related to the same
project).
EDIT:
When the interaction with the desktop is not enabled, the console application does not get executed correctly and the following error appears inside the Windows Logs:
Faulting application myapp.exe, version 1.0.0.0, time stamp 0x4b8304c3,
faulting module KERNEL32.dll, version 6.0.6002.18005, time stamp 0x49e03821,
exception code 0xc0000142, fault offset 0x00009eed, process id 0x10ec,
application start time 0x01cab736950a64b5.
Once the desktop interaction is enabled, application gets executed normally.
Any thoughts?
Thanks a lot for your time.

If you are using Vista and later and you don't really need any interaction with the user, but have an interactive exe to execute, the Session 0 isolation feature should help alleviate some of the concerns about the 'bad practice' on having a service interact with the desktop (which in Session 0 has no physical console).
This Session 0 isolation would prevent unprivileged users from performing Shatter Attacks on your service as they get their interactive desktops in different sessions. Shatter attacks are the main reason why this 'interaction with desktop' was considered bad practice and if you are using Vista or later, it should be ok if you cannot avoid it (or will have to spend too much effort to do it).
So, if things are working fine as they are, you are probably ok.
Of course, after an OS update, things might just stop working, so it is probably better to prepare to move the dependency on interactivity out, as you don't really need it.

I know this is a bit late but in this circumstance i would use the task scheduler and not bother with the windows service. The task scheduler has a comprehensive set of scheduling options and can run console applications without issue.

If you can, I would recommend rewriting your executables that handle the move to not use an output window. If they are standard, console applications with no output, you can execute them from within a service without requiring "Allow service to interact with desktop". This provides you all of the benefits, without any changes to your service.

Is the subprocess just a console application? I've not written Windows Services, but I think perhaps just starting the subprocess without a window would be sufficient. Use the overload of Process.Start that takes a ProcessStartInfo and set ProcessStartInfo.CreateNoWindow to true.
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow.aspx

Related

Is it good to have windows service or console application?

I have a tasks table in my db. I want to read data from this table and run tasks. Which one is better whether to have it as windows service or a console application running. The server on which this will be run will not be shutdown
You most likely want to use a windows service.
Benefits:
You can control the user (and the rights associated with this user account) which starts the process
An automatically started process means the desktop need to be on, not user logged, for the service to run
A policy on failure can be defined (try to restart n times run a specific program if fails)
A dependency can be defined (if you depend on other sevices)
You can wrap your script in an invisible window
You can easily start/stop/restart the script (net start <scriptname>)
Quoted from here: What is the benefit of developing the application as a windows service?
A running console app is not an option, as the others have stated.
If you just want the task run every x minutes the simplest option is a scheduled task using a console application.
A windows service has it's benefits, but is a little bit more complex to implement and deploy. However if your app needs to be 'always on' (e.g. need to react to external triggers, listen to message queue, ...), a windows service is the only option. As the others have said, the services infrastructure also provides more management capabilities, built-in integration with the event log, restart and failover options...
Windows service, because it does not require logged-in user.
I would say; Windows Services.
In that case (among other things) you don't need a user to be logged in, you can configure it in a matter to restart automatically if it shuts down for some reason and you (could) have extensive rights throughout the system.
Windows service generally. Console app will need to be restarted if the server reboots while a windows service can start automatically.
You should look at: https://github.com/thedavejay/Self-Installing-Windows-Service
It allows you to debug as a console application and then install it as a windows service.

Windows program that always runs

I have a requirement that a Windows Forms C# .NET 2.0 program running in user-space (not a service) must always be running. As I'm not infallible and make coding mistakes, I wanted to know of any extra safeguards I could use to ensure this requirement is met. The things I've been thinking of are TaskScheduler to check it every 5 minutes, A stub watcher or a secondary process. Are these good / bad ideas?
Thanks,
Richard
EDIT: The reason I didn't use a service (the obvious and sensible answer!) was the program runs in a kiosk type environment and has has a heavy GUI component. The service option didn't work well across Windows 2000 - W7.
EDIT: The second reason not to use a service was the app needs internet access and on some of our customer sites, proxies are set up to only allow specific users (not the local system account) so it would be tricky to ensure access if multiple users log onto the machine.
Task scheduler is a cheap solution for this which does work. I use this to keep our Perforce Proxy server running (had some issues with the service), and so far there's been no problems - though now I've said that the server's probably exploded!
However, the most complete solution is a Windows service which invokes your app. You can make that service catch error return codes from the app, restart it on failure and notify you by email, which may help you diagnose and fix those issues. I think the Task Scheduler does something similar but it won't be able to provide as much insight into your application as a custom service.
If you're unsure of how to do that, then something like this should work:
http://www.codeproject.com/KB/install/csharpsvclesson1.aspx
There are three approaches that you can take:
Heartbeat Message.
A heartbeat is useful in a distributed application and is simply message that is sent (from let say a client to server) to confirm that it is still healthy/running.
Manager Process
A stub program, implemented as either a user process or a service. It launches the main application, monitors any unhandled exceptions, reports errors, and restarts on failure.
An exception guard on the entry point.
A try-catch-all in the application entry point.
I would recommend either of the first two options; the third option, the try-catch-all, is a particular nasty hack for the lazy and inexperienced programmer (IMHO).
I have successfully used both heartbeat and manager process in a large distributed application.
UPDATE
As for ready-to-go™ restart managers, take a look at the Windows API Codepack as discussed in Emmanuel Istace blog post (http://istacee.wordpress.com/2013/09/21/automatic-recovery-restart-in-net-application/).
You can install the package from https://www.nuget.org/packages/WindowsAPICodePack-Core/

C# application keeps freezing on remote

I am developing a C# application (.Net 3.5, Win Forms) which is run on a server, and is accessed by Users using remote desktop. The application keeps freezing on seemingly random occasions on the remote machine (i.e. all GUI components turn to white, task manager reports the application to be not responding), but not when run locally (I'm not entirely sure about that, but failed to reproduce the freeze on my machine).
Has anyone experienced such behavior in his apps that are accessed remotely? What debugging strategy would you suggest? Do I need to consider something special when developing Win Forms applications that are accessed by remote desktop?
EDIT: some notes about the application and the freeze: The application does not recover from the freeze. Also, the freeze does not happen (or did not happen yet) during user interaction, but in between log ins to the remote machine. The application monitors a CFD solver, so it's doing things even when no one is using it.
UPDATE:
We did infact implement detailed logging, writing every function call to a file with a timestamp. Unfortunately, the results were not very conclusive. I.e. the last function call logged always returned correctly. Also, there were some background timers still running, even though the application appeared frozne (GUI completely white etc.). After some trouble we managed to have a look at a crashdump in WinDBG. On the system thread we found a call to OnUserPreferenceChanged() and further up to Invoke.WaitOne(). We can't say for sure yet, but it seems to be the issue decribed in these articles. As a quick fix, I installed a dummy handler to the event mentioned. I'll report how this works out.
UPDATE 2:
As it turns out, a Log In to a remote machine fires several OnUserPreferenceChanged() events. So it was indeed the suspected issue. The fix turned out to be not so easy though. I would have expected that an IllegalCrossReferenceException is thrown everytime a background thread tries to modify a control that was created on the system thread. This does not seem to be the case. I named my system thread and before each access to a control I asserted that the current thread name is the system thread's name. In various places this assertion failed (e.g. in a callback from a timer), but no exception was thrown. After using proper delegation at these places, the freezes stopped. The application runs nonstop for some weeks now and my users are happy again ;)
I do not think the freeze has anything to do with remote desktop. Adding logging was a good suggestion. I have a few suggestions, but without knowing the details of you application I can't get too specific.
The simplest suggestion I have is to check the memory useage and CPU usage in task manager when the freeze occurs.
If adding detailed logging is not an option, add just enough logging to know WHEN the application freezes. This could simply be a thread in the application which writes a timestamp to a file once a minute. Then you can see if there is any pattern in when it freezes, such as after a user has logged off, or when some of the data which you are monitoring changes, or at a certain time each day, or after being online for a certain amount of time.
A final and very hacky solution is to write a small watch dog application. This application's only job is to periodically check on the main application to make sure it is still responsive. How you dow this various drastically based on what your application does. If the watchdog sees the the main application has stopped, it can kill the thread for the main application and re-start it from the binaries.
if your using application streaming your server could be slowing the connection or waiting for packets that are dropping this can create this if your physical using windows remote desktop then there is your problem intense applications are not supposed to be run though remote desktop
AFAIK, there is no difference. Additionaly, I never experienced such a problem. I suggest, you try the following:
Extend your application with extended logging, to see what the users are doing when your application freezes
Check the network connection that is used to connect to the remote machine
Check the CPU usage during the freeze
If the freeze is for an extended amount of time, try to do the following:
Reproduce the freeze via remote desktop.
Go to the machine you just reproduced the freeze on and log in directly and see, whether the application is still freezed
If it is windows 10 version 1903 plus version. Then probably its the issue of windows. Please try the following settings:
Have read various blogs and concluded that the GPO has to force to use XDDM rather than WDDM. The issue is observed with windows 10 version 1903. Currently tested the workaround on machine NDT-61. It is working fine. Please practice the same for respective environment and let me know if some issue is faced.
Steps to Follow:
Open Group Policy Editor
Explore Administrative Templates
Explore Windows Components
Explore Remote Desktop Service
Click Remote Session Environment
Under Remote Session Environment Disable Use WDDM graphics display drive for Remote Desktop Connections
Note:
This policy setting lets you enable WDDM graphics display driver for Remote Desktop Connections.
If you enable or do not configure this policy setting, Remote Desktop Connections will use WDDM graphics display driver.
If you disable this policy setting, Remote Desktop Connections will NOT use WDDM graphics display driver. In this case, the Remote Desktop Connections will use XDDM graphics display driver.
For this change to take effect, you must restart Windows
Observation:
The policy settings are only available in windows 10 version 1903 and plus [ideally since when the issue started].

C# ClickOnce deployment for Windows Services?

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.

Unable to execute a program from a service

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.

Categories

Resources