如何在Powershell中创建新窗口并将UseShellExecute设置为false?

时间:2018-09-01 17:04:47

标签: .net powershell

要求有点奇怪,我在Powershell的多线程中遇到了一个奇怪的卡住问题。因此,我想创建一个新窗口,而不使用Shell Execute。但是我不能用下面的代码来实现,窗口不会显示。 $ approot是桌面,在start.bat中,只需执行“ dir / s。\” 我希望目录结果显示在另一个窗口中,而不是在窗口中执行此脚本,并且我不希望使用shell执行。

$startInfo = New-Object system.Diagnostics.ProcessStartInfo
$startInfo.UseShellExecute = $false
$startinfo.FileName = $env:ComSpec
$startInfo.CreateNoWindow = $false
$startInfo.Arguments = "/c cd /d $AppRoot & call start.bat"
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$process.Start() | Out-Null

1 个答案:

答案 0 :(得分:2)

如果将.UseShellExecute设置为$False,则无法在 new 窗口中启动命令.CreateNoNewWindow实际上被忽略

因此,您也可以使用Start-Process,它将.UseShellExecute的默认设置为$True [1]

Start-Process $env:ComSpec -Args '/k', "cd /d `"$AppRoot`" & call start.bat"

为养成良好的习惯,将$AppRoot括在嵌入双引号中(转义为`"),以正确处理包含空格的路径。尽管对于cmd.exe的{​​{1}}来说并不是必须的,但是实际上所有其他命令/程序都需要这样做。

请注意,我使用cd而不是/k作为/ccmd.exe)开关,以确保新窗口保持打开状态。


如果必须将$env:ComSpec设置为.UseShellExecute,请使用$False显式创建一个新窗口(需要Windows 10):

conhost.exe

在其他版本的Windows上,您可以使用CreateProcess() Windows API function使用P / Invoke直接调用CREATE_NEW_CONSOLE flag


[1]
*请注意,某些$process = New-Object System.Diagnostics.Process $process.startInfo.UseShellExecute = $false $process.startinfo.FileName = 'conhost.exe' $process.startInfo.Arguments = "cmd /k cd /d `"$AppRoot`" & call start.bat" $null = $process.Start() 参数,例如Start-Process-NoNewWindow,要求将-Credential设置为.UseShellExecute,在这种情况下,$False在后台使用WinAPI函数(而不是CreateProcess())。
*另请注意,在.NET Core 中,默认值为ShellExecute(),但是PowerShell Core的$False仍默认为Start-Process以匹配Windows PowerShell的行为。