gpt4 book ai didi

windows - 确保在任何给定时间只有 1 个 PowerShell 脚本实例正在运行

转载 作者:可可西里 更新时间:2023-11-01 12:40:46 24 4
gpt4 key购买 nike

我正在 PowerShell v1 中编写一个批处理脚本,它将被安排为每分钟运行一次。不可避免地,有时作业需要超过 1 分钟才能完成,现在我们有两个脚本实例正在运行,然后可能有 3 个,等等......

我想通过让脚本本身检查是否有自己的实例已经在运行来避免这种情况,如果是,则脚本退出。

我在 Linux 上用其他语言做过,但从未在 Windows 上用 PowerShell 做过。

例如在 PHP 中我可以做类似的事情:

exec("ps auxwww|grep mybatchscript.php|grep -v grep", $output);
if($output){exit;}

PowerShell v1 中有这样的东西吗?我还没有遇到过这样的事情。

在这些常见模式中,哪种模式最适合频繁运行的 PowerShell 脚本?

  1. 锁定文件
  2. 操作系统任务调度器
  3. 具有 sleep 间隔的无限循环

最佳答案

这是我的解决方案。它使用命令行和进程 ID,因此无需创建和跟踪任何内容。并且它不关心您如何启动脚本的任一实例。

以下应该按原样运行:

    Function Test-IfAlreadyRunning {
<#
.SYNOPSIS
Kills CURRENT instance if this script already running.
.DESCRIPTION
Kills CURRENT instance if this script already running.
Call this function VERY early in your script.
If it sees itself already running, it exits.

Uses WMI because any other methods because we need the commandline
.PARAMETER ScriptName
Name of this script
Use the following line *OUTSIDE* of this function to get it automatically
$ScriptName = $MyInvocation.MyCommand.Name
.EXAMPLE
$ScriptName = $MyInvocation.MyCommand.Name
Test-IfAlreadyRunning -ScriptName $ScriptName
.NOTES
$PID is a Built-in Variable for the current script''s Process ID number
.LINK
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[String]$ScriptName
)
#Get array of all powershell scripts currently running
$PsScriptsRunning = get-wmiobject win32_process | where{$_.processname -eq 'powershell.exe'} | select-object commandline,ProcessId

#Get name of current script
#$ScriptName = $MyInvocation.MyCommand.Name #NO! This gets name of *THIS FUNCTION*

#enumerate each element of array and compare
ForEach ($PsCmdLine in $PsScriptsRunning){
[Int32]$OtherPID = $PsCmdLine.ProcessId
[String]$OtherCmdLine = $PsCmdLine.commandline
#Are other instances of this script already running?
If (($OtherCmdLine -match $ScriptName) -And ($OtherPID -ne $PID) ){
Write-host "PID [$OtherPID] is already running this script [$ScriptName]"
Write-host "Exiting this instance. (PID=[$PID])..."
Start-Sleep -Second 7
Exit
}
}
} #Function Test-IfAlreadyRunning


#Main
#Get name of current script
$ScriptName = $MyInvocation.MyCommand.Name


Test-IfAlreadyRunning -ScriptName $ScriptName
write-host "(PID=[$PID]) This is the 1st and only instance allowed to run" #this only shows in one instance
read-host 'Press ENTER to continue...' # aka Pause

#Put the rest of your script here

关于windows - 确保在任何给定时间只有 1 个 PowerShell 脚本实例正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15969662/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com