Udostępnij za pośrednictwem


Opis kodowania plików w programach VS Code i PowerShell

W przypadku tworzenia i edytowania skryptów programu PowerShell przy użyciu programu VS Code ważne jest, aby pliki zostały zapisane przy użyciu poprawnego formatu kodowania znaków.

Co to jest kodowanie plików i dlaczego jest to ważne?

Program VS Code zarządza interfejsem między człowiekiem wprowadzającymi ciągi znaków do buforu, a blokami odczytu/zapisu bajtów w systemie plików. Gdy program VS Code zapisuje plik, używa kodowania tekstu, aby zdecydować, jakie bajty stają się poszczególnymi znakami. Aby uzyskać więcej informacji, zobacz about_Character_Encoding.

Podobnie, gdy program PowerShell uruchamia skrypt, musi przekonwertować bajty w pliku na znaki, aby odtworzyć plik w programie PowerShell. Ponieważ program VS Code zapisuje plik i program PowerShell odczytuje plik, muszą używać tego samego systemu kodowania. Ten proces analizowania skryptu programu PowerShell jest następujący: bajty -znaki ->tokeny ->abstrakcyjne drzewo składni ->>wykonanie.

Program VS Code i program PowerShell są instalowane z rozsądną konfiguracją kodowania domyślnego. Jednak domyślne kodowanie używane przez program PowerShell zmieniło się wraz z wydaniem programu PowerShell 6. Aby upewnić się, że nie masz problemów z używaniem programu PowerShell lub rozszerzenia programu PowerShell w programie VS Code, musisz prawidłowo skonfigurować ustawienia programu VS Code i programu PowerShell.

Typowe przyczyny problemów z kodowaniem

Problemy z kodowaniem występują, gdy kodowanie programu VS Code lub plik skryptu nie jest zgodne z oczekiwanym kodowaniem programu PowerShell. Nie ma możliwości automatycznego określenia kodowania pliku przez program PowerShell.

