Search code examples
powershellwindows-10powershell-5.0

Executing a file that may reside at two different locations using PowerShell


I have a cute little script in my $PROFILE helping me start Notepad++ from the script showing a file of my choosing.

function Edit{
  param([string]$file = " ")
  Start-Process "C:\Program Files\Notepad++\notepad++.exe" -ArgumentList $file
}

It's worked great until recently, where I jump between different systems. I discovered that NPP is installed in C:\Program Files on some systems but in C:\Program Files (x86) on others. I can edit the script adapting it but having done so a gazillion times (i.e. 5 to this point), I got sick and tired of it, realizing that I have to automate this insanity.

Knowing little about scripting, I wonder what I should Google for. Does best practice dictate using exception handling in such a case or is it more appropriate to go for conditional expressions?

According to Get-Host | Select-Object Version I'm running version 5.1, if it's of any significance. Perhaps there's an even neater method I'm unaware of? Relying on an environment variable? I'd also prefer to not use a method valid in an older version of PS, although working, if there's a more convenient approach in a later one. (And given my experience on the subject, I can't tell a duck from a goose.)


Solution

  • I would use conditionals for this one. One option is to test the path directly if you know for certain it is in a particular location.

    Hard coded paths:

    function Edit{
      param([string]$file = " ")
    
    $32bit = "C:\Program Files (x86)\Notepad++\notepad++.exe"
    $64bit = "C:\Program Files\Notepad++\notepad++.exe"
    
    if (Test-Path $32bit) {Start-Process -FilePath $32bit -ArgumentList $file}
    elseif (Test-Path $64bit) {Start-Process -FilePath $64bit -ArgumentList $file}
    else {Write-Error -Exception "NotePad++ not found."}
    }
    

    Another option is pulling path information from registry keys, if they're available:

    function Edit{
      param([string]$file = " ")
    
    $32bit = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Notepad++\' -ErrorAction SilentlyContinue).("(default)")
    $64bit = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Notepad++\' -ErrorAction SilentlyContinue).("(default)")
    
    if ($32bit) {Start-Process -FilePath "$32bit\notepad++.exe" -ArgumentList $file}
    elseif ($64bit) {Start-Process -FilePath "$64bit\notepad++.exe" -ArgumentList $file}
    else {Write-Error -Exception "NotePad++ not found."}
    }