PS1-GUI Aufruf aus C, Steuerelement Button reagiert nicht
Hallo zusammen,
kann mir eventuell jemand einen Denkanstoß geben, wie ich eine PowershellGUI aus C# starten kann und dabei die Steuerelemente z.B. Button reaktionsfähig bleiben.
Aktuell wird die Form aufgerufen, aber der Button hat keine Auswirkung auf den Script, von PS aus funktioniert es, über C# Aufruf nicht.
Ich denke, dass die Ursache im Aufruf aus einer anderen Instant zu suchen ist, aber wie kriege ich es hin auf die Steuerelemente zu verweisen.
Die Form in C# nachzubauen wollte ich nicht, weil der PS Script mit der GUI fertig vorliegen und C#, weil ich die DLL (SharpShell Sachen, für SelectedItemPaths aus Wind. Explorer) aus PS nicht ansprechen/anbinden konnte.
Ist ein Mischmasch, ich weiß, aber mit PS kenn eich mich etwas besser aus als mit C#.
Vielen Dank im Voraus
Inhalt C# DLL, PS-Aufruf
Inhalt PS Designer
Inhalt PS1
kann mir eventuell jemand einen Denkanstoß geben, wie ich eine PowershellGUI aus C# starten kann und dabei die Steuerelemente z.B. Button reaktionsfähig bleiben.
Aktuell wird die Form aufgerufen, aber der Button hat keine Auswirkung auf den Script, von PS aus funktioniert es, über C# Aufruf nicht.
Ich denke, dass die Ursache im Aufruf aus einer anderen Instant zu suchen ist, aber wie kriege ich es hin auf die Steuerelemente zu verweisen.
Die Form in C# nachzubauen wollte ich nicht, weil der PS Script mit der GUI fertig vorliegen und C#, weil ich die DLL (SharpShell Sachen, für SelectedItemPaths aus Wind. Explorer) aus PS nicht ansprechen/anbinden konnte.
Ist ein Mischmasch, ich weiß, aber mit PS kenn eich mich etwas besser aus als mit C#.
Vielen Dank im Voraus
Inhalt C# DLL, PS-Aufruf
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpShell;
using SharpShell.SharpContextMenu;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using SharpShell.Attributes;
using System.Diagnostics;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections;
namespace Shell_Extensions_DLL
{
[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".mpr")]
public class CountLinesExtension : SharpContextMenu
{
protected override bool CanShowMenu()
{
return true;
}
protected override ContextMenuStrip CreateMenu()
{
var menu = new ContextMenuStrip();
var itemCountLines = new ToolStripMenuItem { Text = "Sauger einfügen BMG511 Platz 2" };
itemCountLines.Click += (sender, args) => PS_Script_Run();
menu.Items.Add(itemCountLines);
return menu;
}
public void PS_Script_Run()
{
// $synkTable = [System.Collections.Hashtable]::Synchronized(@{ })
// Collection<PSObject> SynchPSObject = new Collection<PSObject>();
string PSScriptPath = @"C:\Users\dell\OneDrive\05_Batch\PS_Saugopti\SaugOpti\SaugOpti.ps1";
var builder2 = new StringBuilder();
foreach (var FulPath in SelectedItemPaths) { builder2.AppendLine(string.Format("{0}", Path.GetFullPath(FulPath))); }
MessageBox.Show("01_Oben builder2.ToString() Inhalt : " + builder2.ToString());
var SynchC = builder2.ToString();
Runspace RS = RunspaceFactory.CreateRunspace();
RS.Open();
RS.SessionStateProxy.SetVariable("Synch", SynchC);
RS.SessionStateProxy.SetVariable("SaugOpti", this);
PowerShell RSInst = PowerShell.Create();
RSInst.AddScript(PSScriptPath);
RSInst.Runspace = RS;
MessageBox.Show("02_vor BeginInvoce Synch Inhalt: " + SynchC);
Collection<PSObject> SynchPSObject = RSInst.Invoke();
MessageBox.Show("03_nach BeginInvoce Synch Inhalt: " + SynchC);
//RSInst.EndInvoke(u);
// ps.Runspace.Close();
}
}
}
Inhalt PS Designer
[void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
$SaugOpti = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Button]$button2 = $null
[System.Windows.Forms.TextBox]$textBox1 = $null
[System.Windows.Forms.Button]$button1 = $null
function InitializeComponent
{
$button2 = (New-Object -TypeName System.Windows.Forms.Button)
$textBox1 = (New-Object -TypeName System.Windows.Forms.TextBox)
$SaugOpti.SuspendLayout()
#
#button2
#
$button2.Anchor = ([System.Windows.Forms.AnchorStyles][System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right)
$button2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]710,[System.Int32]12))
$button2.Name = [System.String]'button2'
$button2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]75,[System.Int32]23))
$button2.TabIndex = [System.Int32]0
$button2.Text = [System.String]'Button'
$button2.UseVisualStyleBackColor = $true
$button2.add_Click($button2_Click)
#
#textBox1
#
$textBox1.Anchor = ([System.Windows.Forms.AnchorStyles][System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right)
$textBox1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]41))
$textBox1.Multiline = $true
$textBox1.Name = [System.String]'textBox1'
$textBox1.ScrollBars = [System.Windows.Forms.ScrollBars]::Both
$textBox1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]773,[System.Int32]307))
$textBox1.TabIndex = [System.Int32]1
#
#SaugOpti
#
$SaugOpti.ClientSize = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]797,[System.Int32]360))
$SaugOpti.Controls.Add($textBox1)
$SaugOpti.Controls.Add($button2)
$SaugOpti.Name = [System.String]'SaugOpti'
$SaugOpti.TopMost = $true
$SaugOpti.ResumeLayout($false)
$SaugOpti.PerformLayout()
Add-Member -InputObject $SaugOpti -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name button2 -Value $button2 -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name textBox1 -Value $textBox1 -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name button1 -Value $button1 -MemberType NoteProperty
}
. InitializeComponent
Inhalt PS1
param($in)
. (Join-Path $PSScriptRoot 'SaugOpti.designer.ps1')
# $SynchTB = [System.Collections.Hashtable]::Synchronized($Synch)
$button2_Click = {
$SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
}
$SaugOpti.textBox1.AppendText($Synch) # Übername aus der DLL
$SaugOpti.ShowDialog()
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 2446436423
Url: https://administrator.de/forum/ps1-gui-aufruf-aus-c-steuerelement-button-reagiert-nicht-2446436423.html
Ausgedruckt am: 02.05.2025 um 09:05 Uhr
7 Kommentare
Neuester Kommentar

