How to create a new window and set UseShellExecute false in powershell?

末鹿安然 提交于 2021-02-19 07:35:12

问题


The requirement is a bit strange, I've encountered a strange stuck problem in multi-thread in powershell. So I want to create a new window and don't use shell Execute. But I cannot make it with below code, the window doesn't show up. $approot is desktop, in start.bat, just do "dir /s .\" I want the dir result shows in another window instead of the window execute this script, and I don't want use shell execute.

$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:


If you set .UseShellExecute to $False, you cannot start your command in a new window; the value of the .CreateNoNewWindow property is then effectively ignored.

Therefore, you may as well use Start-Process, which leaves .UseShellExecute at its default, $True[1].

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

To promote good habits, $AppRoot is enclosed in embedded double quotes (escaped as `") to properly deal with paths containing spaces. While this is not strictly necessary with cmd.exe's cd, it is with virtually all other commands / programs.

Note that I'm using /k rather than /c as the cmd.exe ($env:ComSpec) switch to ensure that the new windows stays open.


If setting .UseShellExecute to $False is a must, use conhost.exe to explicitly create a new window (requires Windows 10):

$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()

On other flavors / versions of Windows, you may be able to use P/Invoke to call the CreateProcess() Windows API function directly, using the CREATE_NEW_CONSOLE flag.


[1]
* Note that certain Start-Process parameters, such as -NoNewWindow and -Credential, require that .UseShellExecute be set to $False, in which case the CreateProcess() WinAPI function is used (rather than ShellExecute()) behind the scenes.
* Also note that in .NET Core the default is $False, but PowerShell Core's Start-Process still defaults to $True to match Windows PowerShell's behavior.



来源:https://stackoverflow.com/questions/52130413/how-to-create-a-new-window-and-set-useshellexecute-false-in-powershell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!