Use C# Console.WriteLine in a Windows Service - c#

If I call Console.WriteLine in a Windows Service, are the logs written anywhere in a sort of "hidden" console?
I'm NOT interested in finding out where Windows Service writes Console.WriteLine's logs, I'm just wondering if the service still writes the log in a background console (invisible to the user) when Console.WriteLine is called.

Services have no allocated consoles, stdout data will silently get dropped.
Unless of course at any point you attach something to it, like a debugger that hooks into stdout, in which case you'll start seeing your messages.

Related

XpsDocumenWriter hangs from Windows Service, but works fine when running from console

I have a Window Service that is used to perform various jobs, among them, one is to print a document that is generated through WPF. When running the console application, it works fine, but when running from windows service, it just hangs.
Let me explain a little bit the Window Service. In order to minimize any possible side effect, Windows Service is just a wrapper for the actual console. So, when Window Service is started (in its start method), there is a simple Process.Start call that calls the console, like this:
Process.Start("[path_to_my_console_exe]");
Now, when the code for printing is invoked it just hangs. I am using PrintDialog API to print a document. The call to print a document is simple:
var printDialog = new PrintDialog();
printDialog.PrintDocument(doc.DocumentPaginator);
When PrintDocument is hit, it will block the execution (method will never end).
So, I did a little investigation. Googling gave me some hints, so
I made sure that Windows Service is running with same permissions as is standalone console.
I made sure that Windows Service is running as x64 process, same as standalone console
I tried to debug the PrintDialog.PrintDocument method. I literately downloaded the code from referencesource and it gave me a new insight, but unluckily, that didn't solve the problem neither, it just pinpointed further which method is blocking the execution (it is XpsDocumentWriter.Writer method, line 460).
Now, after all this, I am sure it must be something regarding permissions. Although the Windows Service is using the same user to run as a standalone console app (admin user) it seems to me that is still doesn't have all permissions needed. Is there something special with Windows Service here? Am I missing something, is there anything else what should be set for Windows Service before running the console?
I solved the issue, so if anyone gets in the same situation, here is what happend.
For testing the app, I was using Microsoft pdf printer, so when running the console as a standalone app (not through the service), when Microsoft pdf printer is used it would show a dialog at the end to ask for the file name and location. That could work because I could see a dialog and press the button. But, when running the same Console, through Windows Service, and using the same printer (Microsof pdf) for printing it would just hang and the reason is the service property "Alow service to interact with desktop". This is by default false, so when registering a service, any user interaction won't be visible and in my case it was the exact point where PrintDialog hangs, because it is waiting for a user input to save the pdf. After changing to a real printer, it all worked as excpected.
Another way to solve this is to use different printing API, that could work without user interaction (by passing the arguments programatically).

Check for file existence OnStart() and then stop service [duplicate]

I have a service application written in C# and under certain circumstances, I would like it to terminate itself. This would happen after the service has been running for a while, so this would not be happening in the OnStart() event.
Everything that I have read so far suggests that the only safe way to terminate a service is through the Service Control Manager. My service runs as Local Service and does not have the rights to start or stop services, so I can't access the SCM from the service itself. Is there another way to self-terminate while still playing by the rules of the SCM?
Try ServiceBase.Stop().
If you want to terminate the service instead of stopping it (perhaps because the service has caught an otherwise unhandled exception) you can use Environment.Exit(1) (use another exit code if you want).
Windows will discover that the service has terminated unexpectedly. If the service has been configured to recover the recovery procedure will be used which includes options for restarting the service, running a program or restarting the computer.
What happens if you just let all the executing threads finish? I can imagine three possible outcomes:
The SCM notices, and decides you finished appropriately
The SCM notices, thinks you died, and restarts you
The SCM doesn't notice, and shows you as still running
EDIT: I suspect this answer is the best one really, but I'll leave this up (for the moment) just for the sake of interest.
Don't have the service run under Local Service. Have it run under a user that has the rights to stop a service.
Although the idea of self-terminating services is not the best of ideas. That very fact alone means that it should be an application, and not a service.

What can be the reasons why windows service OnStart is not called?