Weil du
. hinterher bringt das nix weil zum dem Zeitpunkt der Zuweisung von .add_Click der Skriptblock $button2_Click ja noch nicht existiert.
Ergo logisch das beim Klick nix passiert. Also die add_Click Methode nach der Definition des Script-Blocks aufrufen. Oder einfach direkt so zusammenfassen
$button2.add_Click($button2_Click)
ja schon vorher ausführst ohne das$button2_Click = {
$SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
}
je definiert wurde $SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
}
Ergo logisch das beim Klick nix passiert. Also die add_Click Methode nach der Definition des Script-Blocks aufrufen. Oder einfach direkt so zusammenfassen
$button2.add_Click({
$SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
})

Ja bringt aber nix wenn die Reihenfolge der Aufrufe nicht stimmt
. Denn du definierst die Variable wie gesagt erst hinterher nachdem der Funktionsaufruf von add_click schon passiert ist und zu dem Zeitpunkt gibt es die Variable nicht. Ergo ist der Skriptblock leer.
Irgendwie verstehe ich das nicht, warum funktioniert es dann, wenn ich die GUI aus VS oder ISE starte?
Oder ich sehe den Wald vor laute Bäume nicht mehr, kann auch sein und muss für heute aufhören☺
Jepp du siehst den ganzen Wald nicht, ließ meinen Post nochmal ganz in Ruhe!Oder ich sehe den Wald vor laute Bäume nicht mehr, kann auch sein und muss für heute aufhören☺

