您没有使用任何特定标签(例如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 switch 强制关闭指定进程,只有在 温和 终止不起作用时才这样做。
-
/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();
}
}
请注意,我在这里写了代码然后它没有经过测试,小心......