“WriteLine”停止写入文件,(Windows PowerShell)

eyh26e7m  于 2023-05-08  发布在  Windows
关注(0)|答案(1)|浏览(193)

我试图创建一个脚本的大学,排序的进程数量在系统中的处理数量,并保存在一个文件中。到目前为止一切顺利,听起来很容易。但是当我以为我已经完成了它时,我意识到“WriteLine”在缺少几个进程时会停止写入,并使输出不完整。我已经通过调试检查了进程列表是OK的,但我无法找出导致问题的原因。
下面是代码和输出:

# Comprobación de la existencia del directorio C:\Temp
if (-not (Test-Path -Path "C:\Temp" -PathType Container)) {
    Write-Host "El directorio C:\Temp no existe. Abortando la ejecución del script."
    exit
}

# Solicitar el nombre del fichero de salida y cargarlo en la variable $Fichero
$Fichero = Read-Host "Introduzca el nombre del fichero de salida"

# Generación de una línea en blanco en la consola
Write-Host ""

# Guardar en el array $Procesos todos los procesos en ejecución ordenados por su número de handles
$Procesos = Get-Process | Sort-Object -Property HandleCount

# Creación del fichero informativo

    # Abrir o crear el archivo en C:\Temp\$Fichero.txt para escritura
    $handle = [System.IO.File]::Open("C:\Temp\$Fichero.txt", 'OpenOrCreate', 'ReadWrite')
    $writer = New-Object System.IO.StreamWriter($handle)

    ######## Procesos entre 0 y 100 ########
    # Escribir en el fichero el intervalo de procesos
    $writer.WriteLine("######## Procesos entre 0 y 100 ########")

    # Escribir en el fichero una cabecera apropiada para la tabla de procesos
    $writer.WriteLine("{0,-10} {1,-40} {2,20}", "Id", "Nombre", "Número de handles")
    $writer.WriteLine("{0,-10} {1,-40} {2,20}", "==" * 4, "==" * 10, "==" * 19)

    # Escribir en el fichero informativo los procesos cuyo Nº de handles se encuentre entre 0 y 100
    # Para ello, se utilizará un bucle foreach.
    foreach ($p in $Procesos) {
        if ($p.HandleCount -ge 0 -and $p.HandleCount -le 100) {
            $Linea = "{0,-10} {1,-40} {2,20}" -f $p.Id, $p.ProcessName, $p.HandleCount
            $writer.WriteLine($Linea)
        }
    }

    $writer.WriteLine("")

    ####### Procesos entre 101 y 1000 ########
    # Escribir en el fichero el intervalo de procesos
    $writer.WriteLine("####### Procesos entre 101 y 1000 ########")

    # Escribir en el fichero una cabecera apropiada para la tabla de procesos
    $writer.WriteLine("{0,-10} {1,-40} {2,20}", "Id", "Nombre", "Número de handles")
    $writer.WriteLine("{0,-10} {1,-40} {2,20}", "==" * 4, "==" * 10, "==" * 19)

    # Escribir en el fichero informativo los procesos cuyo Nº de handles se encuentre entre 101 y 1000
    foreach ($p in $Procesos) {
        if ($p.HandleCount -ge 101 -and $p.HandleCount -le 1000) {
            $Linea = "{0,-10} {1,-40} {2,20}" -f $p.Id, $p.ProcessName, $p.HandleCount
            $writer.WriteLine($Linea)
            Write-Host $Linea
         }
      }

####### Procesos de 1001 o mas ########
    # Escribir en el fichero el intervalo de procesos
    $writer.WriteLine("####### Procesos de 1001 o mas ########")

    # Escribir en el fichero una cabecera apropiada para la tabla de procesos
    $writer.WriteLine("{0,-10} {1,-40} {2,20}", "Id", "Nombre", "Número de handles")
    $writer.WriteLine("{0,-10} {1,-40} {2,20}", "==" * 4, "==" * 10, "==" * 19)

    # Escribir en el fichero informativo los procesos cuyo Nº de handles se encuentre de 1001 o mas
    foreach ($p in $Procesos) {
        if ($p.HandleCount -ge 1001) {
            $Linea = "{0,-10} {1,-40} {2,20}" -f $p.Id, $p.ProcessName, $p.HandleCount
            $writer.WriteLine($Linea)
            Write-Host $Linea
         }
      }
    Write-Host "Fin"
    $writer.WriteLine("Final")

    $handle.Close()

文件中的输出:

我想要的真实的输出:

谢谢你的帮助。
我试着通过:

Add-Content $path "###################### Processes between 0 and 100 handles #####################"

# Write in the file an appropriate header for the process table.
 Add-Content $path ('{0,-25} {1,-25} {2,25}' -f "Id", "Name", "Number of handles")

 Add-Content $ruta ("=============================================================================")

# Write in the info file the processes whose number of handles is between 0 and 100.
# between 0 and 100. To do this, a foreach loop will be used.

# Inside the loop body, the information # corresponding to each process will be generated in the variable $Line.
# corresponding to each process. Extended string formatting will be used to # format each line appropriately.
# will be used to format each line appropriately.
foreach($linea in $Processes)
{
    if(($linea.handles -ge 0) -and ($linea.handles -le 100)){
        $id=$linea.Id
        $name=$linea.Name
        $nHandles=$$linea.Handles
        Add-Content $path ('{0,-25} {1,-25} {2,25}' -f $id,$name,$nHandles)
    }

这是可行的,但我需要用另一种形式来做。

kq4fsx7k

kq4fsx7k1#

您的代码的问题是,您正在调用$handle.Close()关闭FileStream,但没有首先调用$writer.Dispose(),这将确保剩余的缓冲区写入您的文件。
StreamWriter缓冲数据,直到达到限制,并将缓冲的数据作为一个整体写入(默认缓冲区大小为1024个字符,请参阅streamwriter.cs)。例如,如果我们启用AutoFlush,情况就不是这样了。
我们还建议使用.Dispose(),因为这个方法已经在内部调用了.Close()。下面的模式是实现try / catch / finally的方法。

try {
    $Procesos = Get-Process | Sort-Object -Property HandleCount
    $handle = [System.IO.File]::Open("$pwd\test.txt", 'OpenOrCreate', 'ReadWrite')
    $writer = New-Object System.IO.StreamWriter($handle)
    # do stuff here...
}
catch {
    # error handling here
    Write-Error -Exception $_
}
finally {
    # dispose stuff
    if($writer) {
        $writer.Dispose()
    }

    if($handle) {
        $handle.Dispose()
    }
}

相关问题