从服务运行程序

时间:2011-07-26 20:05:04

标签: c++ windows-services path environment-variables

我正在使用vs2005编写用C ++编写的Windows服务,我遇到了问题。

服务必须启动另一个小的可执行文件并获取它的输出。我这样做是通过调用CreateProcess(实际上是一个库为我做这个(libexecstream)),它可以工作。

正在启动的可执行文件,在磁盘上的某个地方,我不知道在哪里,它的目录在路径环境变量中。我的服务只是启动“theTool.exe”,然后我们去了。
如果路径变量如下所示:smting;smthingelse;C:\Program Files\blah\bin;meow它可以工作 但是如果路径看起来像这样:smting;smthingelse;%ProgramFiles%\blah\bin;meow它就不再起作用了!

问题是,在某些机器上它看起来像第一个,在其他机器上看起来像第二个...... 有趣的是,如果我在控制台中启动它(而不是作为服务),它可以正常工作!

有没有办法避免这个问题?编程? 手动更改的解决方案不是一种选择(客户不需要它)。在安装脚本或类似的东西中更改它不是一个选项,因为之后可能会更改路径 并且修改工具也不是一种选择,因为我们没有这样做而且我们没有源代码。

修改 CreateProcess行如下所示:

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 );
}

其中command是“theTool”

第二次编辑:如果我的程序作为服务启动它失败,如果它在控制台中启动它就会运行

3 个答案:

答案 0 :(得分:3)

环境变量问题可能很棘手,尤其是当您谈论服务时。一些想法:

  1. 使用process explorer验证进程正在运行的用户。确保运行该服务的用户具有相应的环境变量设置(尽管这不应该是一个像%programfiles%一样的问题)

  2. 如果您以某种方式以编程方式更改环境变量,则会出现缓存environment vars on startup的问题。

  3. 只是一些想法。

答案 1 :(得分:2)

%ProgramFiles%是环境变量值条目中的另一个环境变量。你需要解决它。如果在解析出遇到此模式的路径时,您应该查找它并使用所有部分的UNC路径指向您的文件。

在这里结合使用皮肤的方法:

  • 使用GetEnvironmentStrings Windows API预先获取所有内容并将其放入地图中,以便您的服务轻松查找
  • 使用GetEnviromentVariable检查是否存在并获取特定环境变量的值,例如ProgramFiles
  • HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
  • 查询注册表中的环境变量
  • 设置你自己的环境变量,而不是使用PATH,而{{1}}应保留给系统内容,而不是以任何方式被欺骗
  • 使用更强大的文件系统库,该库具有处理环境变量的功能
  • 忘记环境变量并使用配置文件(这可以伴随一个简单的GUI程序,允许他们使用打开的文件对话框来浏览和选择将存储的服务以供以后使用的路径)< / LI>

答案 2 :(得分:0)

您可以改为use the App Paths registry key而不是使用CreateProcess,并使用ShellExecute启动应用程序。这样可以避免污染PATH环境变量。