W rzeczywistości zestaw znaków używany przez tasklist
jest zawsze inny niż domyślny system.
Z drugiej strony całkiem bezpiecznie jest używać wartości domyślnej, o ile moc wyjściowa jest ograniczona do ASCII. Zwykle moduły wykonywalne mają tylko nazwy ASCII w swoich nazwach.
Aby uzyskać poprawne łańcuchy, należy zamienić (ANSI) stronę kodową systemu Windows na stronę kodową OEM i przekazać ją jako zestaw znaków do InputStreamReader
.
Wygląda na to, że nie ma kompleksowego odwzorowania między tymi kodowaniami. Poniższy mapowania można stosować:
Map<String, String> ansi2oem = new HashMap<String, String>();
ansi2oem.put("windows-1250", "IBM852");
ansi2oem.put("windows-1251", "IBM866");
ansi2oem.put("windows-1252", "IBM850");
ansi2oem.put("windows-1253", "IBM869");
Charset charset = Charset.defaultCharset();
String streamCharset = ansi2oem.get(charset.name());
if (streamCharset) {
streamCharset = charset.name();
}
InputStreamReader isr = new InputStreamReader(p.getInputStream(),
streamCharset);
Takie podejście pracował dla mnie z windows-1251
i IBM866
pary.
Aby uzyskać aktualne kodowanie OEM używane przez system Windows, można użyć funkcji GetOEMCP
.Wartość zwracana zależy od ustawienia Język dla programów nieobsługujących kodu Unicode ustawienie Administracja zakładka w Panel sterowania dla regionu i języka. Aby zastosować zmianę, wymagane jest ponowne uruchomienie.
Istnieją dwa rodzaje kodowania w systemie Windows: ANSI i OEM.
To pierwsze jest używane przez aplikacje nie obsługujące kodu Unicode w trybie GUI.
Ten drugi jest używany przez aplikacje konsoli. Aplikacje konsoli nie mogą wyświetlać znaków, które nie mogą być reprezentowane w aktualnym kodowaniu OEM.
Od tasklist
jest aplikacją trybu konsoli, jej wyjście jest zawsze w aktualnym kodowaniu OEM.
W przypadku systemów angielskich, para ta zwykle jest Windows-1252 i CP850.
Ponieważ jestem w Rosji, mój system ma następujące kodowania: Windows-1251 i CP866.
Gdybym przechwycić wyjście tasklist
do pliku, plik nie może wyświetlać znaki cyrylicy poprawnie:
uzyskać ЏаЁўҐв
zamiast Привет
patrząc w Notatniku (Cześć!).
I µTorrent
jest wyświetlany jako зTorrent
.
Nie można zmienić kodowania używanego przez tasklist
.
Istnieje jednak możliwość zmiany kodowania wyjściowego cmd
. Jeśli przejdziesz na /u
, wyświetli on wszystko w kodowaniu UTF-16.
cmd /c echo Hi>echo.txt
Wielkość echo.txt
wynosi 4: dwa bajty w bajtach dla Hi
oraz dwa bajty do nowej linii (\r
i \n
).
cmd /u /c echo Hi>echo.txt
Teraz wielkość echo.txt
jest 8 bajtów: każdy znak jest reprezentowany z dwóch bajtów.
Czy jest tu pytanie? Spróbowałeś i zobaczysz? –
@JimGarrison Dostałem ostrzeżenie od FindBugs o * "poleganiu na domyślnym kodowaniu" * w InputStreamReader i nie mam pojęcia, czy to może spowodować problem, czy nie. Więc szukałem i znalazłem drugi post, który wydaje się mówić, że może. Właśnie to chcę sprawdzić. Na moim komputerze ten kod działa dobrze. – assylias
Dodam to jako komentarz, a nie pytanie, ponieważ moja niepewność jest dość duża. Powiedziałbym jednak, że zestaw znaków używany przez takie narzędzie systemowe będzie domyślnym ustawieniem dla instalacji systemu operacyjnego. Zapytanie o to locale i użycie go do interpretacji strumienia wyjściowego wydaje się być najbardziej ogólnym podejściem. Ale jeśli istnieją również lokalizacje, musisz odwrócić inżynierię pól, które mogą ulec zmianie, aby je przeanalizować. Wszystko to zależy od tego, czy narzędzie, o którym mowa, zostało napisane w ten sposób w różny sposób. – eh9