Mario-HS 5 Geschrieben 30. Oktober 2020 Melden Teilen Geschrieben 30. Oktober 2020 Hallo allerseits, ich habe mir überlegt, eine gui zu erstellen, die ich immer wieder erweitern möchte, wenn Zeit und Forscherdrang besteht. Ich versuche, alles irgendwie nachzuvollziehen, anzupassen etc. Ich bin jetzt auf ein Problem gestoßen, das ich nicht nachvollziehen kann. Die Zeile "$Starten_Knopf.Add_Click({ZeitServerStart})" wird als unbekanntes cmdlet angegeben, kann mir jemand sagen, wo ich einen Fehler habe? Zitat function Funktion-ZeitServer_Test { # ────────── Start Funktion ZeitServerStart function ZeitServerStart { if ($Eigenen_Zeit_Server.Checked -eq $true) {$Ausgabe_Ergebniss=w32tm /query /source} if ($Zeit_Server_Testen.Checked -eq $true) {$Ausgabe_Ergebniss=w32tm /stripchart /computer:0.de.pool.ntp.org /samples:5 /dataonly} if ($Zeit_Server_festlegen.Checked -eq $true) {$Ausgabe_Ergebniss=3} $ZeitServer_Test_Ausgabe=$Ausgabe_Ergebniss | fl | out-string; $Ausgabe_Feld.text=$ZeitServer_Test_Ausgabe } # ────────── Ende Funktion ZeitServerStart # ────────── Start Auswahlkasten $AuswahlBox = New-Object System.Windows.Forms.GroupBox $AuswahlBox.Location = New-Object System.Drawing.Size(40,50) $AuswahlBox.size = New-Object System.Drawing.Size(320,140) $AuswahlBox.text = "Auswahl-Funktionen" $Hauptfenster.Controls.Add($AuswahlBox) # ────────── Ende Auswahlkasten # ────────── Start Auswahlschalter Funktion-ZeitServer_Test $Eigenen_Zeit_Server = New-Object System.Windows.Forms.RadioButton $Eigenen_Zeit_Server.Location = new-object System.Drawing.Point(25,30) $Eigenen_Zeit_Server.size = New-Object System.Drawing.Size(260,20) $Eigenen_Zeit_Server.Checked = $true $Eigenen_Zeit_Server.Text = "Eigenen Zeit-Server ermitteln" $AuswahlBox.Controls.Add($Eigenen_Zeit_Server) $Zeit_Server_Testen = New-Object System.Windows.Forms.RadioButton $Zeit_Server_Testen.Location = new-object System.Drawing.Point(25,65) $Zeit_Server_Testen.size = New-Object System.Drawing.Size(260,20) $Zeit_Server_Testen.Text = "Test des Zeit-Servers Starten" $AuswahlBox.Controls.Add($Zeit_Server_Testen) $Zeit_Server_festlegen = New-Object System.Windows.Forms.RadioButton $Zeit_Server_festlegen.Location = new-object System.Drawing.Point(25,100) $Zeit_Server_festlegen.size = New-Object System.Drawing.Size(260,20) $Zeit_Server_festlegen.Text = "Neuen Zeit-Server festlegen" $AuswahlBox.Controls.Add($Zeit_Server_festlegen) # ────────── Ende Auswahlschalter Funktion-ZeitServer_Test # ────────── Start Startknopf Funktion-ZeitServer_Test $Starten_Knopf = New-Object System.Windows.Forms.Button $Starten_Knopf.Location = New-Object System.Drawing.Size(370,45) $Starten_Knopf.Size = New-Object System.Drawing.Size(40,40) $Starten_Knopf.Text = "Test Starten" $Starten_Knopf.Add_Click({ZeitServerStart}) $Starten_Knopf.Cursor = [System.Windows.Forms.Cursors]::Hand $Hauptfenster.Controls.Add($Starten_Knopf) # ────────── Ende Startknopf Funktion-ZeitServer_Test # ────────── Start Ausgabe Funktion-ZeitServer_Test $Ausgabe_Feld = New-Object System.Windows.Forms.TextBox $Ausgabe_Feld.Location = New-Object System.Drawing.Size(40,195) $Ausgabe_Feld.Size = New-Object System.Drawing.Size(320,140) $Ausgabe_Feld.MultiLine = $True # ────────── Ende Ausgabe Funktion-ZeitServer_Test $Ausgabe_Feld.ScrollBars = "Vertical" $Hauptfenster.Controls.Add($Ausgabe_Feld) } Zitieren Link zu diesem Kommentar
BOfH_666 577 Geschrieben 30. Oktober 2020 Melden Teilen Geschrieben 30. Oktober 2020 (bearbeitet) Ohne die komplette Fehlermeldung kann man nur raten ... Du definierst die Funktion "ZeitServerStart" innerhalb der Funktion "Funktion-ZeitServer_Test". So lange die Funktion "Funktion-ZeitServer_Test" noch nicht gelaufen ist, existiert also die Funktion "ZeitServerStart" noch nicht ... isses vielleicht das? Übrigens ist es Best Practice die Funktionen in Powershell in der gleichen Art und Weise zu benennen, wie die cmdlets - also die Form "Verb-Nomen" zu benutzen - und dabei die empfohlenen Verben zu benutzen. Die kannst Du Dir mit Get-Verb auf der Konsole anzeigen lassen. bearbeitet 30. Oktober 2020 von BOfH_666 Zitieren Link zu diesem Kommentar
Mario-HS 5 Geschrieben 30. Oktober 2020 Autor Melden Teilen Geschrieben 30. Oktober 2020 Hallo BOfH, ich rufe die Funktion "Funktion-ZeitServer_Test" vorher über die GUI auf die anderen Objekte in der Funktion werden auch angezeigt. Zitieren Link zu diesem Kommentar
Dukel 455 Geschrieben 30. Oktober 2020 Melden Teilen Geschrieben 30. Oktober 2020 Verschiebe die ZeitServerStart außerhalb von Funktion-ZeitServer_Test. Bei Powershell ist auch wichtig, dass die Funktionen als erstes kommen, vor dem eigendlichen Code. function a{ ... } function b{ ... } function c{ ... } ### Main: # Run a Function: a Zitieren Link zu diesem Kommentar
daabm 1.366 Geschrieben 30. Oktober 2020 Melden Teilen Geschrieben 30. Oktober 2020 It's all about scope... Eine Funktion, die Du INNERHALB einer andere Funktion erstellst, existiert auch nur IN dieser anderen Funktion. Denn "global gesehen" ist eine Funktion auch wieder nur ein Objekt, und jedes Objekt hat seinen Scope. Zitieren Link zu diesem Kommentar
Mario-HS 5 Geschrieben 2. November 2020 Autor Melden Teilen Geschrieben 2. November 2020 Guten Morgen allerseits, @daabm aus dem Grund habe ich die Funktion in der Funktion, es werden ja auch Objekte in der Funktion definiert die ich anspreche. @BOfH_666 das ist die Fehlermeldung Zitieren Link zu diesem Kommentar
BOfH_666 577 Geschrieben 2. November 2020 Melden Teilen Geschrieben 2. November 2020 OK. Als Erstes bitte: In Zukunft solltest Du Code, Fehlermeldungen, Konsolen-Output oder Beispiel-Daten als Code formatieren. Nicht als Zitat und schon gar nicht als Bild. Du hast jetzt aus 3 verschiedenen Richtungen gehört, dass es eventuell keine gute Idee ist, eine Funktion innerhalb einer Funktion zu definieren. Wie wär's, wenn Du einfach mal probierst, die Funktionsdefinition für "ZeitServerStart" außerhalb der Funktionsdefinition von "Funktion-ZeitServer_Test" zu packen und schaust, was passiert? Unabhängig davon wäre es bestimmt hilfreich, den kompletten Code zu sehen, oder wenigstens ein größeres Stück, welches einem potenziellen Helfer ermöglicht, den Code auszuführen und evtl. die gleiche Fehlermeldung zu erhalten. Dafür hilft es manchmal, den betreffenden Code-Schnipsel so weit "abzuspecken", dass er ohne den eventuell viel größeren Rest des Scripts läuft. Zitieren Link zu diesem Kommentar
Mario-HS 5 Geschrieben 2. November 2020 Autor Melden Teilen Geschrieben 2. November 2020 [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [Windows.Forms.Application]::EnableVisualStyles() $PS_Symbol = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path) $Schrift = New-Object System.Drawing.Font("Arial",10,[System.Drawing.FontStyle]::Regular) ########## ──────────────────── Start Bereich-Definitionen ──────────────────── ########## # ─────────────── Start Hauptfenster $Hauptfenster = New-Object System.Windows.Forms.Form # Ende Hauptfenster ─────────────── # # ─────────────── Start Hauptmenü $Hauptmenue = New-Object System.Windows.Forms.MenuStrip $Statusleiste = New-Object System.Windows.Forms.StatusStrip $statustext = New-Object System.Windows.Forms.ToolStripStatusLabel # Ende Hauptmenü ─────────────── # # ─────────────── Start Menüfunktionen $menue_Datei = New-Object System.Windows.Forms.ToolStripMenuItem $menue_System = New-Object System.Windows.Forms.ToolStripMenuItem $menue_Netzwerk = New-Object System.Windows.Forms.ToolStripMenuItem $menue_Domain = New-Object System.Windows.Forms.ToolStripMenuItem $menue_Weblinks = New-Object System.Windows.Forms.ToolStripMenuItem # Ende Menüfunktionen ─────────────── # # ─────────────── Start Unterpunkte-Menüfunktionen ─────────────── # # ────────── Start Menü-Datei $menueBeenden = New-Object System.Windows.Forms.ToolStripMenuItem $menueDateisuche = New-Object System.Windows.Forms.ToolStripMenuItem $menueDateiinhalt = New-Object System.Windows.Forms.ToolStripMenuItem # Ende Menü-Datei ────────── # # ────────── Start Menü-System $menueZeitServerTest = New-Object System.Windows.Forms.ToolStripMenuItem $menueZeitServerFestlegen = New-Object System.Windows.Forms.ToolStripMenuItem $menueDISM = New-Object System.Windows.Forms.ToolStripMenuItem # Ende Menü-System ────────── # # ────────── Start Menü-Netzwerk $menuePing = New-Object System.Windows.Forms.ToolStripMenuItem # Ende Menü-Netzwerk ────────── # # ────────── Start Menü-Domain $menueFSR_DFS_Migration = New-Object System.Windows.Forms.ToolStripMenuItem # Ende Menü-Domain ────────── # # ────────── Start Menü-Weblinks $menueFSR_DFS_Migration = New-Object System.Windows.Forms.ToolStripMenuItem # Ende Menü-Weblinks ────────── # # ─────────────── Ende Unterpunkte-Menüfunktionen ─────────────── # # ─────────────── Start Import-Symbole ─────────────── # $Import = @" using System; using System.Drawing; using System.Runtime.InteropServices; namespace System { public class IconExtractor { public static Icon Extract(string file, int number, bool largeIcon) { IntPtr large; IntPtr small; ExtractIconEx(file, number, out large, out small, 1); try { return Icon.FromHandle(largeIcon ? large : small); } catch { return null; } } [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons); } } "@ Add-Type -TypeDefinition $Import -ReferencedAssemblies System.Drawing # ─────────────── Ende Import-Symbole ─────────────── # ########## ──────────────────── Ende Bereich-Definitionen ──────────────────── ########## ########## ──────────────────── Start Bereich-Funktionen ──────────────────── ########## # ─────────────── Start Hauptfenster Setup $Hauptfenster.Icon = $PS_Symbol $Hauptfenster.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::SizableToolWindow $Hauptfenster.MainMenuStrip = $Hauptmenue $Hauptfenster.Height = 600 $Hauptfenster.Width = 1000 $Hauptfenster.StartPosition = "CenterScreen" $Hauptfenster.TopMost = $true $Hauptfenster.Text = "Probi Tool" $Hauptfenster.Font = $Schrift $Hauptfenster.Controls.Add($Hauptmenue) # Ende Hauptfenster Setup ─────────────── # # ─────────────── Start Statusbalken [void]$Statusleiste.Items.Add($Statustext) $Statustext.AutoSize = $true $Statustext.Text = "Bereit." $Hauptfenster.Controls.Add($Statusleiste) # Ende Statusbalken ─────────────── # ##### ──────────────────── Start Menüleiste Setup ──────────────────── ##### [void]$Hauptfenster.Controls.Add($Hauptmenue) # ─────────────── Menüleiste - Datei $menue_Datei.Text = "&Datei" [void]$Hauptmenue.Items.Add($menue_Datei) # ─────────────── Menüleiste - System $menue_System.Text = "&System" [void]$Hauptmenue.Items.Add($menue_System) # ─────────────── Menüleiste - Netzwerk $menue_Netzwerk.Text = "&Netzwerk" [void]$Hauptmenue.Items.Add($menue_Netzwerk) # ─────────────── Menüleiste - Active-Directory $menue_Domain.Text = "&Active-Directory" [void]$Hauptmenue.Items.Add($menue_Domain) # ─────────────── Menüleiste - Active-Directory $menue_Weblinks.Text = "&Website-Links" [void]$Hauptmenue.Items.Add($menue_Weblinks) ##--------------- Ende Menüleiste Setup ---------------## ########## ──────────────────── Ende Bereich-Funktionen ──────────────────── ########## ########## ──────────────────── Start Bereich-Programm ──────────────────── ########## ##### ──────────────────── Start Datei-Menüleiste ──────────────────── ##### $menueBeenden.Image = [System.IconExtractor]::Extract("shell32.dll", 27, $true) $menueBeenden.Text = "&Beenden" $menueBeenden.Add_Click({$Hauptfenster.Close()}) [void]$menue_Datei.DropDownItems.Add($menueBeenden) ##### ──────────────────── Ende Datei-Menüleiste ──────────────────── ##### ##### ──────────────────── Start System-Menüleiste ──────────────────── ##### $menueZeitServerTest.Image = [System.IconExtractor]::Extract("shell32.dll", 265, $true) $menueZeitServerTest.Text = "&Zeit Server Testen" $menueZeitServerTest.Add_Click({Funktion-ZeitServer_Test}) [void]$menue_System.DropDownItems.Add($menueZeitServerTest) ##### ──────────────────── Ende System-Menüleiste ──────────────────── ##### ########## ──────────────────── Ende Bereich-Programm ──────────────────── ########## ########## ──────────────────── Start Bereich-Funktionen ──────────────────── ########## ##### ──────────────────── Start Funktion-ZeitServer_Test ──────────────────── ##### function Funktion-ZeitServer_Test { # ────────── Start Funktion ZeitServerStart function ZeitServerStart { if ($Eigenen_Zeit_Server.Checked -eq $true) {$Ausgabe_Ergebniss=w32tm /query /source} if ($Zeit_Server_Testen.Checked -eq $true) {$Ausgabe_Ergebniss=w32tm /stripchart /computer:0.de.pool.ntp.org /samples:5 /dataonly} if ($Zeit_Server_festlegen.Checked -eq $true) {$Ausgabe_Ergebniss=3} $ZeitServer_Test_Ausgabe=$Ausgabe_Ergebniss | fl | out-string; $Ausgabe_Feld.text=$ZeitServer_Test_Ausgabe } # ────────── Ende Funktion ZeitServerStart # ────────── Start Auswahlkasten $AuswahlBox = New-Object System.Windows.Forms.GroupBox $AuswahlBox.Location = New-Object System.Drawing.Size(40,50) $AuswahlBox.size = New-Object System.Drawing.Size(320,140) $AuswahlBox.text = "Auswahl-Funktionen" $Hauptfenster.Controls.Add($AuswahlBox) # ────────── Ende Auswahlkasten # ────────── Start Auswahlschalter Funktion-ZeitServer_Test $Eigenen_Zeit_Server = New-Object System.Windows.Forms.RadioButton $Eigenen_Zeit_Server.Location = new-object System.Drawing.Point(25,30) $Eigenen_Zeit_Server.size = New-Object System.Drawing.Size(260,20) $Eigenen_Zeit_Server.Checked = $true $Eigenen_Zeit_Server.Text = "Eigenen Zeit-Server ermitteln" $AuswahlBox.Controls.Add($Eigenen_Zeit_Server) $Zeit_Server_Testen = New-Object System.Windows.Forms.RadioButton $Zeit_Server_Testen.Location = new-object System.Drawing.Point(25,65) $Zeit_Server_Testen.size = New-Object System.Drawing.Size(260,20) $Zeit_Server_Testen.Text = "Test des Zeit-Servers Starten" $AuswahlBox.Controls.Add($Zeit_Server_Testen) $Zeit_Server_festlegen = New-Object System.Windows.Forms.RadioButton $Zeit_Server_festlegen.Location = new-object System.Drawing.Point(25,100) $Zeit_Server_festlegen.size = New-Object System.Drawing.Size(260,20) $Zeit_Server_festlegen.Text = "Neuen Zeit-Server festlegen" $AuswahlBox.Controls.Add($Zeit_Server_festlegen) # ────────── Ende Auswahlschalter Funktion-ZeitServer_Test # ────────── Start Startknopf Funktion-ZeitServer_Test $Starten_Knopf = New-Object System.Windows.Forms.Button $Starten_Knopf.Location = New-Object System.Drawing.Size(370,65) $Starten_Knopf.Size = New-Object System.Drawing.Size(90,50) $Starten_Knopf.Text = "Test Starten" $Starten_Knopf.Add_Click({ZeitServerStart}) $Starten_Knopf.Cursor = [System.Windows.Forms.Cursors]::Hand $Hauptfenster.Controls.Add($Starten_Knopf) # ────────── Ende Startknopf Funktion-ZeitServer_Test # ────────── Start Ausgabe Funktion-ZeitServer_Test $Ausgabe_Feld = New-Object System.Windows.Forms.TextBox $Ausgabe_Feld.Location = New-Object System.Drawing.Size(40,195) $Ausgabe_Feld.Size = New-Object System.Drawing.Size(320,140) $Ausgabe_Feld.MultiLine = $True # ────────── Ende Ausgabe Funktion-ZeitServer_Test $Ausgabe_Feld.ScrollBars = "Vertical" $Hauptfenster.Controls.Add($Ausgabe_Feld) } ##### ──────────────────── Ende Funktion-ZeitServer_Test ──────────────────── ##### ########## ──────────────────── Ende Bereich-Funktionen ──────────────────── ########## [void] $Hauptfenster.ShowDialog() Wenn ich die Funktion "ZeitServerStart" ausserhalb von "Funktion-ZeitServer_Test" habe bekomme ich die Meldung das er mit "$Ausgabe_Feld.text=$ZeitServer_Test_Ausgabe" nichts anfangen kann. Zitieren Link zu diesem Kommentar
BOfH_666 577 Geschrieben 2. November 2020 Melden Teilen Geschrieben 2. November 2020 OK ... vorher muss ich sagen, dass ich mich überhaupt gar nicht mit GUIs in Powershell beschäftige und auch nicht auskenne, ABER ... Du versuchst innerhalb einer Funktion auf eine Eigenschaft eines Objekts zuzugreifen, welches die Funktion nicht kennt. Stattdessen solltest Du einfach den Wert als Rückgabewert der Funktion ausgeben und damit weiterarbeiten. Also statt: $Ausgabe_Feld.text = $ZeitServer_Test_Ausgabe Einfach: $ZeitServer_Test_Ausgabe Wie Du das allerdings in Deine GUI eingebaut bekommst, kann ich Dir leider auch nicht sagen. Ich bin aber sicher, dass das einer der anderen Kollegen hier drauf hat ... hab ein bissl Geduld, bitte! 1 Zitieren Link zu diesem Kommentar
daabm 1.366 Geschrieben 3. November 2020 Melden Teilen Geschrieben 3. November 2020 Hm - Scope... Ich glaub ich hab das nicht deutlich rübergebracht: Scope, Scope, Scope! $ZeitServer_Test_Ausgabe=$Ausgabe_Ergebniss | fl | out-string; Das ist in zweierlei Hinsicht - sorry - Mist. Einerseits zerstörst Du mit "| fl | out-string" jedwede Objekteigenschaften und machst $Ausgabe_Ergebniss zu einem Stringhaufen. Andererseits existiert diese Variable nur INNERHALB ihres Scopes und das ist diese nested Function. "get-help about_scopes" wäre meine erste Empfehlung in dieser Situation Und wie Olaf schon schrieb: Wenn Funktionen etwas tun, was dann woanders benötigt wird, dann speichern sie das nicht in Variablen (die dann nur im Funktions-Scope existieren), sondern sie geben es zurück. Entweder per Return $var explizit oder einfach per $var in die Pipeline. Zweiteres klappt aber nur, wenn man darauf achtet, daß man keinen "Kruscht" in die Pipeline schreibt. Weil auch ein simples "Hallo" in ebendieser landet. Zitieren Link zu diesem Kommentar
Mario-HS 5 Geschrieben 5. November 2020 Autor Melden Teilen Geschrieben 5. November 2020 Einen wunderschönen Guten Morgen allerseits, vorab danke für die ganzen Hilfestellungen. Ich denke, ich muss mich noch etwas in die Thematik mit Funktionen einlesen, daher habe ich mir etwas anderes überlegt, wie ich es Realisieren könnte (glaube ich zumindest). Wenn ich peer button click eine Funktion Aufrufen kann, dann sollte doch Folgendes auch möglich sein oder. # ────────── Start Startknopf Funktion-ZeitServer_Test $Starten_Knopf = New-Object System.Windows.Forms.Button $Starten_Knopf.Location = New-Object System.Drawing.Size(370,65) $Starten_Knopf.Size = New-Object System.Drawing.Size(90,50) $Starten_Knopf.Text = "Test Starten" $Starten_Knopf.Cursor = [System.Windows.Forms.Cursors]::Hand $Starten_Knopf.Add_Click({ if ($Eigenen_Zeit_Server.Checked) { $Ausgabe_Ergebniss=w32tm /query /source write-host "Der aktuelle Zeitserver ist: "$Ausgabe_Ergebniss } elseif ($Zeit_Server_Testen.Checked) { $Ausgabe_Ergebniss=w32tm /stripchart /computer:0.de.pool.ntp.org /samples:5 /dataonly write-host "Der Zeitserver Unterschied beträgt: "$Ausgabe_Ergebniss } else { $Ausgabe_Ergebniss="Keine Funktion ansgewaehlt!" } }) $Hauptfenster.Controls.Add($Starten_Knopf) # ────────── Ende Startknopf Funktion-ZeitServer_Test Zitieren Link zu diesem Kommentar
lefg 276 Geschrieben 5. November 2020 Melden Teilen Geschrieben 5. November 2020 Moin Ob es dafür nicht etwas fertiges gibt? Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.