I've installed my serivce but cannot start it.
I get dialog window with the message:
Windows could not start the WU Distribution Service service on Local
Computer. Error 1053: The service did not respond to the start or
control request in a timely fashion.
And two EventLog entries: the first with the same message and the second one with:
A timeout was reached (30000 milliseconds) while waiting for the WU
Distribution Service service to connect.
My serivce class has default generated constructor with the only call to InitializeComponent() so nothing heavy.
Just to check how long OnStart runs I inserted Debug.WriteLine with times tamps and added TextWriterTraceListener with Debug.AutoFlush set to true.
No log file was created, thus OnStart was not called.
To be absolutely sure I just throw exception inside OnStart but still get no messages about exception.
I need to know what can be the reasons why OnStart is not called.
You'll have to debug to see what happens. You can add more prints, I would recommend eliminating complications and just write to a file stream instead of Debug listeners.
You can attach debugger to a running process, see How to: Debug Windows Service Applications, but that requires the service to be up and running. If it hungs at startup you still have a good chance because you can inspect the hung state and understand what happens.
If you need to debug service first moments of life then you'll need to graduate to a true debugger. See KB824344 How to debug Windows services, specifically the Configure a service to start with the WinDbg debugger attached, I usually use gflags, way more elegant than registry. You'll need to bridge a remote to your service attached WinDbg from your own session, see Remote Debugging Using WinDbg.You can debug managed code in WinDbg, is not exactly the posh experience VS is doing, but is the real deal on what the machine is doing.
An easy thing to test first is how does your executable behaves when started under the service account. If service is running as localsystem then use psexec -i -s.

Preventing Windows Error Dialog for Console App

I have a .NET service that monitors a windows share location for console apps written in Fortran, launches them, monitors STDOUT and STDERR, and copies output back to a shared location where it's processed by other services. A few instances wrote output that they were terminating, then the app appeared to lock up (it never terminated). I ran the app that failed with the same input on my local machine, and discovered that there was a memory corruption error caused by, I'm assuming, an attempt to deallocate the same memory twice. A windows error dialog was displayed. I determined that, even though my service was running these console apps as windowless apps, when the error occurred in the Fortran console app it continued "running" because there was no user available to click on the dialog.
Using System.Diagnostics.Process, is there any way to prevent the Windows error dialog? Is there a way to prevent it without making global registry changes? I don't want to turn off this behavior globally.
All I could find by googling this issue, is that the user either 1) Should write appropriate error handling (something that can't be done in Fortran code I don't own), or make changes to the registry (something that I consider wrong because I don't control how other users are using the server).

How can you attach a C# console application to a running windows service?

I have a windows service that generates logs as it does some execution. I also do console.writeline call for every log message I write into the log file. But since its a windows service the console.write line is not visible.
I want to write a C# console application program that can attach to my service (already running) and it could just show all console.writeline messages that the process (my windows service) is generating.
updated: The volume of log is very frequent ( 50 messages every minute) , I would prefer not want to crowd windows event log for this. Using a cosole window helps to look at logs and exit on convenience
Displaying a window from a service is not a good idea as you would have to find out the "correct" session (Windows allows several users to be logged on) and also requires the service to have access to the user's desktop.
Instead, it is probably easiest to change the Console.WriteLine calls into Trace.WriteLine. Then you can attach to these trace messages, e.g. by using SysIntenal's DebugView.
I think you'll struggle to attach a console to an existing service. Two easy options
write to the windows application log
write to a text file, which you can then open with wintail or similar
Re your update - number 2 would be best then.
You can make the service interactive, in which case you'll see the console window, but you'll always see it, and I think if you close it, you'll stop the service.
Alternatively, make your console monitor read updates out of the log file at a reasonable interval instead of trying to get into the service process directly.
I would suggest you to log messages to Windows Event Viewer, if don't have burning desire to show them on console window. This link would help you...
Send data via UDP and make a simple program to show the data.
You warrant and asynchronous operation and can even send to another host.
I used cygwin to tail on the log file thats created by log4net this seems to do the trick for me.
Thanks for all the help!
Or open the file with http://www.log-expert.de/ and tail away. You can even make it colorful!

Categories

Resources