Rufen Sie eine Liste von Prozessen unter Windows auf sichere Weise ab

7

Dieser Beitrag gibt eine Lösung zum Abrufen der Liste der laufenden Prozesse unter Windows. Im Wesentlichen tut es:

%Vor%

liest dann die Eingabe.

Es sieht gut aus und funktioniert gut, aber ich frage mich, ob es möglich ist, dass der Zeichensatz, der von Tasklist verwendet wird, nicht der Standard-Zeichensatz ist und dass dieser Aufruf fehlschlagen könnte?

Zum Beispiel diese andere Frage zu einer anderen ausführbaren Datei zeigt, dass dies zu Problemen führen kann.

Wenn das der Fall ist, gibt es eine Möglichkeit zu bestimmen, was der richtige Zeichensatz wäre?

    
assylias 12.11.2012, 17:52
quelle

4 Antworten

11

Kann das in zwei Teile zerlegen:

  1. Der Windows-Teil
    Von Java aus führen Sie einen Windows-Befehl aus - extern zum jvm in "Windows land". Wenn die java Runtime-Klasse einen Windows-Befehl ausführt, verwendet sie die DLL für Konsolen & amp; So erscheint Windows, als ob der Befehl in einer Konsole ausgeführt wird. Q: Wenn ich C: \ windows \ system32 \ tasklist.exe in einer Konsole ausführe, wie lautet die Zeichencodierung ("Codepage" in Windows) Terminologie) des Ergebnisses?

    • windows "chcp" -Befehl ohne Argument gibt die aktive Codeseitenzahl für die Konsole an (z. B. 850 für Multilingual-Latin-1, 1252 für Latin-1). Siehe Microsoft Windows-Codepages , Windows-OEM-Codepages , Windows-ISO-Codepages
      Die Standard-System-Codepage wurde ursprünglich entsprechend Ihrer System-Ländereinstellung eingerichtet (geben Sie systeminfo ein, um dies zu sehen, oder Systemsteuerung- & gt; Region und Sprache).
    • die Windows OS / .NET-Funktion getACP () auch gibt diese Info
        

    •   
  2. Der Java-Teil:
    Wie dekodiere ich einen Java-Byte-Stream von der Windows-Codepage von "x" (z. B. 850 oder 1252)?

    • Die vollständige Zuordnung zwischen Windows-Codeseitenzahlen und entsprechenden Java-Zeichensatznamen kann von here - Code Page Identifier (Windows)
    • In der Praxis kann jedoch eines der folgenden Präfixe hinzugefügt werden, um das Mapping zu erreichen:
      "" (keine) für ISO, "IBM" oder "x-IBM" für OEM, "windows" oder "x-windows" für Microsoft / Windows.
      Z.B. ISO-8859-1 oder IBM850 oder Windows-1252

Vollständige Lösung:

%Vor%

Danke für das Q! - hat Spaß gemacht.

    
Glen Best 20.11.2012, 23:01
quelle
5

Tatsächlich unterscheidet sich der von tasklist verwendete Zeichensatz immer vom Systemstandard.

Auf der anderen Seite ist es ziemlich sicher, den Standard zu verwenden, solange die Ausgabe auf ASCII beschränkt ist. Normalerweise haben ausführbare Module nur ASCII-Zeichen in ihren Namen.

Um die richtigen Zeichenfolgen zu erhalten, müssen Sie die (ANSI-) Windows-Codepage in die OEM-Codepage konvertieren und letztere als Zeichensatz an InputStreamReader übergeben.

Es scheint, dass es zwischen diesen Kodierungen keine umfassende Zuordnung gibt. Die folgende Zuordnung kann verwendet werden:

%Vor%

Dieser Ansatz funktionierte für mich mit windows-1251 und IBM866 pair.

