running a program from a service
I am working on a windows service written in C++ using vs2005 and I'm running into a problem.
The service must launch an other small executable and get it's output. I do that through a call to CreateProcess (well a library does that for me actually (libexecstream) ), it works.
The executable being launched, is somewhere on the disk, I don't know where, and it's directory is in the path environment variable. My service just launch "theTool.exe" and here we go.
If the path variable looks like this:smting;smthingelse;C:\Program Files\blah\bin;meow
it works.
But if the path looks like this: smting;smthingelse;%ProgramFiles%\blah\bin;meow
it no longer works!
The problem is, on some machines it looks like the first, on others like the second...
The funny thing is that if I launch it in a console (as opposed to as a service) it works fine!Is th开发者_如何学Pythonere a way to avoid that problem? programatically? A solution like changing it by hands is not an option (the client doesn't want it). Changing it in the install script or something like that is not an option either because the path might be changed afterwards.
And modifying the tool is not an option either because we didn't do it and we don't have the source code.edit: the CreateProcess line looks like this:
STARTUPINFO si;
ZeroMemory( &si, sizeof( si ) );
si.cb=sizeof( si );
si.hStdError = err.w();
si.hStdOutput = out.w();
si.hStdInput = in.r();
si.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof( pi ) );
if( !CreateProcess( 0, const_cast< char * >( command.c_str() ), 0, 0, TRUE, 0, 0, 0, &si, &pi ) ) {
throw os_error_t( "exec_stream_t::start: CreateProcess failed.\n command line was: "+command );
}
where command
is "theTool"
2nd edit: if my program is launched as a service it fails, if it is launched in a console it workds
Environment variable problems can be tricky, especially when you are talking about services. A few thoughts:
Use process explorer to verify which user the process is running as. Make sure that the user under which the service is running has the appropriate environment vars setup (although this shouldn't be an issue with one as vanilla as %programfiles%)
If you are somehow programatically changing the environment variable, there are know problems with caching the environment vars on startup.
Just some thoughts.
%ProgramFiles%
is another environment variable within your environment variable value entry. You need to resolve it. If when parsing out the path you encounter this pattern you should then look it up and use the UNC path of all parts to point to your file.
Couple ways to skin the cat here:
- Use
GetEnvironmentStrings
windows API to get everything up front and put them in a map for easy lookup by your service - Use
GetEnviromentVariable
to check the existence and get the value of a specific environment variable for exampleProgramFiles
- Query the registry for the environment variables at
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
- Set your own environment variable rather than using
PATH
which should be reserved for system stuff and not fooled around with anyway - Use a more robust filesystem library which has functionality for dealing with environment variables
- Forget environment variables and use a configuration file (this could be accompanied by a simple GUI program that allows them to use a open file dialog to browse and select paths which will be stored for your service to pick up and use later)
- Etc
Instead of using CreateProcess
, you could instead use the App Paths
registry key and launch the application with ShellExecute
. This avoids polluting the PATH
environment variable.
精彩评论