Reputation: 39148
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.)
Upvotes: 3
Views: 283
Reputation: 438273
Let me offer a streamlined version that also supports passing multiple files:
function Edit {
param(
# Allow passing multiple files, both with explicit array syntax (`,`-separated)
# or as indiv. arguments.
[Parameter(ValueFromRemainingArguments)]
[string[]] $File
)
# Construct the potential Notepad++ paths.
# Note: `-replace '$'` is a trick to append a string to each element
# of an array.
$exePaths = $env:ProgramFiles, ${env:ProgramFiles(x86)} -replace '$', '\Notepad++\notepad++.exe'
# See which one, if any, exists, using Get-Command.
$exeToUse = Get-Command -ErrorAction Ignore $exePaths | Select-Object -First 1
# Fall back to Notepad.
if (-not $exeToUse) { $exeToUse = 'notepad.exe' }
# Invoke whatever editor was found with the optional file(s).
# Note that both Notepad++ and NotePad can be invoked directly
# without blocking subsequent commands, so there is no need for `Start-Process`,
# whose argument processing is buggy.
& $exeToUse $File
}
An array of potential executable paths is passed to Get-Command
, which returns a command-info object for each actual executable found, if any.
-ErrorAction Ignore
quietly ignores any errors.
Select-Object -First 1
extracts the first command-info object, if present, from the Get-Command
output; this is necessary to guard against the (perhaps unlikely) case where the executable exists in both locations.
$exeToUse
receives $null
(effectively) if Get-Command
produces no output, in which case Boolean expression -not $exeToUse
evaluates to $true
, causing the fallback to notepad.exe
to take effect.
Both command names (strings) and command-info objects (instances of System.Management.Automation.CommandInfo
or derived classes, as returned by Get-Command
) can be executed via &
, the call operator.
Upvotes: 1
Reputation: 1781
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."}
}
Upvotes: 3
Reputation: 39148
Based on the great help from @BoogaRoo (who should get some +1 for effort) and asked by the same to post my own version of the answer, I go against my reluctance to post asnwers to own questions due to strong sensation of tackiness.
My final version, taking into account systems that lack NP++ but still want to show the editor of some kind.
function Edit{
param([string]$file = " ")
$executable = "Notepad++\notepad++.exe"
$32bit = "C:\Program Files (x86)\" + $executable
$64bit = "C:\Program Files\" + $executable
$target = "notepad"
if(Test-Path $32bit) { $target = $32bit }
if(Test-Path $64bit) { $target = $64bit }
Start-Process $target -ArgumentList $file
}
Upvotes: 1