Hier vergleiche beide Skripte und du siehst den Unterschied:
Deine Variante : (kann nicht funktionieren aus den oben genannten Gründen der Reihenfolge der Variablendeklaration)
[void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
$SaugOpti = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Button]$button2 = $null
[System.Windows.Forms.TextBox]$textBox1 = $null
[System.Windows.Forms.Button]$button1 = $null
function InitializeComponent
{
$button2 = (New-Object -TypeName System.Windows.Forms.Button)
$textBox1 = (New-Object -TypeName System.Windows.Forms.TextBox)
$SaugOpti.SuspendLayout()
#
#button2
#
$button2.Anchor = ([System.Windows.Forms.AnchorStyles][System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right)
$button2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]710,[System.Int32]12))
$button2.Name = [System.String]'button2'
$button2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]75,[System.Int32]23))
$button2.TabIndex = [System.Int32]0
$button2.Text = [System.String]'Button'
$button2.UseVisualStyleBackColor = $true
$button2.add_Click($button2_Click)
#
#textBox1
#
$textBox1.Anchor = ([System.Windows.Forms.AnchorStyles][System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right)
$textBox1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]41))
$textBox1.Multiline = $true
$textBox1.Name = [System.String]'textBox1'
$textBox1.ScrollBars = [System.Windows.Forms.ScrollBars]::Both
$textBox1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]773,[System.Int32]307))
$textBox1.TabIndex = [System.Int32]1
#
#SaugOpti
#
$SaugOpti.ClientSize = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]797,[System.Int32]360))
$SaugOpti.Controls.Add($textBox1)
$SaugOpti.Controls.Add($button2)
$SaugOpti.Name = [System.String]'SaugOpti'
$SaugOpti.TopMost = $true
$SaugOpti.ResumeLayout($false)
$SaugOpti.PerformLayout()
Add-Member -InputObject $SaugOpti -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name button2 -Value $button2 -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name textBox1 -Value $textBox1 -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name button1 -Value $button1 -MemberType NoteProperty
}
. InitializeComponent
$button2_Click = {
$SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
}
$SaugOpti.textBox1.AppendText($Synch) # Übername aus der DLL
$SaugOpti.ShowDialog()
Mit meiner oben genannten Korrektur geht es ...
[void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
$SaugOpti = New-Object -TypeName System.Windows.Forms.Form
[System.Windows.Forms.Button]$button2 = $null
[System.Windows.Forms.TextBox]$textBox1 = $null
[System.Windows.Forms.Button]$button1 = $null
function InitializeComponent
{
$button2 = (New-Object -TypeName System.Windows.Forms.Button)
$textBox1 = (New-Object -TypeName System.Windows.Forms.TextBox)
$SaugOpti.SuspendLayout()
#
#button2
#
$button2.Anchor = ([System.Windows.Forms.AnchorStyles][System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right)
$button2.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]710,[System.Int32]12))
$button2.Name = [System.String]'button2'
$button2.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]75,[System.Int32]23))
$button2.TabIndex = [System.Int32]0
$button2.Text = [System.String]'Button'
$button2.UseVisualStyleBackColor = $true
#
#textBox1
#
$textBox1.Anchor = ([System.Windows.Forms.AnchorStyles][System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right)
$textBox1.Location = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]41))
$textBox1.Multiline = $true
$textBox1.Name = [System.String]'textBox1'
$textBox1.ScrollBars = [System.Windows.Forms.ScrollBars]::Both
$textBox1.Size = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]773,[System.Int32]307))
$textBox1.TabIndex = [System.Int32]1
#
#SaugOpti
#
$SaugOpti.ClientSize = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]797,[System.Int32]360))
$SaugOpti.Controls.Add($textBox1)
$SaugOpti.Controls.Add($button2)
$SaugOpti.Name = [System.String]'SaugOpti'
$SaugOpti.TopMost = $true
$SaugOpti.ResumeLayout($false)
$SaugOpti.PerformLayout()
Add-Member -InputObject $SaugOpti -Name base -Value $base -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name button2 -Value $button2 -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name textBox1 -Value $textBox1 -MemberType NoteProperty
Add-Member -InputObject $SaugOpti -Name button1 -Value $button1 -MemberType NoteProperty
}
. InitializeComponent
$button2_Click = {
$SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
}
# Aufruf muss nach der Definition von $button2_Click geschehen!
$button2.add_Click($button2_Click)
$SaugOpti.textBox1.AppendText($Synch) # Übername aus der DLL
$SaugOpti.ShowDialog()

Zitat von @Johann.Z:
Habe deine Anpassungen übernommen.
So richtig habe ich es zwar nicht verinnerlicht,
Ist doch eigentlich ganz einfachHabe deine Anpassungen übernommen.
So richtig habe ich es zwar nicht verinnerlicht,
Wenn du folgenden Aufruf
$button2.add_Click($button2_Click)
schon machst ohne das die Variable $button2_Click zu dem Zeitpunkt Inhalt hat, dann übergibt du der Funktion ja leeren Inhalt. Es bringt hier also nichts die Variable hinterher zu definieren weil der Funktionsaufruf ja schon abgearbeitet wurde, also dem Click Event wurde schon ein leerer Inhalt übergeben wurde.Wenn du die Variable neu definierst musst du auch den Eventhandler mit neuem Inhalt definieren, denn dieser wird ja nicht dynamisch erzeugt sondern durch den Aufruf der add_click Funktion zugewiesen und dabei wird der Inhalt von der Variablen $button2_Click einmalig expandiert.