Abrufen der privaten Umgebungsvariablen eines Prozesses in Windows mit Powershell?
Ich habe einen Prozess (testxx) auf meiner Datenbank laufen. Jedes Mal, wenn sich ein Benutzer mit der Datenbank verbindet, startet der Prozess eine separate Sitzung für. Alle Prozesse enthalten eine private Umgebungsvariable (Client-Nr) mit unterschiedlichen Werten. Ich möchte einen bestimmten Prozess mit einer bestimmten privaten Umgebungsvariablen aufrufen. Ich habe den folgenden Befehl verwendet:
Nehmen wir an, es gibt 5x "testxx"-Prozesse. Ich möchte den einen Prozess aufrufen, der den Wert "Client-Two" in der privaten Umgebungsvariable "Client-Nr" hat.
Dazu verwende ich den folgenden Code:
get-process -name "testxx" | where-object {$env:Client-Nr -eq "client-Two"}
der Prozess, den ich brauche, wird nicht aufgerufen. Ich habe mit dem folgenden Befehl überprüft, ob powershell die private Umgebungsvariable erkennt:
(get-process -Name "testxx").StartInfo.EnvironmentVariables
Die Powershell hat diese private Umgebungsvariable nicht erkannt. Wenn ich jedoch "Process Hacker" öffne und den spezifischen "testxx"-Prozess auswähle, sehe ich die private Umgebungsvariable "client-Nr" mit diesem bestimmten "Client-nr"-Wert. Wie kann ich diese Art von privater Umgebungsvariable über die Powershell aufrufen?
1 Antwort
Vornweg... was get-process betrifft, gehört eine env-Variable nicht zu den von diesem cmtlet gelieferten Daten und kann somit auch nicht über eine Pipe ausgewertet werden. (Du kannst mit "where" nur Daten filtern, welche vom Datenlieferanten übergeben werden.
Get-Process deinprog|fl *
..zeigt dir alle verfügbaren Daten für deinprog.
Irgendwie hast Du wohl noch nicht so ganz die Funktionsweise von Powershell und des Systems begriffen
Umgebungsvariablen können nur vom Aufrufenden Prozess an den Aufgerufenen Prozess weitergegeben werden. Der Aufgerufene Prozess bekommt eine Kopie des Zustands der Umgebungsvariablen des Aufrufers beim Aufruf übergeben. Das Set an Umgebungsvariablen ist an den aufrufenden Prozess gebunden und kann durch andere Prozesse weder "gesehen" noch beeinflusst werden.
Ebensowenig kann der Kindprozess Elternvariablen nutzen. Mit dem Beenden eines Prozesses erlischt auch dessen Environment.
Dein Problem ist nicht über Umgebungsvariablen zu lösen. Über eine effiziente "Kommunikation" zwischen verschiedenen parallelen/unabhängigen Prozessen zerbrechen sich Leute den Kopf seit es Multitasking gibt.
Wirklich befriedigende Lösungen kann es eigentlich nicht geben . Im Bereich von Batch ist es bei parallelen Abläufen einfach üblich über "Signal"-Dateien mit dem Elternprozess zu kommunizieren.
Das geht auch unter Powershell. Über die Effizienz von Events/Eventlogs in der Kommunikation zwischen verschiedenen Scripten /Prozessen scheiden sich die Geister. Da der Vewaltunsaufwand Verhältnis mäßig hoch ist.
In Deinem Fall gehst Du die ganze Sache warscheinlich schon organisatorisch falsch an. Ich habe auch keine Ahnung, wie Du von außen auf einen laufenden Prozess Einfluss nehmen willst? (Abgesehen von Taskkill oder Änderungen der Prozesspriorität oder der Zuweisung spezieller CPU-Kerne.)
Ich habe noch etwas Zeit. Also eine kleine Demonstration des obigen.
starte folgendes Script:
demo1.ps1
$host.ui.RawUI.WindowTitle = "Ratzfatz" #ändere den Fensternamen zur besseren Unterscheidung
$env:blub='Hallo' #setze/ändere neue Environvariable
Get-Process |?{$_.MainWindowTitle -like 'Ratzfatz'}|%{$_.StartInfo.EnvironmentVariables} #rufe die Env des Prozesses mit dem Fenternamen Ratzfatz ab
#innerhalb der eigenen Prozessumgebung werden Änderungen der Env durch .StartInfo.EnvironmentVariables sehr wohl wahrgenommen. und liefert das gleiche ergebnis wie: gci env:
pause
nun starte einen 2.Prozess:
Demo2.ps1
Get-Process |?{$_.MainWindowTitle -like 'Ratzfatz'}|%{$_.StartInfo.EnvironmentVariables} #die gleiche Abfrage
#natürlich erfährt get-process lediglich mit welchen variablen der andere Prozess gestartet wurde. Spätere änderungen bleiben dem Blick verwehrt
pause
Veränderungen sind für andere Prozesse nicht zugänglich!