Um die aktuelle von Windows verwendete OEM-Codierung zu erhalten, können Sie GetOEMCP Funktion. Der Rückgabewert hängt von der Einstellung Sprache für Nicht-Unicode-Programme auf der Registerkarte Verwaltung im Kontrollfeld Region und Sprache ab. Neustart ist erforderlich, um die Änderung zu übernehmen.

Unter Windows gibt es zwei Arten von Codierungen: ANSI und OEM .

Ersteres wird von Nicht-Unicode-Anwendungen verwendet, die im GUI-Modus ausgeführt werden.
Letzteres wird von Konsolenanwendungen verwendet. Konsolenanwendungen können keine Zeichen anzeigen, die in der aktuellen OEM-Codierung nicht dargestellt werden können.

Da tasklist eine Konsole-Modus-Anwendung ist, liegt ihre Ausgabe immer in der aktuellen OEM-Codierung.

Für englische Systeme lautet das Paar normalerweise Windows-1252 und CP850 .

Wie ich in Russland bin, hat mein System die folgenden Kodierungen: Windows-1251 und CP866 .
Wenn ich die Ausgabe von tasklist in eine Datei aufnehme, kann die Datei kyrillische Zeichen nicht korrekt anzeigen:

  

Ich bekomme ЏаЁўҐв anstelle von Привет (Hallo!) , wenn Sie im Editor angezeigt werden.
  Und µTorrent wird als зTorrent angezeigt.

Sie können die von tasklist verwendete Codierung nicht ändern.

Es ist jedoch möglich, die Ausgabecodierung von cmd zu ändern. Wenn Sie /u an ihn übergeben, wird alles in UTF-16-Codierung ausgegeben.

%Vor%

Die Größe von echo.txt ist 4 Bytes: zwei Bytes für Hi und zwei Bytes für neue Zeile ( \r und \n ).

%Vor%

Jetzt ist die Größe von echo.txt 8 Bytes: Jedes Zeichen wird mit zwei Bytes dargestellt.

    
Alexey Ivanov 19.11.2012 21:45
quelle
2

Warum nicht die Windows-API über JNA anstelle von Launch-Prozessen verwenden? So:

%Vor%

Ich habe eine ähnliche Antwort woanders gepostet.

    
mikeslattery 20.11.2012 17:28
quelle
0

Es gibt eine viel bessere Möglichkeit, die laufenden Prozesse zu überprüfen oder sogar den OS-Befehl über Java auszuführen: Process und ProcessBuilder .

Was den Zeichensatz betrifft, können Sie das Betriebssystem immer nach den unterstützten Zeichensätzen fragen und erhalten eine Encoder oder Decoder nach Ihren Bedürfnissen.

[Bearbeiten] Lass es uns brechen. Es gibt keine Möglichkeit zu wissen, in welcher Kodierung die Bytes eines gegebenen Strings sind, also ist Ihre einzige Wahl, diese Bytes zu bekommen, verschieben Sie die Reihenfolge wie nötig (wenn Sie jemals in einer solchen Umgebung sind, in der ein Prozess Ihnen ein Array geben kann) Bytes in verschiedenen Ordnungen, benutze ByteBuffer, um damit umzugehen), und benutze die mehreren unterstützten CharsetDecoder, um die Bytes zu vernünftigen Ausgaben zu dekodieren.

Es ist übertrieben und erfordert, dass Sie schätzen, dass eine bestimmte Ausgabe in UTF-8, UTF-16 oder einer anderen Kodierung sein könnte. Aber bei least können Sie die gegebene Ausgabe mit einem der möglichen Zeichenfolgen dekodieren und dann versuchen, die verarbeitete Ausgabe für Ihre Bedürfnisse zu verwenden.

Da es sich um einen Prozess handelt, der von demselben Betriebssystem ausgeführt wird, in dem die JVM selbst läuft, ist es durchaus möglich, dass Ihre Ausgabe in einer der Charset-Kodierungen liegt, die von der availableCharsets () -Methode zurückgegeben werden.

    
javabeats 12.11.2012 19:00
quelle