Windows powershell ise кодировка

Время на прочтение6 мин

Количество просмотров151K

В процессе разработки очень часто возникает необходимость запустить из powershell скрипта консольное приложение. Что может быть проще?

#test.ps1
& $PSScriptRoot\ConsoleApp.exe

Изучим поведение консольных приложений при запуске их из командной строки, через PowerShell и через PowerShell ISE:

Результат выполнения

В PowerShell ISE возникла проблема с кодировкой, так как ISE ожидает вывод в кодировке 1251. Воспользуемся гуглом и найдем два решения проблемы: c использованием [Console]::OutputEncoding и через powershell pipeline. Воспользуемся первым решением:

test2.ps1

$ErrorActionPreference = "Stop"

function RunConsole($scriptBlock)
{
    $encoding = [Console]::OutputEncoding 
    [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
    try
    {
        &$scriptBlock
    }
    finally
    {
        [Console]::OutputEncoding = $encoding
    }
}

RunConsole {
    & $PSScriptRoot\ConsoleApp1.exe
}

Результат выполнения

В командной строке все хорошо, а вот в ISE ошибка. Exception setting «OutputEncoding»: «The handle is invalid.». Снова берем в руки гугл, и в первом же результате находим решение — надо запустить какое-нибудь консольное приложение для создания консоли. Ну что-же, попробуем.

test3.ps1

$ErrorActionPreference = "Stop"

function RunConsole($scriptBlock)
{
    # Популярное решение "устранения" ошибки: Exception setting "OutputEncoding": "The handle is invalid."
    & cmd /c ver | Out-Null

    $encoding = [Console]::OutputEncoding 
    [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
    try
    {
        &$scriptBlock
    }
    finally
    {
        [Console]::OutputEncoding = $encoding
    }
}

RunConsole {
    & $PSScriptRoot\ConsoleApp1.exe
}

Результат выполнения

Все красиво, все работает. Кто читал мою прошлую заметку, обратил внимание, что WinRM приносит нам много острых впечатлений. Попробуем запустить тест через WinRM. Для запуска воспользуемся вот таким скриптом:

remote1.ps1

param($script)

$ErrorActionPreference = "Stop"

$s = New-PSSession "."
try
{
    $path = "$PSScriptRoot\$script"
    Invoke-Command -Session $s -ScriptBlock { &$using:path }
}
finally
{
    Remove-PSSession -Session $s
}

Результат выполнения

Что-то пошло не так. Решение с созданием консоли не работает. Ранее мы находили два решения проблемы кодировки. Попробуем второй:

test4.ps1

$ErrorActionPreference = "Stop"
#$VerbosePreference = "Continue"

function RunConsole($scriptBlock)
{
    function ConvertTo-Encoding ([string]$From, [string]$To)
    {
        Begin
        {
            $encFrom = [System.Text.Encoding]::GetEncoding($from)
            $encTo = [System.Text.Encoding]::GetEncoding($to)
        }
        Process
        {
            $bytes = $encTo.GetBytes($_)
            $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
            $encTo.GetString($bytes)
        }
    }

    Write-Verbose "RunConsole: Pipline mode"
    &$scriptBlock | ConvertTo-Encoding cp866 windows-1251 
}

RunConsole {
    & $PSScriptRoot\ConsoleApp1.exe
}

Результат выполнения

В ISE и через WinRM решение работает, а вот через командную строку и shell — нет.
Надо объединить эти два способа и проблема будет решена!

test5.ps1

$ErrorActionPreference = "Stop"
#$VerbosePreference = "Continue"

function RunConsole($scriptBlock)
{
    if([Environment]::UserInteractive)
    {
        # Популярное решение "устранения" ошибки: Exception setting "OutputEncoding": "The handle is invalid."
        & cmd /c ver | Out-Null

        $encoding = [Console]::OutputEncoding 
        [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")

        try
        {
            Write-Verbose "RunConsole: Console.OutputEncoding mode"
            &$scriptBlock
            return
        }
        finally
        {
            [Console]::OutputEncoding = $encoding
        }
    }

    function ConvertTo-Encoding ([string]$From, [string]$To)
    {
        Begin
        {
            $encFrom = [System.Text.Encoding]::GetEncoding($from)
            $encTo = [System.Text.Encoding]::GetEncoding($to)
        }
        Process
        {
            $bytes = $encTo.GetBytes($_)
            $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
            $encTo.GetString($bytes)
        }
    }

    Write-Verbose "RunConsole: Pipline mode"
    &$scriptBlock | ConvertTo-Encoding cp866 windows-1251 
}

RunConsole {
    & $PSScriptRoot\ConsoleApp1.exe
}

Результат выполнения

Кажется, что проблема решена, но продолжим исследование и усложним наше консольное приложение, добавив в него вывод в stdError.

Результат выполнения

Становится все веселее :) В ISE исполнение скрипта прервалось на середине, а через WinRM мало того, что прервалось, так еще сообщение из stdErr прочитать невозможно. Первым шагом решим проблему с остановкой запускаемого из скрипта приложения, для этого перед запуском приложения изменим значение глобальной переменной $ErrorActionPreference.

test7.ps1

$ErrorActionPreference = "Stop"
#$VerbosePreference = "Continue"

function RunConsole($scriptBlock)
{
    if([Environment]::UserInteractive)
    {
        # Популярное решение "устранения" ошибки: Exception setting "OutputEncoding": "The handle is invalid."
        & cmd /c ver | Out-Null

        $encoding = [Console]::OutputEncoding 
        [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")

        try
        {
            Write-Verbose "RunConsole: Console.OutputEncoding mode"
            $prevErrAction = $ErrorActionPreference
            $ErrorActionPreference = "Continue"
            try
            {
                &$scriptBlock
                return
            }
            finally
            {
                $ErrorActionPreference = $prevErrAction
            }
        }
        finally
        {
            [Console]::OutputEncoding = $encoding
        }
    }

    function ConvertTo-Encoding ([string]$From, [string]$To)
    {
        Begin
        {
            $encFrom = [System.Text.Encoding]::GetEncoding($from)
            $encTo = [System.Text.Encoding]::GetEncoding($to)
        }
        Process
        {
            $bytes = $encTo.GetBytes($_)
            $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
            $encTo.GetString($bytes)
        }
    }

    Write-Verbose "RunConsole: Pipline mode"
    $prevErrAction = $ErrorActionPreference
    $ErrorActionPreference = "Continue"
    try
    {
        &$scriptBlock | ConvertTo-Encoding cp866 windows-1251 
        return
    }
    finally
    {
        $ErrorActionPreference = $prevErrAction
    }
}

RunConsole {
    & $PSScriptRoot\ConsoleApp2.exe
}
Write-Host "ExitCode = $LASTEXITCODE"

Результат выполнения

Для тех что знает о существовании параметра -ErrorAction

error.cmd

echo error message 1>&2

errorActionTest.ps1

#error.cmd
#echo error message 1>&2

#errorActionTest.ps1
$ErrorActionPreference = "Stop"
Write-Host "before"
Invoke-Expression -ErrorAction SilentlyContinue -Command $PSScriptRoot\error.cmd
Write-Host "after"

Какой будет результат выполнения такого скрипта?

Вторым шагом доработаем скрипт удаленного запуска через WinRM, чтобы он не падал:

remote2.ps1

param($script)

$ErrorActionPreference = "Stop"

$s = New-PSSession "."
try
{
    $path = "$PSScriptRoot\$script"

    $err = @()
    $r = Invoke-Command -Session $s -ErrorAction Continue -ErrorVariable err -ScriptBlock `
    {
        $ErrorActionPreference = "Stop"
        & $using:path | Out-Host
        return $true
    } 

    if($r -ne $true)
    {
        Write-Error "The remote script was completed with an error"
    }

    if($err.length -ne 0)
    {
        Write-Warning "Error occurred on remote host"
    }
}
finally
{
    Remove-PSSession -Session $s
}

Результат выполнения

И осталось самое сложное — скорректировать сообщение формируемое через stdErr и при этом не изменить его положение в логе. В процессе решения этой задачи коллеги предложили самостоятельно создать консоль, воспользовавшись win api функцией AllocConsole.

test8.ps1

$ErrorActionPreference = "Stop"
#$VerbosePreference = "continue"

$consoleAllocated = [Environment]::UserInteractive
function AllocConsole()
{
    if($Global:consoleAllocated)
    {
        return
    }

    &cmd /c ver | Out-Null
    $a = @' 
[DllImport("kernel32", SetLastError = true)] 
public static extern bool AllocConsole(); 
'@

    $params = New-Object CodeDom.Compiler.CompilerParameters 
    $params.MainClass = "methods" 
    $params.GenerateInMemory = $true 
    $params.CompilerOptions = "/unsafe" 
 
    $r = Add-Type -MemberDefinition $a -Name methods -Namespace kernel32 -PassThru -CompilerParameters $params

    Write-Verbose "Allocating console"
    [kernel32.methods]::AllocConsole() | Out-Null
    Write-Verbose "Console allocated"
    $Global:consoleAllocated = $true
}

function RunConsole($scriptBlock)
{
    AllocConsole

    $encoding = [Console]::OutputEncoding 
    [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
    $prevErrAction = $ErrorActionPreference
    $ErrorActionPreference = "Continue"
    try
    {
        & $scriptBlock
    }
    finally
    {
        $ErrorActionPreference = $prevErrAction
        [Console]::OutputEncoding = $encoding
    }
}

RunConsole {
    & $PSScriptRoot\ConsoleApp2.exe
}
Write-Host "ExitCode = $LASTEXITCODE"

Избавится от информации, которую добавляет powershell к stdErr мне так и не удалось.

Надеюсь, что эта информация окажется полезной не только мне! :)

update 1
В некоторых сценариях использования создавалась дополнительная консоль, в которую выдавался результат выполнения скриптов. В скрипт test8.ps1 внесены исправления.

update 2
Так как у многих комментаторов статьи возникла путаница между понятиями набор символов (char set) и кодировка (encoding) хотел бы еще раз обратить внимание, что в статье решается проблема именно несоответствия кодировок консоли и вызываемого приложения.

Как можно увидеть из скрипта test8.ps1, кодировка указывается в статическом свойстве [Console]::OutputEncoding, и никто не мешает указать в нем одну из кодировок семейства unicode:

[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")

Но, для работы скрипта в стандартной консоли windows (aka cmd.exe) необходимо изменить шрифт консоли со стандартного «Rasters Fonts» на Consolas или «Lucida Console». Если бы данные скрипты мы использовали только на собственных рабочих станциях или серверах, то такое изменение было бы допустимо, но так как нам приходится распространять наши решения заказчикам, вмешиваться в системные настройки серверов мы не имеем права. Именно по этой причине в скриптах используется cp866, как кодировка настроенная по умолчанию для консоли.

В данной статье приведу несколько практических примеров по изменению кодировки в PowerShell. Ранее я уже публиковал статью про смену кодировки, когда не отображались кириллические символы, сейчас рассмотрю тему более подробно.

Смена кодировки вывода в консоль

Сменить кодировку вывода в консоль можно одним из предложенных ниже способов:

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")

В данных примерах меняем ее на utf8. Это решает проблему с отображением кириллицы. Решение будет действовать только в текущем сеансе консоли.

Кракозябры в PowerShell ISE можно побороть вот так (сменив кодировку на cp866):

[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')

При сборке скрипта в exe файл через Win-PS2EXE тоже были проблемы с кодировкой при выводе кириллицы:

В Windows 10 помогло это:

[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("windows-1251")

В Win7 нужную кодировку не подобрал.

Смена кодировки вывода в файл Out-File

Вывод результата консольной утилиты, запущенной через PowerShell, в txt файл выдавал кракозябры. Помогло использование параметра -Encoding и выбор кодировки oem в конвейере в качестве параметра командлета Out-File (в примере zab_api.exe это консольная утилита, вывод которой нужно было писать в файл).

.\zab_api.exe | Out-File data.txt -Encoding oem

Глобальная смена кодировки на уровне системы

В этом решении будет рассказано как решить этот вопрос глобально.

Win + R -> Intl.cpl -> OK

На вкладке «Дополнительно»(«Administrative») Измените язык для программ, не поддерживающих Юникод — выберите Русский (Russian)

Перезагрузите систему

Всем привет.

Традиционные приложения Windows запускаемые в консоли cmd.exe, как правило не являются unicode-приложениями. Иначе говоря, они ожидают ввод и выводят информацию в обычной кодировке, например, CP866 или CP1251. С другой стороны, Powershell является unicode-приложением. Это означает, что Powershell должен выполнять перекодировку в обе стороны при вызове native application. По умолчанию он это делает в большинстве случаев правильно. Но если на целевой системе вместо кодировки по умолчанию для non-unicode программ стоит не «Русский», что соответствует CP866, а «Английский» — CP437, при работе «русской» native application мы получим проблемы: программа не будет понимать ввод, а ее вывод будет абракадаброй.

В Powershell за перекодировку отвечают две переменные:

[Console]::OutputEncoding : отвечает за перекодировку <native application> -> <Powershell>

$OutputEncoding : отвечает за перекодировку <Powershell> -> <native application>

Есть ещё [Console]::InputEncoding, которая отвечает за ввод с клавиатуры в консольное приложение.

Например при попытке получить результат команды ping увидим такое:

Посмотрим кодировку в обоих консолях следующей командой [Console]::outputEncoding

ISE:

Powershell консоль:

И текущая кодовая страница по команде chcp: 866

Исправляем ситуацию — вставляем в рабочий профиль Powershell следующие три команды:

chcp

[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding(‘cp866’)

chcp

Выполняем:

’ҐЄгй п Є®¤®ў п бва ­Ёж : 866

Текущая кодовая страница: 866

Последняя проверка:

Все Ок.

It has been a long time since last time I’m posting on wordpress, I can find lots of excuses to explain why I’m not able to keep it updated, but this is another story I’m not talking about this time :). Let me start topic below.

I’ve been recently working with Powershell ISE(PowerShell v1.0) to edit Powershell code, with this simple piece of edit tool, creating PS scripts is more enjoyable. However, the ISE has bugs and some user-unfriendly designs, the encoding for ISE default SaveAs is one of those.

Powershell ISE by defult is saving files to ps1 extention with encoding “unicode big endian” while it doesn’t provide options for you to chose like what Noptepad has been doing.I’m not sure, but I’m guessing this is a valuable-to-chose feature for Powershell developers. As such, if you use tools like windiff to open these files, you will feel crappy like below.

Image

It was said that in Powershell 3.0(coming Win8), the default encoding has been set to UTF8. However, I’m guess lots of guys are still working on 1.0 or 2.0. The straightforward solution would be using Notepad to open the ps1 file, save it as the encoding you want, then you can edit it again using ISE, the encoding keeps to be the one you chose.

I googled and find below solution that uses ISE object model(http://technet.microsoft.com/en-us/library/bb978525.aspx).

Below is solution one.

#Change default file that is opened when PowerShell_ISE opens to UTF encoding.
$psise.CurrentPowerShellTab.Files | % { 
    # set private field which holds default encoding to UTF8
    $_.gettype().getfield("encoding","nonpublic,instance").setvalue($_, [text.encoding]::UTF8) 
}

another solution is to subscribe to collectionchanged event for files like below.

register-objectevent -EventObject $psise.CurrentPowerShellTab.Files -EventName collectionchanged -action { 
    # iterate ISEFile objects 
    $event.sender | % { 
         $_.gettype().getfield("encoding","nonpublic,instance").setvalue($_, [text.encoding]::UTF8) 
    } 
}

That is a bit awkward but it solves current issues before v3.0. Powershell has been cool enough for my work and I’m going to give more posts later then. C# programmer with script background might have felt its power in Windows environment, agree?

Note:

  • This answer shows how to switch the character encoding in the Windows console to
    (BOM-less) UTF-8 (code page 65001), so that shells such as cmd.exe and PowerShell properly encode and decode characters (text) when communicating with external (console) programs with full Unicode support, and in cmd.exe also for file I/O.[1]

  • If, by contrast, your concern is about the separate aspect of the limitations of Unicode character rendering in console windows, see the middle and bottom sections of this answer, where alternative console (terminal) applications are discussed too.


Does Microsoft provide an improved / complete alternative to chcp 65001 that can be saved permanently without manual alteration of the Registry?

As of (at least) Windows 10, version 1903, you have the option to set the system locale (language for non-Unicode programs) to UTF-8, but the feature is still in beta as of this writing.

To activate it:

  • Run intl.cpl (which opens the regional settings in Control Panel)
  • Follow the instructions in the screen shot below.

Control Panel data-lazy-src=

  • This sets both the system’s active OEM and the ANSI code page to 65001, the UTF-8 code page, which therefore (a) makes all future console windows, which use the OEM code page, default to UTF-8 (as if chcp 65001 had been executed in a cmd.exe window) and (b) also makes legacy, non-Unicode GUI-subsystem applications, which (among others) use the ANSI code page, use UTF-8.

    • Caveats:

      • If you’re using Windows PowerShell, this will also make Get-Content and Set-Content and other contexts where Windows PowerShell default so the system’s active ANSI code page, notably reading source code from BOM-less files, default to UTF-8 (which PowerShell Core (v6+) always does). This means that, in the absence of an -Encoding argument, BOM-less files that are ANSI-encoded (which is historically common) will then be misread, and files created with Set-Content will be UTF-8 rather than ANSI-encoded.

      • [Fixed in PowerShell 7.1] Up to at least PowerShell 7.0, a bug in the underlying .NET version (.NET Core 3.1) causes follow-on bugs in PowerShell: a UTF-8 BOM is unexpectedly prepended to data sent to external processes via stdin (irrespective of what you set $OutputEncoding to), which notably breaks Start-Job – see this GitHub issue.

      • Not all fonts speak Unicode, so pick a TT (TrueType) font, but even they usually support only a subset of all characters, so you may have to experiment with specific fonts to see if all characters you care about are represented – see this answer for details, which also discusses alternative console (terminal) applications that have better Unicode rendering support.

      • As eryksun points out, legacy console applications that do not “speak” UTF-8 will be limited to ASCII-only input and will produce incorrect output when trying to output characters outside the (7-bit) ASCII range. (In the obsolescent Windows 7 and below, programs may even crash).
        If running legacy console applications is important to you, see eryksun’s recommendations in the comments.

  • However, for Windows PowerShell, that is not enough:

    • You must additionally set the $OutputEncoding preference variable to UTF-8 as well: $OutputEncoding = [System.Text.UTF8Encoding]::new()[2]; it’s simplest to add that command to your $PROFILE (current user only) or $PROFILE.AllUsersCurrentHost (all users) file.
    • Fortunately, this is no longer necessary in PowerShell Core, which internally consistently defaults to BOM-less UTF-8.

If setting the system locale to UTF-8 is not an option in your environment, use startup commands instead:

Note: The caveat re legacy console applications mentioned above equally applies here. If running legacy console applications is important to you, see eryksun’s recommendations in the comments.

  • For PowerShell (both editions), add the following line to your $PROFILE (current user only) or $PROFILE.AllUsersCurrentHost (all users) file, which is the equivalent of chcp 65001, supplemented with setting preference variable $OutputEncoding to instruct PowerShell to send data to external programs via the pipeline in UTF-8:

    • Note that running chcp 65001 from inside a PowerShell session is not effective, because .NET caches the console’s output encoding on startup and is unaware of later changes made with chcp; additionally, as stated, Windows PowerShell requires $OutputEncoding to be set – see this answer for details.
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
  • For example, here’s a quick-and-dirty approach to add this line to $PROFILE programmatically:
'$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding' + [Environment]::Newline + (Get-Content -Raw $PROFILE -ErrorAction SilentlyContinue) | Set-Content -Encoding utf8 $PROFILE
  • For cmd.exe, define an auto-run command via the registry, in value AutoRun of key HKEY_CURRENT_USER\Software\Microsoft\Command Processor (current user only) or HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor (all users):

    • For instance, you can use PowerShell to create this value for you:
# Auto-execute `chcp 65001` whenever the current user opens a `cmd.exe` console
# window (including when running a batch file):
Set-ItemProperty 'HKCU:\Software\Microsoft\Command Processor' AutoRun 'chcp 65001 >NUL'

Optional reading: Why the Windows PowerShell ISE is a poor choice:

While the ISE does have better Unicode rendering support than the console, it is generally a poor choice:

  • First and foremost, the ISE is obsolescent: it doesn’t support PowerShell (Core) 7+, where all future development will go, and it isn’t cross-platform, unlike the new premier IDE for both PowerShell editions, Visual Studio Code, which already speaks UTF-8 by default for PowerShell Core and can be configured to do so for Windows PowerShell.

  • The ISE is generally an environment for developing scripts, not for running them in production (if you’re writing scripts (also) for others, you should assume that they’ll be run in the console); notably, with respect to running code, the ISE’s behavior is not the same as that of a regular console:

    • Poor support for running external programs, not only due to lack of supporting interactive ones (see next point), but also with respect to:

      • character encoding: the ISE mistakenly assumes that external programs use the ANSI code page by default, when in reality it is the OEM code page. E.g., by default this simple command, which tries to simply pass a string echoed from cmd.exe through, malfunctions (see below for a fix):
        cmd /c echo hü | Write-Output

      • Inappropriate rendering of stderr output as PowerShell errors: see this answer.

    • The ISE dot-sources script-file invocations instead of running them in a child scope (the latter is what happens in a regular console window); that is, repeated invocations run in the very same scope. This can lead to subtle bugs, where definitions left behind by a previous run can affect subsequent ones.

  • As eryksun points out, the ISE doesn’t support running interactive external console programs, namely those that require user input:

The problem is that it hides the console and redirects the process output (but not input) to a pipe. Most console applications switch to full buffering when a file is a pipe. Also, interactive applications require reading from stdin, which isn’t possible from a hidden console window. (It can be unhidden via ShowWindow, but a separate window for input is clunky.)

  • If you’re willing to live with that limitation, switching the active code page to 65001 (UTF-8) for proper communication with external programs requires an awkward workaround:

    • You must first force creation of the hidden console window by running any external program from the built-in console, e.g., chcp – you’ll see a console window flash briefly.

    • Only then can you set [console]::OutputEncoding (and $OutputEncoding) to UTF-8, as shown above (if the hidden console hasn’t been created yet, you’ll get a handle is invalid error).


[1] In PowerShell, if you never call external programs, you needn’t worry about the system locale (active code pages): PowerShell-native commands and .NET calls always communicate via UTF-16 strings (native .NET strings) and on file I/O apply default encodings that are independent of the system locale. Similarly, because the Unicode versions of the Windows API functions are used to print to and read from the console, non-ASCII characters always print correctly (within the rendering limitations of the console).
In cmd.exe, by contrast, the system locale matters for file I/O (with < and > redirections, but notably including what encoding to assume for batch-file source code), not just for communicating with external programs in-memory (such as when reading program output in a for /f loop).

[2] In PowerShell v4-, where the static ::new() method isn’t available, use $OutputEncoding = (New-Object System.Text.UTF8Encoding).psobject.BaseObject. See GitHub issue #5763 for why the .psobject.BaseObject part is needed.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Msi ge70 установка windows 10
  • Pantum m6200 m6500 m6550 m6600 series windows driver
  • Как отключить защитник windows 7 максимальная 64 bit
  • Как вернуть ноутбук к заводским настройкам windows 10 самсунг
  • Failed to reset windows update due to wuauserv service failing to stop