C # -Ereignisse, die in PowerShell 5 nicht behandelt wurden

8

Ich versuche in .NET ein PowerShell-Add-In zu erstellen, mit dem ich auf einige Windows 10-Funktionen zugreifen kann. Ich kenne C #, aber PowerShell ist relativ neu für mich.

Ich habe alle meine Funktionsaufrufe und Cmdlets. Ich kann die C # -Klassen dazu bringen, Dinge aus PowerShell zu machen. Was mich auf den Kopf stellt, ist Ereigniserhöhung und -behandlung, damit der C # -Code zurückrufen kann. Ich bin jetzt für drei Abende dabei.

Beispiele online und hier in SO zeigen immer Timer und Dateisystembeobachter oder manchmal ein Windows Form. Ich habe noch nie ein Beispiel mit einer Klasse gesehen, die jemand selbst geschrieben hat. Nicht sicher, ob etwas Zucker benötigt wird, um die Ereignisse anzuregen, oder etwas anderes.

Der Hauptunterschied, den ich zwischen meinem Code und anderen gesehen habe, ist, dass ich eine Factory-Klasse habe, die eine Instanz des Objekts zurückgibt, das die Ereignisse auslöst. Ich benutze das, anstatt das neue Objekt aufzurufen. Allerdings erkennt PowerShell den Typ und freut sich, Mitglieder darauf aufzulisten, also habe ich angenommen, dass das nicht das Problem ist.

Ich habe ein einfaches Repro-Cmdlet, eine Klasse und Skripts erstellt. Hier sind sie:

GetTestObject-Cmdlet

%Vor%

TestObject-Klasse

%Vor%

Und hier sind die Skripte und ihre Ausgabe

test-events1.ps1 mit einfacher .NET-Event-Handler-Syntax

%Vor%

Ausgabe: (Ereignis wird in C # ausgelöst, aber niemals in PS behandelt)

%Vor%

test-events2.ps1 Verwenden der async / BeginInvoke-Syntax für den Fall, dass das Problem

war %Vor%

Ausgabe: (Ereignis wird in C # ausgelöst, aber nie in PS behandelt. Außerdem erhalte ich eine Ausnahme.)

%Vor%

test-events3.ps1 Verwenden des Register-ObjectEvent-Ansatzes. Hinzugefügte weitere Diagnosetyp-Informationen zur Ausgabe hier.

%Vor%

Ausgabe: (Ereignis wird in C # ausgelöst, aber niemals in PS behandelt)

%Vor%

In keinem Fall bekomme ich tatsächlich die Event-Handler-Aktion abgefeuert. Ich habe auch versucht, eine Variable zu verwenden, um die Aktion zu halten, aber das scheint auf die gleiche Weise behandelt zu werden. Der Console.Writeline-Code in C # dient nur zur Fehlersuche. Und ich habe den vollständigen Pfad für die DLL in den eingefügten Skripten entfernt, um sie einfacher zu lesen. Die DLL wird geladen.

Verwenden von PowerShell 5 unter Windows 10 pro 64 Bit mit .NET Framework 4.6 (CLR 4). VS 2015 RTM.

%Vor%

Irgendwelche Vorschläge für dieses PowerShell-Noob?

    
Pete 12.08.2015, 04:23
quelle

1 Antwort

3

Write-Output zeigt kein Objekt auf der Konsole an, es sendet Objekt an den nächsten Befehl in der Pipeline. Wenn Sie sofort Text auf der Konsole anzeigen möchten, müssen Sie Write-Host oder Out-Host cmdlet verwenden.

  

"Benutze niemals Write-Host, weil böse!"

Ich würde es so sagen: "Benutze niemals Write-Host bei Zwischendaten weil böse!". Es ist OK, eine Fortschrittsbenachrichtigung mit Write-Host anzuzeigen (obwohl Sie stattdessen Write-Progress verwenden können) oder es zum Anzeigen des Endergebnisses zu verwenden, aber Write-Host sendet nichts an den nächsten Befehl in der Pipeline, sodass Sie Daten nicht verarbeiten können weiter.

  

Warum schreiben alle anderen Write-Output-Befehle in die Konsole?

Wenn ein Objekt das ultimative Ende der Pipeline erreicht, muss PowerShell etwas dagegen tun. Standardmäßig wird es auf dem Host (in diesem Fall Konsole) angezeigt, obwohl Sie dies überschreiben können:

%Vor%

PowerShell unterstützt den Skriptblockaufruf in einem beliebigen Thread nicht, daher müssen Sie für asynchrone Ereignisse Register-ObjectEvent verwenden, damit PowerShell mit ihnen umgehen kann.

    
PetSerAl 12.08.2015, 05:56
quelle

Tags und Links