Start-Process -RedirectStandardInput $null -FilePath powershell.exe -ArgumentList "myprogram.exe arg



unix的powershell等价物是什么<dev/null";使用启动过程时?在unix中,我会这样做:;myprogram.exe arg1 arg2<dev/null":

我在powershell中尝试了同样的启动过程:

Start-Process -RedirectStandardInput $null -FilePath powershell.exe -ArgumentList "myprogram.exe arg1 arg2"

错误消息,它不起作用:

Start-Process : Cannot validate argument on parameter 'RedirectStandardInput'. The argument is null or empty. Provide an argument that is not null or
empty, and then try the command again.
At line:1 char:38
+ Start-Process -RedirectStandardInput $null -FilePath powershell.exe - ...
+                                      ~~~~~
+ CategoryInfo          : InvalidData: (:) [Start-Process], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.StartProcessCommand

必须有更好的方法:

PS> $temp = New-TemporaryFile
PS> start-process powershell.exe -ArgumentList "gci C:" -nnw -wait -RedirectStandardInput $temp 

这是可行的,但它会在临时文件夹中创建一百万个空文件来清除。

另一种可能性:

PS> start-process powershell.exe -ArgumentList "`$null `| gci C:" -nnw -wait

使用直接、同步调用:

# Provide empty stdin input to myprogram.exe
# Equivalent to the following in a Unix shell:
#     myprogram.exe arg1 arg2 </dev/null
@() | myprogram.exe arg1 arg2

注:

正如js2010所建议的,
  • $null也可以工作,但只有与外部程序一起使用-PowerShell命令将接收实际的$null作为输入
  • 相比之下,@()(一个空数组(始终通过管道发送nothing(外部程序通过stdin接收管道输入(,因为正发送的是数组的元素,一个接一个(如果有的话(,而空数组根据定义没有元素(

默认情况下使用异步Start-Process调用

注:

  • Start-Process仅在异常调用场景中需要,例如需要在new控制台窗口中启动命令(包括提升(或需要使用不同的用户身份运行(;对于将流连接到PowerShell的CLI的同步执行,请使用上面显示的直接调用技术。有关Start-Process何时合适或不合适的指导,请参阅GitHub文档#6239

从PowerShell 7.2开始,只能将文件路径传递给Start-Process-Redirect*参数。

  • GitHub问题#5184提出了一个潜在的未来增强,也将允许使用变量,使用variable:null等符号

因此,要通过Start-Process有效地传递空的stdin输入,您必须将-RedirectStandardInput与(临时(空文件(0字节(一起使用,如您自己的答案所示。

  • Unix类平台上,应该能够使用-RedirectStandardInput /dev/null,但由于长期存在的错误,CCD_13在PowerShell 7.2.1时不起作用:发送换行而不是没有stdin输入-请参阅GitHub问题#8702。也就是说,Start-Process在Unix上很少有用,因为它无法在新窗口中启动进程。

  • 不幸的是,在Windows上,删除临时文件需要等待启动的程序退出,因为在此之前文件将被锁定。因此,为了可靠地清理以这种方式使用的临时文件,您必须使用:

    • -Wait,使呼叫同步
    • -PassThru,返回一个System.Diagnostics.Process,您可以稍后监视进程是否已退出(通过.HasExited.WaitForExit()(

但是,有一个解决方法:通过cmd.exe调用并使用<NUL重定向(相当于Unix中的</dev/null(:

# Parameters -FilePath and -ArgumentList positionally implied.
Start-Process cmd.exe '/c "myprogram.exe arg1 arg2 <NUL"'

或者,如果你仍然需要一个新的PowerShell实例,你可以在你传递的命令行中使用它的直接调用语法:

Start-Process powershell.exe '-c "@() | myprogram.exe arg1 arg2"'

注:

  • 基于cmd的解决方法更快、更轻,因此如果调用myprogram.exe是唯一需要的操作,则是更好的选择。

  • 更普遍地说,委派给cmd.exe的管道和重定向运算符(类似地,在Unix上委派给CCD26的(是一种变通方法,可以绕过PowerShell的管道当前不能用作原始字节管道的限制,例如,如果试图用>捕获原始字节输出,则会导致数据损坏;Start-Process'-Redirect*参数同上-请参阅此答案。

  • 通过这个答案中详细介绍的额外工作,您还可以通过下面显示的与System.Diagnostics.Process相关的.NETAPI来实现原始字节处理。


通过直接使用System.Diagnostics.Process相关的.NET API

注意

  • 您将无法在新控制台窗口中以这种方式启动进程,因为这需要将System.Diagnostics.ProcessStartInfo实例的.UseShellExecute属性设置为$true,而.RedirectStandardInput的使用排除了
# Configure the process to launch.
$ps = [System.Diagnostics.Process] @{
StartInfo = [System.Diagnostics.ProcessStartInfo] @{ 
FileName = 'myprogram.exe'
Arguments = 'arg1 arg2'
UseShellExecute = $false # Required for use of .Redirect* properties
RedirectStandardInput = $true # Provide stdin input programmatically below
WorkingDirectory = $PWD.ProviderPath # Use PowerShell's current dir.
}
}
$null = $ps.Start() # Launch asynchronously
$ps.StandardInput.Close() # Close stdin, effectively providing no input.
$ps.WaitForExit()  # Wait for the process to exit.

最新更新