我们目前拥有一个自动系统,可作为处理卫星图像的服务运行。此服务维护配置文件,在配置文件中我们应用某些脚本(python)将输入卫星图像转换为更有用的格式。脚本为转换过程调用所需的应用程序。这些脚本本身由服务通过系统调用(“命令”)(用c / c ++编写)。 (该服务使用与用户相同的帐户)。
我们目前正在尝试添加对另一种satelitte图像格式的支持,转换器是来自ERDAS Imagine(importavhrr)的商业.exe(我们在脚本中执行了几个自己的步骤来更改投影)。
该脚本运行良好,直至达到此目的:
argslist = ['importavhrr.exe', '-in', '%s' % infn, '-out', '%s' % tmpimg1, '-gui', 'FALSE', '-correct', '-flyingheight', '833', '-rect', 'gcp', gcpfn]
print "".join(argslist)
p = subprocess.Popen(argslist, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
print str(p.communicate())
现在最终发生的事情是,importavhrr.exe只是坐在那里,并没有做任何事情(根据taskmanager它使用0 cpu使用,并且内存使用永远不会改变)。好像它在等待某种用户输入。 (尝试os.system,os.spawnv都产生相同的结果)我猜猜某种gui元素是以太网弹出的各种各样的gui窗口。从任务管理器关闭进程,将控制权返回给python。
注意:-gui FALSE / false / 0参数应该可以防止gui弹出。但是,如果数据不好(我通过破坏数据手动测试,并通过脚本调用),将弹出一个错误窗口显示结果。
当我手动运行脚本(相同的文件,相同的工作目录)时,它工作正常....当我使用相同的系统函数(它的内部库的一部分)手动调用它作为服务时脚本甚至工作
同样使服务仅使用importavhrr.exe和环境变量调用批处理文件也会导致importavhrr.exe挂起。
服务支持: - 使用与我登录时相同的用户帐户 - python脚本为ERDAS设置了大约30-40个环境变量 - 正确设置所有环境变量(在首次运行脚本时转储环境变量,并将它们与我打印消息时得到的相比较) - 将环境变量传递给subprocess.Popen()会产生相同的结果 - 该公司拒绝帮助我们,因为他们不支持从命令行运行程序(但是当用户执行时它工作正常,而不是服务) - 在调试模式下运行服务工作正常。 - 我已重新启动机器。
我在这里不知所措,我认为(并且担心)ERDAS可执行文件正在制作某种错误消息窗口弹出窗口,但是我已经查看过,并且看起来并且找不到任何方式来查看服务见。我一直试图解决这个问题差不多一个星期,所以是的。
修改的
我抓住了推荐的Process Explorer,看着堆栈线程我有这个:
<snip ntoskrnl calls>
ntdll.dll!KiFastSystemCallRet
ntdll.dll!RtlSetLastWin32ErrorAndNtStatusFromNtStatus+0x301
kernel32.dll!GetModuleHandleA+0xdf
等了几分钟后,它改为:
<snip ntoskrnl calls>
ntdll.dll!KiFastSystemCallRet
USER32.dll!ScrollWindowEx+0x121d
USER32.dll!SoftModalMessageBox+0x6f8
USER32.dll!MessageBoxTimeoutW+0x1d9
USER32.dll!MessageBoxTimeoutW+0x5b
USER32.dll!MessageBoxTimeoutA+0x9c
USER32.dll!MessageBoxExA+0x1b
USER32.dll!MessageBoxA+0x45
elib.dll!esmg_GetLocalTapesDB+0x23b
elib.dll!esmg_LogMessageFunc+0x13a
嗯,它正试图展示一个窗口,我猜想。我不知道他们的行为,看看是什么导致esmg_LogMessageFunc崩溃。该功能是他们的开发工具的一部分,我有0访问权限。此外,我从来没有真正看到erdas记录任何东西。
答案 0 :(得分:1)
您是否尝试允许该服务与桌面交互,登录计算机并检查是否实际出现错误框?
答案 1 :(得分:1)
尝试使用任何假定访问windowstation的Windows API调用都会导致服务的安全上下文出现问题。
您可以使用Sysinternals中的几个工具来诊断此类事情。具体来说,请考虑使用Process Explorer代替任务管理器,并使用Process Monitor来跟踪特定流程的活动。
编辑:他们的新ProcDump工具可用于获取具有强大触发功能的任何进程的核心转储。 Mark Russinovich's Blog上的一些最新战争故事利用了ProcDump来发现真实情况。
为了完整起见,对用于调试服务的“官方”工具的概述是this KB article。
答案 2 :(得分:1)
您可能希望从Process Explorer开始。您可以看到这些线程的线程和堆栈。如果你真的认为有一个打开的窗口,你可能会在堆栈底部看到这个
kernel32.dll!RegisterWaitForInputIdle+0x49
如果不能解决问题,那么我将获得该进程的完整内存转储,然后使用WinDBG查看它的作用。