Noob请帮忙.我正在尝试编写一个脚本来检查进程是否正在运行,如果没有,请启动它.如果进程正在运行,它应该什么都不做.到目前为止,我已经提出了以下内容,但它正在启动一个新的流程实例,无论它是否已经运行.任何帮助表示赞赏.
$Prog = "C:\utilities\prog.exe"
$Running = Get-Process prog -ErrorAction SilentlyContinue
$Start = ([wmiclass]"win32_process").Create($Prog)
if($Running -eq $null)
{$Start}
else
{}
Run Code Online (Sandbox Code Playgroud)
jon*_*n Z 29
首先,这是代码中的错误.在您的代码中,在评估您的程序是否已在运行之前创建该过程
$Prog = "C:\utilities\prog.exe"
$Running = Get-Process prog -ErrorAction SilentlyContinue
$Start = ([wmiclass]"win32_process").Create($Prog) # the process is created on this line
if($Running -eq $null) # evaluating if the program is running
{$Start}
Run Code Online (Sandbox Code Playgroud)
可以通过将其包装在{}(脚本块)中来创建应在代码中进一步评估的代码块:
$Prog = "C:\utilities\prog.exe"
$Running = Get-Process prog -ErrorAction SilentlyContinue
$Start = {([wmiclass]"win32_process").Create($Prog)}
if($Running -eq $null) # evaluating if the program is running
{& $Start} # the process is created on this line
Run Code Online (Sandbox Code Playgroud)
但是,如果您正在寻找一个简短的单行程来解决您的问题:
if (! (ps | ? {$_.path -eq $prog})) {& $prog}
Run Code Online (Sandbox Code Playgroud)
Enr*_*lio 10
在Get-Process cmdlet中,进程名称参数必须是没有文件扩展名的可执行文件的名称.尝试替代$Prog = "C:\utilities\prog.exe"使用$Prog = "prog".
在我看来,如果您使用Where-Object cmdlet过滤掉进程,那么您的脚本将更具可读性.这是一个例子:
$programName = "prog"
$isRunning = (Get-Process | Where-Object { $_.Name -eq $programName }).Count -gt 0
if ($isRunning)
# ...
else
# ...
Run Code Online (Sandbox Code Playgroud)
这样你就可以摆脱这个-ErrorAction SilentlyContinue论点,如果找不到Get-Process 如果找不到具有指定名称的进程就会抛出错误,那么这个参数可能会让人感到困惑.
$path = "C:\utilities\prog.exe"
$list = get-process | where-object {$_.Path -eq $path }
if ($list -eq $null) { start-process -filepath $path }
Run Code Online (Sandbox Code Playgroud)
或者
$path = "C:\utilities\prog.exe"
get-process | where-object {$_.Path -eq $path } | measure-object | where-object { $_.Count -eq 0} | foreach-object {start-process -filepath $path }
Run Code Online (Sandbox Code Playgroud)
这将为您节省 if 语句和一个变量声明。它也可以是一行命令:
不要让最后的 foreach 让你失望。度量对象将仅返回一项,而 where 将返回 1 或零。foreach 仅在结果为零时执行。它不会启动多个进程。:)
请记住,PowerShell处理对象而不仅仅是文本.在普通批处理文件中,您可以将变量设置为字符串,然后将其用作命令:
set Foo=dir /b
%Foo%
Run Code Online (Sandbox Code Playgroud)
...这在PowerShell中不起作用.因此,您的分配$Start已经创建了新进程,因为=运行后的命令及其结果已分配给$Start.
此外,你不必要地使事情复杂化.我建议以下内容:
$Running = Get-Process prog -ErrorAction SilentlyContinue
if (!$Running) { Start-Process C:\utilities\prog.exe }
Run Code Online (Sandbox Code Playgroud)
由于Get-Process返回一个对象(计算结果为$true)或$null(计算结果为$false),您可以简化检查,如上所示.这称为类型强制,因为该if语句需要一个布尔值以及在上述情况下将被视为$true和$false非常一致的规则.它看起来更好.
我还使用Start-Processcmdlet而不是WMI来创建新进程.你甚至可以使用以下内容:
if (!$Running) { C:\utilities\prog.exe }
Run Code Online (Sandbox Code Playgroud)
如果应用程序不是控制台应用程序(因此会阻止PowerShell脚本直到它退出).PowerShell仍然是一个shell,因此启动程序本身就能很好地工作:-)
你甚至可以内联$running变量,但我想一个评论是为了澄清你做了什么,然后.
| 归档时间: |
|
| 查看次数: |
39961 次 |
| 最近记录: |