我正在使用Start-Process
以管理员身份启动Powershell的另一个实例,但是当我尝试传递参数列表时,无论是作为变量还是纯字符串,Powershell都会删除引号。下面是我正在使用的命令:
$argu = '-noexit "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"';
powershell Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu
这是我得到的错误:
x86 : The term 'x86' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
At line:1 char:88
+ ... Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\v ...
+ ~~~
+ CategoryInfo : ObjectNotFound: (x86:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
在此先感谢您的帮助。
更新:
$argu = '''-noexit ""C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat""''';
powershell Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu
这几乎可以解决它,但是现在我在第二窗口而不是第一个窗口中得到了上面的错误。
答案 0 :(得分:2)
(A)从内部 PowerShell:
$argu = '-noexit -command & \"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat\"'
Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu
注意:我一般不会通过Start-Process
呼叫powershell.exe
,因为通常不需要这样做。
嵌入式"
被转义为\
,这是PowerShell在调用其 CLI 时所需要的(也许令人惊讶,因为PowerShell在内部是`
作为转义字符。
"
嵌入在'...'
内,它们不需要额外转义-见下文。要执行的文件路径以调用运算符&
为前缀,因为您需要它来执行以引号形式指定的文件。
请注意,我已经添加了-Command
,这在Windows PowerShell中不是严格必需的,但是如果您从PowerShell Core (现在默认为-File
。
或者,您也可以单独指定参数,作为 array 的一部分,这可以说是更干净的解决方案:
$argu = '-noexit', '-command', '&', 'de',
'\"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat\"'
Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu
遗憾的是,即使在这种情况下,您也需要为包含空格的参数a known Start-Process
problem being tracked on GitHub使用多余的嵌入式引号。
PowerShell在调用外部程序时对报价的处理通常是有问题的。 this GitHub issue中总结了当前问题。
(B)从外部 PowerShell(cmd.exe
,自定义File Explorer上下文菜单):
powershell -command Start-Process -Verb RunAs -FilePath powershell -ArgumentList '-noexit -command . ''C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat'''
单引号(嵌套的单引号转义为''
),因为双引号实际上会使转义变得复杂。
.
而不是&
来执行.bat
文件,这避免了如何解析&
的问题。尽管.
的用途与&
的用途不同,但是两个运算符在调用 external 程序时的行为相同。
如果您还想为最终打开提升权限的PowerShell会话设置工作目录,则需要合并一个明确的Set-Location
(cd
)调用放入命令字符串中,因为Start-Process -Verb RunAs
始终默认为SYSTEM32文件夹(在这种情况下,即使-WorkingDirectory
参数也无济于事)。
为使该文件安全运行,您必须使用 double -引号 quote 目录路径,因为文件名可能包含单引号。使用%V
作为目录路径(文件浏览器将其提供给通过自定义上下文菜单调用的命令),正确转义的Set-Location
调用看起来像这样(我希望我在开玩笑):
Set-Location \"\"\"%V%\"\"\"
已集成到完整命令中(为简便起见,使用Set-Location
的内置别名cd
)
powershell -command Start-Process -Verb RunAs -FilePath powershell -ArgumentList '-noexit -command cd \"\"\"%V%\"\"\"; . ''C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat'''
顺便说一句:PowerShell Core 现在具有一个-WorkingDirectory
(-wd
)CLI参数,该参数可让您更可靠地控制启动目录(pwsh -wd "c:\path\to\dir" ...
) ;实际上,prompted the introduction of this parameter正是File Explorer自定义上下文菜单用例。