johann.z
Goto Top

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

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()
2022-04-08 11_47_34-
2022-04-08 11_45_09-ma_pa

Content-Key: 2446436423

Url: https://administrator.de/contentid/2446436423

Printed on: April 23, 2024 at 20:04 o'clock

Mitglied: 1915348599
1915348599 Apr 08, 2022 updated at 10:11:01 (UTC)
Goto Top
Weil du
$button2.add_Click($button2_Click)
ja schon vorher ausführst ohne das
$button2_Click = {
$SaugOpti.textBox1.Clear()
$SaugOpti.textBox1.AppendText("Hallo")
}
je definiert wurde face-wink. 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({
    $SaugOpti.textBox1.Clear()
    $SaugOpti.textBox1.AppendText("Hallo")  
})
Member: Johann.Z
Johann.Z Apr 08, 2022 at 10:44:54 (UTC)
Goto Top
Aber der Designer wird doch als erstes dot-sourced geladen.
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☺
2022-04-08 12_37_03-saugopti - microsoft visual studio (administrator)
Mitglied: 1915348599
1915348599 Apr 08, 2022 updated at 10:51:29 (UTC)
Goto Top
Zitat von @Johann.Z:

Aber der Designer wird doch als erstes dot-sourced geladen.
Ja bringt aber nix wenn die Reihenfolge der Aufrufe nicht stimmt face-wink. 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!
Mitglied: 1915348599
Solution 1915348599 Apr 08, 2022 updated at 15:38:27 (UTC)
Goto Top
Hier vergleiche beide Skripte und du siehst den Unterschied:

back-to-topDeine 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()

back-to-topMit 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()
Member: Johann.Z
Johann.Z Apr 09, 2022 at 05:10:05 (UTC)
Goto Top
Hi, vielen Dank für die Hilfe
Leider kann im Designerfile nichts ändern, da der Code von PowerShell Pro Tools automatisch generiert wird und Änderungen nicht zugelassen werden.
Ich werde mir das Ganze jetzt in aller Frische anschauen und versuchen zu lösen.
Die Ursache ist ja jetzt, Dank dir, klar.
Gruß Johann
Member: Johann.Z
Johann.Z Apr 09, 2022 at 05:49:36 (UTC)
Goto Top
Habe deine Anpassungen übernommen.
So richtig habe ich es zwar nicht verinnerlicht, aber jetzt funktioniert es, wie es soll.

Vielen Dank für die Unterstützung
Gruß Johann
Mitglied: 1915348599
1915348599 Apr 09, 2022 updated at 06:08:34 (UTC)
Goto Top
Zitat von @Johann.Z:

Habe deine Anpassungen übernommen.
So richtig habe ich es zwar nicht verinnerlicht,
Ist doch eigentlich ganz einfach
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.