Częściej występują problemy z kodowaniem, gdy używasz znaków spoza 7-bitowego zestawu znaków ASCII. Na przykład:

  • Rozszerzone znaki inne niż litery, takie jak em-dash (), spacja niełamiąca ( ) lub lewy podwójny cudzysłów (")
  • Akcentowane znaki łacińskie (É, ü)
  • Znaki inne niż łacińskie, takie jak cyrylica (Д, Ц)
  • Znaki CJK (, , )

Typowe przyczyny problemów z kodowaniem to:

  • Kodowanie programu VS Code i programu PowerShell nie zostało zmienione z ich wartości domyślnych. W przypadku programu PowerShell 5.1 lub starszego domyślne kodowanie różni się od programu VS Code.
  • Inny edytor otworzył i nadpisał plik w nowym kodowaniu. Dzieje się tak często w przypadku ise.
  • Plik jest sprawdzany w kontroli źródła w kodowaniu, które różni się od oczekiwanego programu VS Code lub programu PowerShell. Może się tak zdarzyć, gdy współpracownicy używają edytorów z różnymi konfiguracjami kodowania.

Jak powiedzieć, kiedy występują problemy z kodowaniem

Często błędy kodowania przedstawiają się jako błędy analizy w skryptach. Jeśli znajdziesz dziwne sekwencje znaków w skrypce, może to być problem. W poniższym przykładzie znak en-dash () jest wyświetlany jako znak â€":

Send-MailMessage : A positional parameter cannot be found that accepts argument 'Testing FuseMail SMTP...'.
At C:\Users\<User>\<OneDrive>\Development\PowerShell\Scripts\Send-EmailUsingSmtpRelay.ps1:6 char:1
+ Send-MailMessage â&euro;"From $from â&euro;"To $recipient1 â&euro;"Subject $subject  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Send-MailMessage], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SendMailMessage

Ten problem występuje, ponieważ program VS Code koduje znak w formacie UTF-8 jako bajty 0xE2 0x80 0x93. Gdy te bajty są dekodowane jako Windows-1252, są interpretowane jako znaki â&euro;".

Niektóre dziwne sekwencje znaków, które mogą być widoczne:

  • â&euro;" zamiast (kreska en-dash)
  • â&euro;" zamiast (kreska em)
  • Ä2 Zamiast Ä
  •   zamiast (spacja niełamiąca)
  • Ã&copy; Zamiast é

Ta przydatna dokumentacja zawiera listę typowych wzorców wskazujących problem z kodowaniem UTF-8/Windows-1252.

Jak rozszerzenie programu PowerShell w programie VS Code współdziała z kodowaniem

Rozszerzenie programu PowerShell współdziała ze skryptami na wiele sposobów:

  1. Gdy skrypty są edytowane w programie VS Code, zawartość jest wysyłana przez program VS Code do rozszerzenia. Protokół Language Server Protocol nakazuje przesyłanie tej zawartości w formacie UTF-8. W związku z tym rozszerzenie nie może uzyskać nieprawidłowego kodowania.
  2. Gdy skrypty są wykonywane bezpośrednio w konsoli zintegrowanej, są one odczytywane bezpośrednio z pliku przez program PowerShell. Jeśli kodowanie programu PowerShell różni się od kodu programu VS Code, coś może pójść nie tak tutaj.
  3. Gdy skrypt otwarty w programie VS Code odwołuje się do innego skryptu, który nie jest otwarty w programie VS Code, rozszerzenie powraca do ładowania zawartości tego skryptu z systemu plików. Rozszerzenie programu PowerShell domyślnie używa kodowania UTF-8, ale używa znacznika kolejności bajtów lub BOM, aby wybrać poprawne kodowanie.

Problem występuje podczas przy założeniu kodowania formatów bez BOM (takich jak UTF-8 bez BOM i Windows-1252). Rozszerzenie programu PowerShell domyślnie ma wartość UTF-8. Rozszerzenie nie może zmienić ustawień kodowania programu VS Code. Aby uzyskać więcej informacji, zobacz problem nr 824.

Wybieranie odpowiedniego kodowania

Różne systemy i aplikacje mogą używać różnych kodowań:

  • W środowisku .NET Standard w internecie i w świecie systemu Linux kodowanie UTF-8 jest teraz dominującym kodowaniem.
  • Wiele aplikacji .NET Framework używa protokołu UTF-16. Ze względów historycznych jest to czasami nazywane "Unicode", termin, który teraz odnosi się do szerokiego standardu , który obejmuje zarówno UTF-8, jak i UTF-16.
  • W systemie Windows wiele natywnych aplikacji, które poprzedzają Unicode, domyślnie używa systemu Windows-1252.

Kodowanie Unicode ma również pojęcie znacznika kolejności bajtów (BOM). BoMs występują na początku tekstu, aby poinformować dekoder, który koduje tekst. W przypadku kodowań wielo bajtowych model BOM wskazuje również endianness kodowania. Moduły BOM są przeznaczone do bajtów, które rzadko występują w tekście innym niż Unicode, co pozwala rozsądnie odgadnąć, że tekst jest Unicode, gdy BOM jest obecny.

BoMs są opcjonalne, a ich wdrażanie nie jest tak popularne w świecie systemu Linux, ponieważ niezawodna konwencja UTF-8 jest używana wszędzie. Większość aplikacji systemu Linux zakłada, że wprowadzanie tekstu jest kodowane w formacie UTF-8. Chociaż wiele aplikacji systemu Linux rozpoznaje i prawidłowo obsługuje model BOM, liczba nie prowadzi do artefaktów w tekście manipulowanych tymi aplikacjami.

W związku z tym:

  • Jeśli pracujesz głównie z aplikacjami systemu Windows i programem Windows PowerShell, wolisz kodowanie, takie jak UTF-8 z modelem BOM lub UTF-16.
  • Jeśli pracujesz na różnych platformach, wolisz stosować model UTF-8 z modelem BOM.
  • Jeśli pracujesz głównie w kontekstach skojarzonych z systemem Linux, należy preferować utF-8 bez modelu BOM.
  • Windows-1252 i latin-1 to zasadniczo starsze kodowanie, których należy unikać, jeśli to możliwe. Jednak niektóre starsze aplikacje systemu Windows mogą zależeć od nich.
  • Warto również zauważyć, że podpisywanie skryptu jest zależne od kodowania, co oznacza, że zmiana kodowania na podpisanym skrycie będzie wymagać rezygnacji.

Konfigurowanie programu VS Code

Domyślne kodowanie programu VS Code to UTF-8 bez modelu BOM.

Aby ustawić kodowanie programu VS Code, przejdź do ustawień programu VS Code (Ctrl+,) i ustaw "files.encoding" ustawienie:

"files.encoding": "utf8bom"

Niektóre możliwe wartości to:

  • utf8: [UTF-8] bez BOM
  • utf8bom: [UTF-8] z modelem BOM
  • utf16le: Little endian [UTF-16]
  • utf16be: Big endian [UTF-16]
  • windows1252: [Windows-1252]

Lista rozwijana powinna zostać wyświetlona w widoku graficznego interfejsu użytkownika lub zakończenia w widoku JSON.

Możesz również dodać następujące elementy do kodowania autowykrywania, jeśli to możliwe:

"files.autoGuessEncoding": true

Jeśli nie chcesz, aby te ustawienia wpływały na wszystkie typy plików, program VS Code zezwala również na konfiguracje poszczególnych języków. Utwórz ustawienie specyficzne dla języka, umieszczając ustawienia w [<language-name>] polu. Na przykład:

"[powershell]": {
    "files.encoding": "utf8bom",
    "files.autoGuessEncoding": true
}

Warto również rozważyć zainstalowanie trackera języka Gremlins dla programu Visual Studio Code. To rozszerzenie ujawnia niektóre znaki Unicode, które łatwo uszkodzone, ponieważ są niewidoczne lub wyglądają jak inne normalne znaki.

Konfigurowanie programu PowerShell

Domyślne kodowanie programu PowerShell różni się w zależności od wersji:

  • W programie PowerShell 6 lub nowszym domyślnym kodowaniem jest UTF-8 bez funkcji BOM na wszystkich platformach.
  • W programie Windows PowerShell domyślne kodowanie to zwykle Windows-1252, czyli rozszerzenie latin-1 (znane również jako ISO 8859-1).

W programie PowerShell 5+ możesz znaleźć domyślne kodowanie przy użyciu następującego polecenia:

[psobject].Assembly.GetTypes() | Where-Object { $_.Name -eq 'ClrFacade'} |
  ForEach-Object {
    $_.GetMethod('GetDefaultEncoding', [System.Reflection.BindingFlags]'nonpublic,static').Invoke($null, @())
  }

Poniższy skrypt może służyć do określenia kodowania wnioskowania sesji programu PowerShell dla skryptu bez modelu BOM.

$badBytes = [byte[]]@(0xC3, 0x80)
$utf8Str = [System.Text.Encoding]::UTF8.GetString($badBytes)
$bytes = [System.Text.Encoding]::ASCII.GetBytes('Write-Output "') + [byte[]]@(0xC3, 0x80) + [byte[]]@(0x22)
$path = Join-Path ([System.IO.Path]::GetTempPath()) 'encodingtest.ps1'

try
{
    [System.IO.File]::WriteAllBytes($path, $bytes)

    switch (& $path)
    {
        $utf8Str
        {
            return 'UTF-8'
            break
        }

        default
        {
            return 'Windows-1252'
            break
        }
    }
}
finally
{
    Remove-Item $path
}

Program PowerShell można skonfigurować tak, aby używał danego kodowania bardziej ogólnie przy użyciu ustawień profilu. Odwiedź następujące artykuły:

Nie można wymusić użycia określonego kodowania danych wejściowych przez program PowerShell. Program PowerShell 5.1 lub nowszy, uruchomiony w systemie Windows z ustawieniami regionalnymi ustawionymi na en-US, domyślnie używa kodowania Windows-1252, gdy nie ma modelu BOM. Inne ustawienia regionalne mogą używać innego kodowania. Aby zapewnić współdziałanie, najlepiej zapisać skrypty w formacie Unicode przy użyciu modelu BOM.

Ważne

Na wszystkie inne narzędzia, na które są używane skrypty programu PowerShell, mogą mieć wpływ wybory kodowania lub ponowne kodowanie skryptów do innego kodowania.

Istniejące skrypty

Skrypty już w systemie plików mogą wymagać ponownego kodowania do nowego wybranego kodowania. Na dolnym pasku programu VS Code zobaczysz etykietę UTF-8. Kliknij go, aby otworzyć pasek akcji, a następnie wybierz pozycję Zapisz z kodowaniem. Teraz możesz wybrać nowe kodowanie dla tego pliku. Aby uzyskać pełne instrukcje, zobacz Kodowanie programu VS Code.

Jeśli musisz ponownie zakodować wiele plików, możesz użyć następującego skryptu:

Get-ChildItem *.ps1 -Recurse | ForEach-Object {
    $content = Get-Content -Path $_
    Set-Content -Path $_.Fullname -Value $content -Encoding UTF8 -PassThru -Force
}

Zintegrowane środowisko skryptów programu PowerShell (ISE)

Jeśli edytujesz również skrypty przy użyciu środowiska PowerShell ISE, musisz zsynchronizować ustawienia kodowania.

IsE powinien honorować model BOM, ale można również użyć odbicia w celu ustawienia kodowania. Należy pamiętać, że nie będzie to utrwalane między uruchamianiami.

Oprogramowanie do kontroli źródła

Niektóre narzędzia kontroli źródła, takie jak git, ignorują kodowanie; usługa git śledzi bajty. Inne, takie jak Azure DevOps lub Mercurial, mogą nie. Nawet niektóre narzędzia oparte na narzędziu git polegają na dekodowaniu tekstu.

W takim przypadku upewnij się, że:

  • Skonfiguruj kodowanie tekstu w kontroli źródła, aby było zgodne z konfiguracją programu VS Code.
  • Upewnij się, że wszystkie pliki są zaewidencjonowane w kontroli źródła w odpowiednim kodowaniu.
  • Należy uważać na zmiany w kodowaniu odebranym za pomocą kontroli źródła. Kluczowym znakiem tego jest różnica wskazująca zmiany, ale gdzie nic się nie zmieniło (ponieważ bajty mają, ale znaki nie mają).

Środowiska współpracowników

W oparciu o konfigurowanie kontroli źródła upewnij się, że współpracownicy na wszystkich udostępnionych plikach nie mają ustawień, które przesłaniają kodowanie przez ponowne kodowanie plików programu PowerShell.

Inne programy

Każdy inny program, który odczytuje lub zapisuje skrypt programu PowerShell, może go ponownie zakodować.

Niektóre przykłady:

  • Kopiowanie i wklejanie skryptu za pomocą schowka. Jest to typowe w scenariuszach, takich jak:
    • Kopiowanie skryptu do maszyny wirtualnej
    • Kopiowanie skryptu z wiadomości e-mail lub strony internetowej
    • Kopiowanie skryptu do lub z dokumentu programu Microsoft Word lub PowerPoint
  • Inne edytory tekstów, takie jak:
    • Notatnik
    • vim
    • Dowolny inny edytor skryptów programu PowerShell
  • Narzędzia do edycji tekstu, takie jak:
    • Get-Content/Set-Content/Out-File
    • Operatory przekierowania programu PowerShell, takie jak > i >>
    • sed/awk
  • Programy transferu plików, takie jak:
    • Przeglądarka internetowa podczas pobierania skryptów
    • Udział plików

Niektóre z tych narzędzi zajmują się bajtami, a nie tekstem, ale inne oferują konfiguracje kodowania. W takich przypadkach, w których trzeba skonfigurować kodowanie, należy ustawić go tak samo jak kodowanie edytora, aby zapobiec problemom.

Inne zasoby dotyczące kodowania w programie PowerShell

Istnieje kilka innych miłych wpisów dotyczących kodowania i konfigurowania kodowania w programie PowerShell, które warto przeczytać: