views:

4115

answers:

7

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 dont 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 its 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!

+2  A: 

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.

Pierre-Alain Vigeant
I don`t need to see anything. All I need - launch the console app, and it will do the job. I know that service do not have ui etc. The question is about how to launch console from service app.
Yaroslav Yakovlev
Then don't call it a console app. A console app have a UI, which is the console. Try changing it to a Windows Application, but that don't show anything.
Pierre-Alain Vigeant
I have 2 apps: service and console app. Console app does it job and has no interaction with user. So I wrote that I don`t need any ui for service or for console to interact with the user, I need to launch console app to do it`s job and need to do it from my service. What did I say wrong?
Yaroslav Yakovlev
A console application as configured in Visual Studio does have a UI: The Console itself. This might be why you are unable to start it with the Windows Service. Even if and since you never interact with the user, you do not need that application to be a Console application.
Pierre-Alain Vigeant
Ok let`s treat it like a special case and get back to the question: how can I launch console with service? I know that if I can switch it all with winform I should write winform app or use only service. But I need to launch console from service :-(
Yaroslav Yakovlev
@Pierre-Alain Vigeant: Your comment is not strictly true. Windows services *can* interact with the desktop under Windows XP, although the feature has essentially been removed from Vista. That notwithstanding, this still doesn't address Yaroslav's question.
Matt Davis
I updated the answer to make the distinction between the Vista and XP behavior.
Pierre-Alain Vigeant
Updated the question. Still need the answer.
Yaroslav Yakovlev
Will update this question in a few days. Would like to thank Pierre-Alain Vigeant for his help. Thanks for your contribution!
Yaroslav Yakovlev
+1  A: 

Windows Services do not have UIs. You can redirect the output from a console app to your service with the code shown in this question.

Dour High Arch
I don`t need to have a UI or redirect an output. I need to launch a console app and let it do the job. I don`t need any ui, so it`s not the way out.
Yaroslav Yakovlev
A: 

As pierre said, there is no way to have a user interface for a windows service (or no easy way). What I do in that kind of situation is to have a settings file that is read from the service on whatever interval the service operates on and have a standalone application that makes changes to the settings file.

SnOrfus
Please read my comments to other answers, I don`t need a ui for service.
Yaroslav Yakovlev
A: 

Does your console app require user interaction? If so, that's a serious no-no and you should redesign your application. While there are some hacks to make this sort of work in older versions of the OS, this is guaranteed to break in the future.

If your app does not require user interaction, then perhaps your problem is related to the user the service is running as. Try making sure that you run as the correct user, or that the user and/or resources you are using have the right permissions.

If you require some kind of user-interaction, then you will need to create a client application and communicate with the service and/or sub-application via rpc, sockets, or named pipes.

Mystere Man
No interaction needed. I tried system account and my admin account. I think admin account should be enuogh to launch a console app.
Yaroslav Yakovlev
A: 

Services are required to connect to the Service Control Manager and provide feedback at start up (ie. tell SCM 'I'm alive!'). That's why C# application have a different project template for services. You have two alternatives:

  • wrapp your exe on srvany.exe, as described in KB How To Create a User-Defined Service
  • have your C# app detect when is launched as a service (eg. command line param) and switch control to a class that inherits from ServiceBase and properly implements a service.
Remus Rusanu
A: 

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
            }
        }
    }
Jesse C. Slicer
That would be great! Really impatiently waitnig!!! :-)
Yaroslav Yakovlev
A: 

I have a Windows service, and I added the following line to the constructor for my service:

using System.Diagnostics;
try {
    Process p = Process.Start(@"C:\Windows\system32\calc.exe");
} catch {
    Debugger.Break();
}

When I tried to run this, the Process.Start() call was made, and no exception occurred. However, the calc.exe application did not show up. In order to make it work, I had edit the properties for my service in the Service Control Manager to enable interaction with the desktop. After doing that, the Process.Start() opened calc.exe as expected.

But as others have said, interaction with the desktop is frowned upon by Microsoft and has essentially been disabled in Vista. So even if you can get it to work in XP, I don't know that you'll be able to make it work in Vista.

Matt Davis