If/Else Question

This topic contains 0 replies, has 1 voice, and was last updated by  Forums Archives 5 years, 9 months ago.

  • Author
    Posts
  • #5816

    by Lery at 2013-04-17 10:59:57

    Does anyone know why this is executing the elseif statement and not the IF statement? I have notepad running and $path does contain notepad. I've tried it a few different ways, but no luck.


    [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
    $balloon = New-Object System.Windows.Forms.NotifyIcon
    $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

    if ($path -contains 'Notepad') {
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }
    elseif ($path -notcontains 'Notepad') {
    $currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }

    by DonJ at 2013-04-17 11:05:06

    You're using the wrong operator. -Contains is not a string-matching operator – read about_comparison_operators.

    You probably meant -like 'Notepad*' instead.

    One of the top 10 PowerShell gotchas.

    by Lery at 2013-04-17 11:11:10

    [quote="DonJ"]You're using the wrong operator. -Contains is not a string-matching operator – read about_comparison_operators.

    You probably meant -like 'Notepad*' instead.

    One of the top 10 PowerShell gotchas.[/quote]

    That worked. I also just got it working using -f. So this also works

    #$ErrorActionPreference = "silentlycontinue"
    [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
    $balloon = New-Object System.Windows.Forms.NotifyIcon
    $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

    if ($path -f 'Notepad*') {
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }
    elseif ($path -notcontains 'Notepad') {
    $currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
    $currentproc
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }

    I got excited when I thought I fixed it myself and rushed here to post it quick. 🙂

    by Lery at 2013-04-17 11:12:51

    Actually, I stand corrected. -like does not work. It skips over the if. I have to use -f. Then it works.

    by DonJ at 2013-04-17 11:16:29

    Uh, no... -f is the format operator. That's not doing what you think it's doing. Use -like. Gotta read up on those operators, man ;).

    by Lery at 2013-04-17 11:48:00

    [quote="DonJ"]Uh, no... -f is the format operator. That's not doing what you think it's doing. Use -like. Gotta read up on those operators, man ;).[/quote]

    I understand what you're saying. But -like is not working. The only way I can get it working is with -f.

    This does not work

    [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
    $balloon = New-Object System.Windows.Forms.NotifyIcon
    $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

    if ($path -like 'Notepad*') {
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }
    elseif ($path -notlike 'Notepad*') {
    $currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }

    This does work

    [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
    $balloon = New-Object System.Windows.Forms.NotifyIcon
    $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

    if ($path -f 'Notepad') {
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }
    elseif ($path -notcontains 'Notepad') {
    $currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = "Hello this is the text"
    $balloon.BalloonTipTitle = "This is the title"
    $balloon.Visible = $true
    $balloon.ShowBalloonTip(10000)
    }

    If I take the balloon thing out of the script, I tested this in a simple if/elseif script.

    This works

    $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path
    if ($path -f 'Notepad*') {
    Write-Host "Notepad is running"
    }
    elseif ($path -notcontains 'Notepad*')
    {
    Write-Host "Notepad is not running"
    }

    This does not work

    $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path
    if ($path -like 'Notepad*') {
    Write-Host "Notepad is running"
    }
    elseif ($path -notcontains 'Notepad*')
    {
    Write-Host "Notepad is not running"
    }

    When I say does not work, I mean specifically the script seems to ignore the if part, and goes right to the elseif. So if Notepad was open and I ran the script with the -like, it would say Notepad is not running.

    No idea why it's this way, just that is what is happening for me.

    by DonJ at 2013-04-17 11:53:35

    You need to get into your data a little. I'm telling you, -f isn't a comparison operator. Trust me on this. You're getting a spurious result because you're using it in a way it isn't intended to be used.

    For example, if $Path contains a COMPLETE path, then $path -like '*notepad*' would be the way to go. I've no idea what's in $path.

    by Lery at 2013-04-17 12:06:33

    [quote="DonJ"]I've no idea what's in $path.[/quote]

    I'm launching Notepad and running this $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

    Running $path gets me C:\Windows\system32\notepad.exe

    Oh, and I fully trust you and what you're saying. I'm just going off the results I'm getting.

    by DonJ at 2013-04-17 12:23:18

    Ok. So, let's talk about how -like works. It's a wildcard match.

    $path -like 'notepad*' will match "notepad.exe" but will not match "c:\windows\system32\notepad.exe" because there's no wildcard at the front of the string – it expects the string to start with "n".

    $path -like '*notepad*' will match "c:\windows\system32\notepad.exe" because there's a wildcard at the front of the string.

    I gotta say – if you're just trying to see if Notepad is running, you're taking the long way around.

    If ((Get-Process -Name Notepad -EA SilentlyContinue).Count -eq 0) { # not running }

    I know I"m only seeing a piece of your code, so you might be after something else, but just offering that. PowerShell being object-oriented, you don't really have to do a text comparison. In fact, the existing logic really relies on an odd design in PowerShell. If Notepad isn't running, "Get-Process -Name Notepad" returns nothing. It's an oddity that Select-Object can do anything with nothing.

    For that matter...

    if (Get-Process -name notepad -EA silentlycontinue) { 'running' } else { 'not running'}

    Works. I had to add -EA in both cases to suppress the error you get from querying a process that doesn't exist. I'm presuming you did something with $ErrorActionPreference in your script to account for that?

    by Lery at 2013-04-17 12:42:50

    [quote="DonJ"]Ok. So, let's talk about how -like works. It's a wildcard match.

    $path -like 'notepad*' will match "notepad.exe" but will not match "c:\windows\system32\notepad.exe" because there's no wildcard at the front of the string – it expects the string to start with "n".

    $path -like '*notepad*' will match "c:\windows\system32\notepad.exe" because there's a wildcard at the front of the string.
    [/quote]

    DOH! As Homer would say. I'm looking at this stuff too much since I overlooked an asterisk! Thanks Don.

    [quote]
    I gotta say – if you're just trying to see if Notepad is running, you're taking the long way around.

    If ((Get-Process -Name Notepad -EA SilentlyContinue).Count -eq 0) { # not running }

    I know I"m only seeing a piece of your code, so you might be after something else, but just offering that. PowerShell being object-oriented, you don't really have to do a text comparison. In fact, the existing logic really relies on an odd design in PowerShell. If Notepad isn't running, "Get-Process -Name Notepad" returns nothing. It's an oddity that Select-Object can do anything with nothing.

    For that matter...

    if (Get-Process -name notepad -EA silentlycontinue) { 'running' } else { 'not running'}

    Works. I had to add -EA in both cases to suppress the error you get from querying a process that doesn't exist. I'm presuming you did something with $ErrorActionPreference in your script to account for that?[/quote]

    Yes, I have the ErrorActionPreference set to suppress that error. I am doing more than the code I put in here. Notepad is just used for testing, because it's simple. Believe it or not I'm playing around with the System.Windows.Forms. I learn by working through examples and applying what is applicable in my world to the lesson. I also have access to all of your CBT Nuggets. Unfortunately for me, I must have a bad case of ADD. I keep learning something new and my mind wonders in a million different directions on what I can do with that data. I need to focus a little more.

    Thanks again!

    by DonJ at 2013-04-17 12:46:19

    Be aware that ErrorActionPreference will suppress *everything*. It's one reason you'll see behavior like you were with -f, in some cases. Things that would normally toss an error will muddle through with weird results.

You must be logged in to reply to this topic.