Wie konfiguriere ich einen Windows-Dienstprozess so, dass er mit niedriger Priorität ausgeführt wird?

16

Gibt es eine Möglichkeit, einen Windows-Dienstprozess (z. B. squidNT, SQL Server usw.) so zu konfigurieren, dass er automatisch mit niedriger Priorität gestartet wird, ohne die Prozesspriorität manuell über den Task-Manager zu ändern?

Eulenspross
quelle
Das Ändern der Priorität von Threads oder Prozessen ist normalerweise eine schlechte Idee, es sei denn, der Code wurde so geschrieben, dass er mit einer anderen Priorität ausgeführt wird. Durch Ändern der Prioritäten wird die Liste der Nebenläufigkeitsprobleme um "Prioritätsumkehrung" erweitert, um dies zu vermeiden.
Richard
1
Das OP fragte nicht, ob es eine gute Idee sei oder nicht. Das OP fragte, ob und wie dies getan werden könne . - Bitte denken Sie daran, beim Thema zu bleiben. 😉
BrainSlugs83

Antworten:

11

Der Dienststeuerungs-Manager, der das Starten / Beenden von Diensten verwaltet, verfügt (in keiner früheren Windows-Version) über einen Mechanismus, mit dem die Priorität der von ihm gestarteten Prozesse festgelegt werden kann.

Da Sie die Priorität eines bereits ausgeführten Prozesses ändern können, empfiehlt es sich, hierfür ein Tool zu verwenden.

Mir ist kein Microsoft-Befehlszeilentool zum Ändern der Prozesspriorität bekannt, aber die "PV" -Befehlszeile unter http://www.teamcti.com/pview/prcview.htm enthält eine Funktion zum Festlegen der Priorität .

pv -pb process-name.exe

Das würde "process-name.exe" auf "Below Normal" setzen.

Wenn Sie damit leben können, dass der Prozess mit der Priorität "Normal" beginnt, bis Sie sich daran gewöhnt haben, ihn zu ändern, können Sie dies mit einem Skript tun, das als "Geplante Aufgabe" ausgeführt wird und das gelegentlich ausgelöst wird (falls der Dienst abruft) abgeprallt).

Es ist ein schneller und schmutziger Hack, aber ich verdanke einen Großteil meines Lebens durch schnelle und schmutzige Hacks, die den Job erledigen!

Evan Anderson
quelle
Führen Sie möglicherweise eine Batch-Datei aus, um die App zu starten, und legen Sie dann die Prozesspriorität fest, möglicherweise mit einer kurzen Pause dazwischen, anstatt die App direkt auszuführen und anschließend eine andere Task auszuführen, um die Priorität festzulegen. Funktioniert nicht für alles, ist aber einen Versuch wert.
John Gardeniers
3

Die obigen Antworten haben bei mir nicht funktioniert. Ich habe die Erstellung des folgenden Powershell-Skripts beendet:

ChangePriority.ps1

Get-WmiObject Win32_process -Filter 'name="ProcessName.exe"' | ForEach-Object {$_.SetPriority(128)}

Und dann habe ich eine geplante Aufgabe erstellt, die alle 5 Minuten aufgerufen wird. In der Administrator- Eingabeaufforderung oder im Batch-Skript:

schtasks /Create /tn "Process Priority Change" /sc MINUTE /mo 5 /ru SYSTEM /tr "powershell -noprofile -executionpolicy bypass -file \"%cd%\ChangePriority.ps1\""

Versuchte zu verwenden , wmicwie besprochen hier , um die geplante Aufgabe nicht auf die Datei fehlgeschlagen zu machen abhängig. Ähnliches mit dem Powershell-Skript: Ich konnte nicht nur einen einzelnen Befehl erstellen, der nur eine Aufgabe mit dem Inline-Skript erstellt. Würdigt, wenn Sie es geschafft haben und eine weitere Antwort hinzufügen.

Werte für die Priorität im Powershell-Skript finden Sie hier [1].

[1] https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/setpriority-method-in-class-win32-process

ceztko
quelle
Sehr hilfreich. Ich habe eine Zeile mit meinen schlechten ps-Kenntnissen aufgeschlüsselt, um den Prozess für den Audiodienst mit dem Diensthost auf Echtzeit einzustellen und ein Knistern des Audios bei starker CPU-Auslastung zu verhindern (schlechte Treiber, denke ich). Funktioniert super!
JasonXA
@JasonXA Gern geschehen. Geschätzt, wenn Sie eine einzeilige Version davon bereitstellen können, die ich nicht konnte
ceztko
Sicher: PowerShell.exe -noprofile -executionpolicy bypass -command "& {Get-WmiObject Win32_service -Filter \" Name = 'AudioSrv' \ "| ForEach {Get-WmiObject Win32_process -Filter \" ProcessId = $ ($ _. ProcessId) \ "} | ForEach-Object {$ _. SetPriority (256)}}" Ich weiß nicht, wie richtig es ist ... aber es funktioniert. Ich habe es nicht geschafft, es versteckt zu machen, kann nur unter Benutzer w / admin priv arbeiten.
JasonXA
1

Folgendes könnte auch funktionieren. Bearbeiten Sie den ImagePath-Registrierungsschlüssel und verwenden Sie den Startbefehl von cmd.exe:

START ["title"] [/Dpath] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
      [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
      [/WAIT] [/B] [command/program]
      [parameters]
HopelessN00b
quelle
Leider funktioniert dies überhaupt nicht, da die ausführbare Datei, die in gestartet wird, ImagePathdie Schnittstelle für Windows-Dienste startberücksichtigen muss und diese nicht implementiert oder an die zu startende ausführbare Datei weiterleitet.
Ceztko
0

Ich musste das tun, damit teamcity weniger CPU nimmt. Und da teamcity die einzige Java-App ist, die wir ausführen, funktioniert diese Lösung perfekt.

  1. Service als Startup "manuell" einstellen.
  2. Erstellen Sie eine Batch-Datei, die Ihren Dienst startet, und senken Sie die Priorität wie folgt:

    net start tcbuildagent
    net start teamcity
    wmic prozess wobei name = "java.exe" CALL setpriority "below normal"

  3. Erstellen Sie einen "Task Scheduler" -Job, der beim "Windows-Start" ausgelöst wird und diese Batch-Datei startet.

Ich habe den TaskScheduler-Trigger mit einer Verzögerung von 1 Minute konfiguriert, um den Start anderer Dienste nicht zu beeinträchtigen.

PS Sie können auch festlegen, dass alle Dienste manuell gestartet werden, und diese Batch-Datei verwenden, um alle in der von Ihnen gewünschten Reihenfolge zu starten. SQL, IIS usw.

Foxontherock
quelle
0

Sie können das folgende Powershell-Skript in eine geplante Task einfügen, die beim Start ausgeführt wird.

do {
    start-sleep -s 5
    $obj = Get-WmiObject Win32_process -Filter 'name="processname"'
} while ($obj -eq $null)
$obj.SetPriority(16384)
Doug
quelle