Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run console application from Windows Service?

I have a windows service, written in c# and I need to run a console application from it. Console application also written in c#.

Console application is running fine when it is run not from windows service. When it is ran from ws it doesn`t do anything it should and as it should work for 10-20 seconds I see in debug code is executed at once.

I`m starting my console app with the following code:

proc.Start(fullPathToConsole, args); proc.WaitForExit(); 

the path to console is right and when I`m trying to run it from the cmd or just in explorer (without args) it works fine. But after running with the service I see no effect.

I already tried to go to service properties and give it access to desktop and run under both system and my user (also specified in service properties). All remains the same.

ADDITION: I know service do not have ui and I don't want one. I want service to run console application. No need to get any data from it or use this console like ui, just run it to do it`s job.

UPDATE I: discovered, that running calc or any other windows app is easy. But still can`t run cmd or any console app. Actually I need to run it on XP SP2 and Windows 2003 Server. So do not need to interact with Vista in anyway.

Would be glad to any comments!

like image 200
Yaroslav Yakovlev Avatar asked Sep 02 '09 18:09

Yaroslav Yakovlev


People also ask

Can a Windows Service launch an application?

Windows Services cannot start additional applications because they are not running in the context of any particular user. Unlike regular Windows applications, services are now run in an isolated session and are prohibited from interacting with a user or the desktop.


2 Answers

Starting from Windows Vista, a service cannot interact with the desktop. You will not be able to see any windows or console windows that are started from a service. See this MSDN forum thread.

On other OS, there is an option that is available in the service option called "Allow Service to interact with desktop". Technically, you should program for the future and should follow the Vista guideline even if you don't use it on Vista.

If you still want to run an application that never interact with the desktop, try specifying the process to not use the shell.

ProcessStartInfo info = new ProcessStartInfo(@"c:\myprogram.exe"); info.UseShellExecute = false; info.RedirectStandardError = true; info.RedirectStandardInput = true; info.RedirectStandardOutput = true; info.CreateNoWindow = true; info.ErrorDialog = false; info.WindowStyle = ProcessWindowStyle.Hidden;  Process process = Process.Start(info); 

See if this does the trick.

First you inform Windows that the program won't use the shell (which is inaccessible in Vista to service).

Secondly, you redirect all consoles interaction to internal stream (see process.StandardInput and process.StandardOutput.

like image 89
Pierre-Alain Vigeant Avatar answered Sep 19 '22 04:09

Pierre-Alain Vigeant


I've done this before successfully - I have some code at home. When I get home tonight, I'll update this answer with the working code of a service launching a console app.

I thought I'd try this from scratch. Here's some code I wrote that launches a console app. I installed it as a service and ran it and it worked properly: cmd.exe launches (as seen in Task Manager) and lives for 10 seconds until I send it the exit command. I hope this helps your situation as it does work properly as expected here.

    using (System.Diagnostics.Process process = new System.Diagnostics.Process())     {         process.StartInfo = new System.Diagnostics.ProcessStartInfo(@"c:\windows\system32\cmd.exe");         process.StartInfo.CreateNoWindow = true;         process.StartInfo.ErrorDialog = false;         process.StartInfo.RedirectStandardError = true;         process.StartInfo.RedirectStandardInput = true;         process.StartInfo.RedirectStandardOutput = true;         process.StartInfo.UseShellExecute = false;         process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;         process.Start();         //// do some other things while you wait...         System.Threading.Thread.Sleep(10000); // simulate doing other things...         process.StandardInput.WriteLine("exit"); // tell console to exit         if (!process.HasExited)         {             process.WaitForExit(120000); // give 2 minutes for process to finish             if (!process.HasExited)             {                 process.Kill(); // took too long, kill it off             }         }     } 
like image 38
Jesse C. Slicer Avatar answered Sep 20 '22 04:09

Jesse C. Slicer