如何使用 Get-Process 的 Count 属性返回一个几乎为零的值?

发布于 2024-12-07 19:54:43 字数 1185 浏览 1 评论 0原文

比较下面的三个脚本:

示例 1

$a = GPS | Where {$_.ProcessName -Match 'AcroRd32'}
$a
$a.Count

If ($a.Count -Eq 0)
{
    Echo "Adobe Reader is Off"
}
Else
{
    Echo "Adobe Reader is On"
}

# If Adobe Reader is not running, how come 0 (zero) is not returned?
# This is prettier, should I use it?  Or does it slow down performance?



示例 2

$a = GPS AcroRd32
$a
$a.Count

If ($a.Count -Eq 0)
{
    Echo "Adobe Reader is Off"
}
Else
{
    Echo "Adobe Reader is On"
}

# If Adobe Reader is not running, how come 0 (zero) is not returned?
# This is uglier, but it doesn't have to pipe any output, so does it have any performance gains?



示例 3

GPS AcroRd32 | Measure | Select -Expand Count

# 0 (zero) is returned, but with an ugly Error



我想我的部分问题是我将 PowerShell 视为 VBS;以这种方式/风格编写代码通常会产生一个零整数值,并且不会抛出任何错误(当然,如果 Adob​​e Reader 关闭的话)。 PowerShell 检查程序实例是否未运行的正确方法是什么?评论中的性能问题是次要的“PowerShell Way”问题。

PS说实话,第三个示例返回的错误消息不会破坏任何东西,它只是丑陋,所以它没有超出实际用途,所以我想真正的问题是我只是一个美学傻瓜=^D

Compare the three scripts below:

Sample 1

$a = GPS | Where {$_.ProcessName -Match 'AcroRd32'}
$a
$a.Count

If ($a.Count -Eq 0)
{
    Echo "Adobe Reader is Off"
}
Else
{
    Echo "Adobe Reader is On"
}

# If Adobe Reader is not running, how come 0 (zero) is not returned?
# This is prettier, should I use it?  Or does it slow down performance?


Sample 2

$a = GPS AcroRd32
$a
$a.Count

If ($a.Count -Eq 0)
{
    Echo "Adobe Reader is Off"
}
Else
{
    Echo "Adobe Reader is On"
}

# If Adobe Reader is not running, how come 0 (zero) is not returned?
# This is uglier, but it doesn't have to pipe any output, so does it have any performance gains?


Sample 3

GPS AcroRd32 | Measure | Select -Expand Count

# 0 (zero) is returned, but with an ugly Error


I guess part of my problem is that I'm treating PowerShell like it's VBS; writing code in this manner/style would usually yield me an integer value of zero and not throw any errors (if Adobe Reader was off, of course). What's the correct PowerShell way of checking that an instance of a program is not running? The performance questions in the comments are secondary to the "PowerShell Way" question.

P.S. To be honest, the Error Message returned by the 3rd Sample wouldn't break anything, it's just ugly, so it's not beyond practical use, so I guess the real problem is that I'm just a sucker for aesthetics =^D

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

星星的轨迹 2024-12-14 19:54:43

这是一个常见的 PowerShell 问题。命令可以返回:

  • Nothing ~ null (没有属性 Count,获取它要么得到 null 要么失败)
  • 单个对象(它可能有自己的属性 Count 属性,最令人困惑的情况 - 可以返回任何内容;或者可能没有它,然后获取 Count 为 null 或失败)
  • 具有属性 Count 的 2+ 对象数组。

解决方案很简单。当您确实需要返回对象的计数时,请使用 @() 运算符。结果始终是一个具有 Count 属性的数组。

# this is always an array
$result = @(<command returning something or nothing>)

# this is always a number:
$result.Count

This is a common PowerShell gotcha. A command can return:

  • Nothing ~ null (does not have the property Count, getting it either gets null or fails)
  • A single object (it may have its own property Count property, the most confusing case -- can return anything; or may not have it, then getting Count gets null or fails)
  • 2+ object array which has the property Count.

The solution is simple. When you really need the count of returned objects use the @() operator. The result is always an array which has the property Count.

# this is always an array
$result = @(<command returning something or nothing>)

# this is always a number:
$result.Count
伴我老 2024-12-14 19:54:43

我建议你这样做:

$count = @(get-process | ?{$_.ProcessName -eq "AcroRd32"}).count

if($count -eq 0){

write-host "Adobe Reader is Off"

} else{

write-host "Adobe Reader is On"

}

上面的作用是将返回的对象强制放入一个数组中,因此如果没有运行的读取器进程,你将得到一个空数组,因此它的计数将为零。当您确实有进程时,您会将它们放在数组中,并且您会得到非零计数,并且上面的代码将按预期工作。

基于 Sample2 / Sample3 的替代方案:

$acrobat = gps AcroRd32 -ErrorAction SilentlyContinue
if($acrobat){

    write-host "Adobe Reader is On"

} else{

    write-host "Adobe Reader is Off"

}

在上面,如果阅读器未运行,我们会抑制错误。然后,如果设置了 $acrobat,您就知道阅读器正在运行。

对代码的观察:

当阅读器未运行时,$a 不会被分配任何内容,因此 $a.Count -eq 0 将为 false。当 reader 运行时,$a 被分配这些进程对象,并且你得到 $a.Count 为 1 或更多,因此再次为 false。因此,您始终会知道阅读器处于打开状态。

I would suggest you to do something like this:

$count = @(get-process | ?{$_.ProcessName -eq "AcroRd32"}).count

if($count -eq 0){

write-host "Adobe Reader is Off"

} else{

write-host "Adobe Reader is On"

}

What the above does is that it forces the returned objects into an array, so if there are no reader processes running, you will get an empty array and hence its count will be zero. And when you do have processes, you have them in the array, and you get the non-zero count and the above code will work as expected.

Alternative based on Sample2 / Sample3:

$acrobat = gps AcroRd32 -ErrorAction SilentlyContinue
if($acrobat){

    write-host "Adobe Reader is On"

} else{

    write-host "Adobe Reader is Off"

}

In the above, we suppress the error if the reader is not running. Then, if $acrobat is set, you know that the reader is running.

Observations on your code:

When the reader is not running, $a gets assigned nothing and hence $a.Count -eq 0 will be false. When reader is running, $a gets assigned those process objects and you get $a.Count as 1 or more and hence again false. So you will always get that the reader is on.

生寂 2024-12-14 19:54:43

您在第三个示例中提到了错误 - 您可以使用 SilentlyContinue ErrorAction 隐藏消息:

GPS -ea silentlycontinue AcroRd32 | Measure | Select -Expand Count

you mention the error in the third example - you can hide the message by using the SilentlyContinue ErrorAction:

GPS -ea silentlycontinue AcroRd32 | Measure | Select -Expand Count
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文