Jump to content

Erweiterbares Tool


Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Empfohlene Beiträge

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)
    }

 

Link zu diesem Kommentar

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 von BOfH_666
Link zu diesem Kommentar

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.

Link zu diesem Kommentar
[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.

Link zu diesem Kommentar

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!   ;-)

Link zu diesem Kommentar

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.

Link zu diesem Kommentar

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

 

Link zu diesem Kommentar
Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Schreibe einen Kommentar

Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor-Fenster leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...