Я пытаюсь вызвать встроенную команду cmd, такую как echo в PowerShell, с помощью Invoke-Expression и преобразовать ее в массив байтов, но в выводе команды отсутствуют символы новой строки.
Пример:
([Text.Encoding]::ASCII).GetBytes((iex "cmd /c echo."))
Он ничего не возвращает вместо последовательности новой строки (CRLF).





Я нашел решение. Не идеально, но я запишу вывод в файл, прочитаю его с помощью [System.IO.File]::ReadAllBytes("path_to_the_file").
и сохранить в переменную
тл;др:
PS> ([text.encoding]::ASCII).GetBytes(((cmd /c echo.) -join "`r`n") + "`r`n")
13
10
As an aside: iex (Invoke-Expression) should be avoided
.
Прочтите справочную информацию и предостережения.
Когда PowerShell захватывает вывод stdout из внешней программы, такой как cmd.exe, он возвращает множество выхода линии с завершающей последовательностью новой строки подстриженный от каждого.
В качестве отступления: именно кодировка символов, о котором сообщает [console]::OutputEncoding, определяет, как PowerShell интерпретирует вывод, который в Windows PowerShell по умолчанию соответствует кодовой странице OEM устаревшей системной локали, и, на момент написания этой статьи, также — все еще — в PowerShell Core в Windows, хотя это надеюсь скоро изменится, учитывая, что PowerShell Core в противном случае использует (без спецификации) UTF-8 в качестве кодировки по умолчанию.
В вашем случае cmd /c echo. сгенерировал одну последовательность новой строки Windows, CRLF, которая в терминах PowerShell равна "`r`n" (вы также можете использовать [Environment]::NewLine для получения строки новой строки, соответствующей платформе).
PowerShell интерпретирует это как одну пустую строку, и из-за того, что в элементы массива не включена завершающая новая строка, а PowerShell разворачивает массив из одного элемента, вы получаете '', то есть пустой строки — вот почему вызов ([text.encoding]::ASCII).GetBytes() не произвел вывод.
Вы можете собрать массив строк вывода, созданный PowerShell, в одну многострочную строку вывода:
-join "`r`n")+ "`r`n")как показано выше.
Предостережения: это "повторная сборка" делает два предположения, которое не всегда может быть правдой:
Что внешняя программа действительно выдавала последовательности Windows CRLF, а не только символы UNIX LF.
Что внешняя программа действительно сгенерировала новую строку тянущийся, что обычно, но не обязательно верно.
Если эти предположения проблематичны, перенаправление вывода в файл и чтение тот — как и в твой собственный ответ — являются правильным решением.
Предостережение: > в Windows PowerShell по умолчанию создает файлы UTF-16LE (а также неизменно добавляет новую строку), поэтому вы не получите байтов ASCII; поэтому используйте перенаправление свояcmd для создания файла (который будет использовать устаревшую OEM-кодировку, указанную chcp, которая обычно представляет собой суперсет ASCII):
# Note that the `>` is *inside the quoted string* to ensure that it is
# cmd.exe that interprets it.
# (...) around `echo.` ensures that the space before `>` doesn't become
# part of the output.
PS> cmd /c '(echo.) >out.txt'; [IO.File]::ReadAllBytes("$PWD\out.txt")
13
10
Пожалуйста, сделайте шаг назад и опишите реальную проблему, которую вы пытаетесь решить, а не то, что вы считаете решением. Почему вы пытаетесь получить последовательность байтов новой строки, запустив
echoчерезInvoke-Expressionвместо, скажем,[Text.Encoding]::ASCII.GetBytes([Environment]::NewLine)или просто[byte[]](13,10)?