从 PowerShell 按名称运行程序(类似于运行框) [英] Run a program by name from PowerShell (similarly to the run box)

查看:43
本文介绍了从 PowerShell 按名称运行程序(类似于运行框)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Windows 中,我们使用 Windows Key + R 访问 运行框.然后我们可以按名称运行程序(例如 firefox、snippingtool).有没有办法从 PowerShell 中按名称运行程序?

In Windows we access the Run box with Windows Key + R. Then we can run a program by name (e.g. firefox, snippingtool). Is there a way to run a program by name from PowerShell?

> run firefox
> run snippingtool

我已经尝试过 Start-Process firefox 但它不起作用.

I have already tried Start-Process firefox and it doesn't work.

编辑

奇怪的是,从 PowerShell 和运行框中,只输入 notepad 即可打开记事本.但是,键入 firefoxsnippingtool 只能从运行"框而不是从 PowerShell 中工作.

Oddly enough, from both PowerShell and the Run box, typing just notepad opens notepad. However, typing either firefox or snippingtool works only from the Run box and not from PowerShell.

推荐答案

运行框使用 PATH 环境变量,但它也使用一组注册表项.

The run box uses the PATH environment variable but it also uses a set of registry keys.

HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths 包含具有特定应用程序名称的子键,每个子键都有一个名为 Path 的字符串值可执行文件的路径.Powershell 和命令提示符不使用这些.

The key HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths contains subkeys with certain application names, and each of those has a string value called Path with the path to the executable. Powershell and the command prompt don't use these.

$allCommands = Get-Command -CommandType All | Select-Object -ExpandProperty Name

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths' | Where-Object { $_.Property -icontains 'Path' } | ForEach-Object {
    $executable = $_.Name | Split-Path -Leaf
    $shortName = $executable -creplace '\.[^.]*$',''
    $path = $_ | Get-ItemProperty | Select-Object -ExpandProperty Path
    $fqPath = $path | Join-Path -ChildPath $executable

    if ( ($allCommands -icontains $executable) -or ($allCommands -icontains $shortName) ) {
        Write-Verbose "Skipping $executable and $shortName because a command already exists with that name."
    } else {
        Write-Verbose "Creating aliases for $executable."
        New-Alias -Name $executable -Value $fqPath
        New-Alias -Name $shortName -Value $fqPath
    }
}

此代码段将读取注册表并将所有这些条目添加为别名.它还添加了不带 .exe 的 EXE 名称,以便您可以使用短名称.

This snippet will read the registry and add all of those entries as aliases. It also adds the EXE name without .exe so that you can use the short name.

它事先检查现有命令以确保它不会破坏任何现有命令(任何类型).

It checks for existing commands beforehand to make sure that it won't clobber any existing command (of any type).

我还创建了一个函数,您可以使用它来执行任意应用程序,而无需修改整个环境:

I also created a function you could use to execute an arbitrary application, without modifying the entire environment:

function Run-Application {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
    [Parameter(
        Mandatory=$true,
        ValueFromPipeline=$true
    )]
    [ValidateNotNullOrEmpty()]
    [String[]]
    $Name ,

    [Parameter()]
    [Switch]
    $NoExtension
)

    Begin {
        if (!$NoExtension -and $env:PATHEXT) {
            $exts = $env:PATHEXT -csplit ';'
        } else {
            $exts = @()
        }

        $regStub = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths'
    }

    Process {
        :outer 
        foreach($app in $Name) {
            $cmd2run = $app
            if (Get-Command -Name $cmd2run -ErrorAction Ignore) {
                if ($PSCmdlet.ShouldProcess($cmd2run)) {
                    & $cmd2run
                }
                continue :outer
            } elseif ($app -cnotlike '*.*') {
                foreach($ext in $exts) {
                    $cmd2run = "$app$ext"
                    if (Get-Command -Name $cmd2run -ErrorAction Ignore) {
                        if ($PSCmdlet.ShouldProcess($cmd2run)) {
                            & $cmd2run
                        }
                        continue :outer
                    }
                }
            } 
            $thisReg = $regStub | Join-Path -ChildPath $cmd2run
            $regItem = $thisReg | Get-Item -ErrorAction Ignore
            if ($regItem -and $regItem.Property -icontains 'Path') {
                $thisPath = $regItem | Get-ItemProperty | Select-Object -ExpandProperty Path | Join-Path -ChildPath $cmd2run
                if ($PSCmdlet.ShouldProcess($thisPath)) {
                    & $thisPath
                }
                continue :outer
            } elseif ($app -cnotlike '*.*') {
                foreach($ext in $exts) {
                    $cmd2run = "$app$ext"
                    $thisReg = $regStub | Join-Path -ChildPath $cmd2run
                    $regItem = $thisReg | Get-Item -ErrorAction Ignore
                    if ($regItem -and $regItem.Property -icontains 'Path') {
                        $thisPath = $regItem | Get-ItemProperty | Select-Object -ExpandProperty Path | Join-Path -ChildPath $cmd2run
                        if ($PSCmdlet.ShouldProcess($thisPath)) {
                            & $thisPath
                        }
                        continue :outer
                    }                    
                }
            }
        }
    }
}

您可以通过参数或管道提供一个或多个名称,带或不带扩展名.

You can supply one or more names, with or without extension, via parameter or via pipeline.

如果值没有扩展名,它使用 PATHEXT 并尝试每个组合.您也可以使用 -NoExtension 禁用它.

If the value has no extension, it uses PATHEXT and tries every combination. You can also disable that by using -NoExtension.

我使用 Run-Application 作为动词-名词语法,但如果你愿意,你总是可以将其别名为 run.

I used Run-Application for verb-noun syntax, but you could always alias it to run if you want.

如果您在使用其他代码时遇到问题,我不确定它是否适合您,但它对我来说效果很好,而且我写得很开心.希望对您或其他人有所帮助.

I'm not sure if it will work for you if you had problems with the other code, but it worked very well for me, and I had fun writing it. Hope it's helpful to you or someone else.

修正函数使其支持-WhatIf.

Run-Application notepad

Run-Application firefox,chrome.exe

'notepad.exe','firefox.exe','snippingtool' | Run-Application -Whatif

Run-Application firefox -NoExtension # Should fail

这篇关于从 PowerShell 按名称运行程序(类似于运行框)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