Windows services 调试Windows服务并尝试查看它所看到的内容

Windows services 调试Windows服务并尝试查看它所看到的内容,windows-services,subprocess,Windows Services,Subprocess,我们目前有一个自动化系统,作为处理卫星图像的服务运行。此服务维护一个配置文件,在配置文件中,我们应用某些脚本(python)将输入的卫星图像转换为更可用的格式。这些脚本调用转换过程所需的应用程序。服务通过系统(“命令”)(用c/c++编写)调用脚本本身。(服务使用与用户相同的帐户) 我们目前正在尝试添加对另一种卫星图像格式的支持,转换器是来自ERDAS Imagine(importavhrr)的commercial.exe(我们在脚本中完成了几个步骤来更改投影) 脚本工作正常,直到遇到以下问题:

我们目前有一个自动化系统,作为处理卫星图像的服务运行。此服务维护一个配置文件,在配置文件中,我们应用某些脚本(python)将输入的卫星图像转换为更可用的格式。这些脚本调用转换过程所需的应用程序。服务通过系统(“命令”)(用c/c++编写)调用脚本本身。(服务使用与用户相同的帐户)

我们目前正在尝试添加对另一种卫星图像格式的支持,转换器是来自ERDAS Imagine(importavhrr)的commercial.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脚本为ERDA设置了大约30-40个环境变量 -所有环境变量都已正确设置(在第一次运行脚本时转储环境变量,并将它们与打印消息时得到的结果进行比较) -将环境变量传递到subprocess.Popen()会产生相同的结果 -该公司拒绝帮助我们,因为他们不支持从命令行运行程序(但当用户这样做时,它工作正常,只是不支持服务) -在调试模式下运行服务可以正常工作。 -我已经重新启动了机器

我在这里不知所措,我认为(并且担心)ERDAS可执行文件正在弹出某种错误消息窗口,但是我已经看了,看了,找不到任何方式来查看服务看到的内容。我已经想了将近一个星期了,所以是的

编辑

我抓取了推荐的Process Explorer,查看堆栈线程,我发现:

<snip ntoskrnl calls>
ntdll.dll!KiFastSystemCallRet
ntdll.dll!RtlSetLastWin32ErrorAndNtStatusFromNtStatus+0x301
kernel32.dll!GetModuleHandleA+0xdf

ntdll.dll!KiFastSystemCallRet
ntdll.dll!RTLSETLASTWIN32Error和NTSTATUS fromNTSTATUS+0x301
内核32.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

ntdll.dll!KiFastSystemCallRet
USER32.dll!ScrollWindowEx+0x121d
USER32.dll!SoftModalMessageBox+0x6f8
USER32.dll!MessageBoxTimeOut+0x1d9
USER32.dll!MessageBoxTimeOut+0x5b
USER32.dll!MessageBoxTimeoutA+0x9c
USER32.dll!messagexa+0x1b
USER32.dll!MessageBoxA+0x45
elib.dll!esmg_GetLocalTapesDB+0x23b
elib.dll!esmg_LogMessageFunc+0x13a

嗯,我想它是想展示一扇窗户吧。我对他们的行为一无所知,不知道是什么导致了esmg_LogMessageFunc崩溃。该函数是他们开发工具的一部分,我没有访问权限。此外,我还从来没有见过erdas记录任何东西

您是否尝试允许该服务与桌面交互,登录到计算机并检查是否确实弹出了错误框?

尝试使用假定访问WindowsStation会导致服务安全上下文出现问题的任何Windows API调用

您可以使用中的几种工具来诊断此类问题。具体来说,考虑使用代替任务管理器,并跟踪特定进程的活动。 编辑:他们的新工具可用于获得任何进程的核心转储,并具有非常强大的触发功能。一些最新的战争故事利用ProcDump发现了真正发生的事情


为完整起见,关于调试服务的“官方”工具的详细概述,请访问。

您可能需要从开始。您可以看到线程和这些线程的堆栈。如果你真的认为有一个打开的窗口,你可能会在堆栈的底部看到它

kernel32.dll!RegisterWaitForInputIdle+0x49

如果这不起作用,我将获得进程的完整内存转储,然后使用WinDBG查看它在做什么

+1只允许访问桌面可能是最简单的方法,假设您没有部署到大型服务器场……您说在调试模式下运行该服务效果很好。这实际上是否意味着作为服务运行的调试构建(即在SCM下,而不是作为独立程序运行)不会触发问题?所谓调试模式,我指的是对服务使用调试开关。这基本上是作为常规exe运行服务。