要求有点奇怪,我在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
答案 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
作为/c
(cmd.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的行为。