I have a Windoze Service which is using Poco::launch to launch an external program. My app can be run as a console app, i.e. not a Service, with a suitable command line option. When I run it with this command line option the launched program is launched ok and runs exactly as expected. However, when I run my program as a service and it launches this particular program the launch apparantly succeeds (I get a pid) but the command then fails silently. It runs for less than a second. This is for an app that is supposed to stay up. This is very mysterious. I wonder what I am doing wrong. Has anyone done Poco::launch from a Windoze Service before? Perhaps there are some special considerations for services that I don't know about.

A process that is spawned from a Windows Service will run under the same user account as the Windows Service, and cannot have a GUI since services don't have an associated desktop session. Since you're using Process::launch, GUI is probably not an issue since it should suppress the GUI anyway, so it's probably a security issue. What does the app do?

codecandy2k wrote:A process that is spawned from a Windows Service will run under the same user account as the Windows Service, and cannot have a GUI since services don't have an associated desktop session. Since you're using Process::launch, GUI is probably not an issue since it should suppress the GUI anyway, so it's probably a security issue. What does the app do?

The app does not have a GUI. It is a command line application. The first thing it does is opens a logfile and writes into it a message saying what version the software is. It does not get that far.

It looks to me like it is some sort of environmental problem rather than the software itself going wrong. Maybe it can't find a DLL but only when running as a service. It is a puzzle.

I suspect an environment problem. Services usually run under the Local System account. If your application requires DLLs that can only be found via PATH, make sure that the global (not user-specific) PATH environment variable is set properly. Or even better, set it from your service before launching the app. You could also try specifying a different user account (e.g., your own or "Local Service" for running your service and see if that helps. Another thing to consider: if you're using mapped drive letters, these are not available to other accounts.

To be sure and narrow it down you can call GetExitCodeProcess with the process handle. If the process failed to initialize due to not being able to find a DLL, you should get an exit code of 0xc0000135.

How does the command line app determine where to write the log file? Keep in mind 2 additional points:

1) The default working directory for Local System account is usually the system32 (or syswow64) directory.

2) If the app reads a path from the registry, HKCU will be for a default user account, not a logged-in user account.

guenter wrote: Services usually run under the Local System account. If your application requires DLLs that can only be found via PATH, make sure that the global (not user-specific) PATH environment variable is set properly. Or even better, set it from your service before launching the app. You could also try specifying a different user account

I used to think it was to do with account but not any more. I can make it work by launching a batch file that runs the command I first thought of.

One thing I did find as I worked on the batch file is that in the batch file I had to change the drive since the service runs from the C drive but my app was on the E drive. Could it be drive-related?

Also a colleague has suggested that it might be something to do with having a console, or not, as the case may be.

guenter wrote: Services usually run under the Local System account. If your application requires DLLs that can only be found via PATH, make sure that the global (not user-specific) PATH environment variable is set properly. Or even better, set it from your service before launching the app. You could also try specifying a different user account

I used to think it was to do with account but not any more. I can make it work by launching a batch file that runs the command I first thought of.

One thing I did find as I worked on the batch file is that in the batch file I had to change the drive since the service runs from the C drive but my app was on the E drive. Could it be drive-related?

Also a colleague has suggested that it might be something to do with having a console, or not, as the case may be.

I don't think it's drive-related. I am not sure about the console thingy. I am at the point now where I am so desperate that I plan to create a batch file on the fly and launch the command "cmd /c <nameOfBatchFile>". This is really kludgey I know but that's what you do when you are desparate. Unfortunately this will stop me from making a couple of enhancements to Poco that I was planning. I wanted to add working directory and process priority to the launch but this will make almost no difference if I end up always launching a batch file.

One other thing you could try is redirect the launched process' IO channels to Pipes and see if that helps. Of course you'll have to read from the process' stdout, preferrably with Poco::StreamCopier, copying the result to a stringstream or NullOutputStream, etc.

guenter wrote:One other thing you could try is redirect the launched process' IO channels to Pipes and see if that helps. Of course you'll have to read from the process' stdout, preferrably with Poco::StreamCopier, copying the result to a stringstream or NullOutputStream, etc.

I already do the I/O redirection.

Another Poco enhancement I had in mind was the setting of environment variables in the process to be launched. This too is scuppered by the intermediate batch file kludge.

guenter wrote:One other thing you could try is redirect the launched process' IO channels to Pipes and see if that helps. Of course you'll have to read from the process' stdout, preferrably with Poco::StreamCopier, copying the result to a stringstream or NullOutputStream, etc.

I already do the I/O redirection.

Another Poco enhancement I had in mind was the setting of environment variables in the process to be launched. This too is scuppered by the intermediate batch file kludge.

It turns out that I can't use the DOS batch file approach. This causes problems of its own. Killing a DOS batch process causes the cmd exe to prompt "ok to terminate batch job?". It seems like there is no way around this obnoxious behaviour other than to patch cmd.exe! Several web sites explain how to do the binary patch.

So I am back to trying to find out what is wrong with the call to CreateProcess that makes it not work for certain exes when they are launched via a windoze service.

This means that my enhancement for specifying environment variables in the launch is on after all. I propose that a new overloaded launch method is provided thus: