views:

347

answers:

3

I have a Windows service and an MSI installer (setup project) for it. The setup project has custom actions for install and uninstall with args of /install and /uninstall respectively.

I would like the service to start immediately after the install. All my service does is starts a process. When the service is stopped, it does process.Close();.

I have tried doing

var sc = new ServiceController( "MyProcess" );
sc.Start();

The process starts, but the event log message saying the service has started doesn't show. When stopping I get the error Error stopping process: System.InvalidOperationException: No process is associated with this object..

If I don't use the service controller to start and use Services.msc instead, it works as expected when stopping.

Is there a way to have the process start immediately and have my start/stop methods work as expected?

+1  A: 

You don't say what operating system you are using, but I remember running into this when developing an installer app last year. I beleive this is a security restriction in Windows 7, Server 2003/2008, and possibly Vista, as installation program cannot start any application program that it installs. If you set the service for Automatic Startup, then it should start the next time the system restarts.

mharr
This is on Windows 7. If you are correct, that makes sense.
Josh Close
Though, it does start the service, just not properly. My code is in the OnStart and OnStop methods of the service class.
Josh Close
A: 

I think what you're saying is that there are two issues are going on here. The first issue is that the service doesn't start upon install. The second is that the service is unable to start the process. Am I right?

When I've installed services through a setup project, I always start the service from the Commit method of the installer class, that way I know that everything got installed correctly. I'm not 100% sure about this, but you may not be able start the service until the installation has been committed. It looks like you have your Custom Actions set up correctly, so there shouldn't be any issue with the Commit method getting called (you do have Commit included in the Custom Actions, right?) Here is an example of the Commit method from one of my projects:

public override void Commit(IDictionary savedState)
{
    base.Commit(savedState);

    try
    {
        var serviceController = new ServiceController("<Insert Service Name>");
        serviceController.Start();
    }
    catch
    {
        MessageBox.Show(
            "There was an error starting the <Insert Service Name> Service. Please manually start it, or restart the computer.");
    }
}

By showing the message box to the user, if something goes wrong with the service start, at least the user will be notified that the service should be started manually. When debugging the install issue, you can include the exception in the message box for more details into what exactly is going on.

I'm curious - what Account are you using in your ServiceProcessInstaller? Does this user have the rights on the computer to start the process? Does the Process have any specific UAC requirements? I suspect that Access Control is what is keeping your process from starting.

fre0n
I'm using the LocalSystem account. When using ServiceController to start the service, the process I'm launching DOES start up, but there usually is a message in the event log saying the service successfully started. I save the process instance so when OnStop is called, I can do `process.Close()`, but the process isn't valid then.
Josh Close
I can't even get the new process to launch now. I was working fine yesterday, but I was on a different network. Maybe it's a UAC issue like you said. If so, what can I do in an installer to enable the service to be able to launch this process that apparently needs some extra rights? The process I'm launching is mongod.exe, which is the MondoDB process, so it binds to a port at the least. I've tried turning the firewall off, but that didn't make a difference.
Josh Close
Also, I have a try/catch around the process start, were an event is logged in the catch. Why wouldn't it fail if the process doesn't start? It must be silently failing.
Josh Close
A: 

I ended up taking a different approach by just getting the running process instead of trying to hold on to the one started before. Stopping the process then works just fine, and doesn't matter of the OnStart/OnStop methods are functioning "properly", because my inner process is starting/stopping like I need.

Josh Close