我们有一个客户端系统,用户通过服务器连接到SAP 9.2。
当用户在Web上运行SAP 9.2时,SAP会在服务器上启动exe进程,就像运行SAP客户端应用程序时一样。用户完成SAP工作后,通常用户不会选择文件并退出,但只要关闭SAP就会关闭标签。
在服务器上SAP exe进程没有关闭,昨天我注意到服务器内存已满(100%利用率),而只有一个用户登录。在任务管理器上,我们运行了100多个SAP exe进程。我不得不手动关闭所有服务,之后Web上的SAP 9.2开始顺利运行。
今天回到11个左右的SAP流程,根据所附截图,自昨天晚上以来只有四个用户登录,当我拍摄截图时没有人登录。
我的问题是,如何使用TASKKILL或任何其他方法来终止属于SAP Business One的所有休眠进程而不影响登录用户?
用户使用的是Windows Server 2012标准版。
答案 0 :(得分:2)
您没有使用任何特定代码(例如batch-file或powershell)标记您的问题,然后我假设您需要批处理文件。无论您使用何种语言,算法都是相同的,但显然语法非常不同(PowerShell脚本更简单,更短)。
从命令行(当用户登录时最终使用计划任务或自动启动操作),您可以使用TASKKILL
:
TASKKILL /FI "IMAGENAME eq imagename.exe" /FI "USERNAME ne %USERNAME%" /T /F
很少注意到:
imagename.exe
替换为 SAP Business One 进程的图像名称(使用TASKLIST
进行检查),或者您可以使用WINDOWTITLE
过滤器。%USERNAME%
替换为%USERDOMAIN%\%USERNAME%
。/F
强制关闭指定的进程,只有在温和终止无法正常工作时才执行此操作。/T
关闭进程及其所有子进程(我看到其中一些进程有子进程)。TASKKILL
帮助以获取更多过滤器,请注意这将导致所有不属于当前登录用户的进程执行此命令。它有一个明显的含义:登录用户必须拥有所需权限,并且您随时只有一个登录用户。最后一点的含义在某种程度上是巨大的,如果你需要规避这一点,情况会更复杂。鉴于您可以使用TASKLIST /V
获取详细的流程信息,并且您可以使用方便的格式格式化输出(假设此示例中流程图像名称为sapbo.exe
):
TASKLIST /V /FO:CSV /FI "IMAGENAME eq sapbo.exe"
可以使用以下内容解析:
FOR /F "delims=, tokens=1-7" %1 IN ('TASKLIST /V /FO:CSV "IMAGENAME eq sapbo.exe"') DO (
echo %1 %7
)
您需要确定用户是否已登录。如果它是一个交互式会话,您可以检查Windows Shell进程(如果您想要做好事情,请从注册表中读取它...)我知道最简单的方法是使用this post中的代码:
TASKLIST /FI "IMAGENAME eq myapp.exe" 2>NUL | FIND /I /N "myapp.exe">NUL
IF "%ERRORLEVEL%"=="0" ECHO Programm is running
因为如果没有登录用户你需要终止进程,那么在DO
部分之后放置它(它是一行,这里我为了清楚起见而拆分):
TASKLIST /FI "IMAGENAME eq winlogon.exe" /FI "USERNAME eq %7" 2>NUL
| FIND /I /N "winlogon.exe" > NUL
|| TASKKILL /T /F /PID %2
不要忘记根据具体情况调整此代码...
正如我在PowerShell中所说的那样容易得多。首先,您希望所有流程都有资格被杀死:
Get-Process sapbo -IncludeUserName
循环浏览它们并检查是否存在交互式会话:
foreach ($eligibleProcess in Get-Process sapbo -IncludeUserName)
{
if (-not Get-Process winlogon -ErrorAction SilentlyContinue -IncludeUserName | where { $_.UserName -eq $eligibleProcess.UserName })
{
$eligibleProcess.Kill();
}
}
请注意我在这里编写代码然后没有经过测试,请小心......