Untitled
unknown
powershell
3 years ago
8.4 kB
27
Indexable
using namespace System.Windows.Forms Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Application]::EnableVisualStyles() $form1 = New-Object 'System.Windows.Forms.Form' $buttonRunPS = New-Object 'System.Windows.Forms.Button' $buttonRunC = New-Object 'System.Windows.Forms.Button' $richtextbox2 = New-Object 'System.Windows.Forms.RichTextBox' $richtextbox1 = New-Object 'System.Windows.Forms.RichTextBox' $treeview1 = New-Object 'System.Windows.Forms.TreeView' $InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState' function Start-RunspaceTask { [CmdletBinding()] Param ( [Parameter(Mandatory, Position = 0)][ScriptBlock]$ScriptBlock, [Parameter(Mandatory, Position = 1)][PSObject[]]$ProxyVars ) $Runspace = [RunspaceFactory]::CreateRunspace($InitialSessionState) $Runspace.ApartmentState = 'STA' $Runspace.ThreadOptions = 'ReuseThread' $Runspace.Open() ForEach ($Var in $ProxyVars) { $Runspace.SessionStateProxy.SetVariable($Var.VariableName, $Var.VariableValue) } $Thread = [PowerShell]::Create() $Thread.AddScript($ScriptBlock, $True) | Out-Null $Thread.Runspace = $Runspace [Void]$jobList.Add([PSObject]@{ PowerShell = $Thread; Runspace = $Thread.BeginInvoke() }) } #System.Collections.Concurrent is thread-safe $global:SyncHash = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() $global:jobList = [System.Collections.Concurrent.ConcurrentBag[object]]::new() $initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() $SyncHash.form1 = $form1 $SyncHash.treeview1 = $treeview1 $SyncHash.richtextbox1 = $richtextbox1 $SyncHash.richtextbox2 = $richtextbox2 $buttonRunC_Click = { #region Custom Types Add-Type -ReferencedAssemblies System.Windows.Forms, System.ComponentModel, System.ComponentModel.Primitives, System.Threading.Tasks -TypeDefinition @' using System.Threading.Tasks; using System.Windows.Forms; public class TreeViewHelper { public static void AddNode(TreeView TreeView, TreeNode TreeNode) { TreeView.Invoke((MethodInvoker)(() => TreeView.Nodes.Add(TreeNode))); } public static async void AddNodeAsync(TreeView TreeView, string Name) { await Task.Run(() => { TreeView.Invoke((MethodInvoker)(() => TreeView.Nodes.Add(Name))); }); } } '@ Add-Type -ReferencedAssemblies System.Windows.Forms, System.ComponentModel, System.ComponentModel.Primitives, System.Threading.Tasks -TypeDefinition @' using System.Threading.Tasks; using System.Windows.Forms; public class RichTextBoxHelper { public static void AddText(RichTextBox RichTextBoxControl, string Text) { RichTextBoxControl.Invoke((MethodInvoker)(() => RichTextBoxControl.AppendText(Text))); } public static async void AddTextAsync(RichTextBox RichTextBoxControl, string Text) { await Task.Run(() => { RichTextBoxControl.Invoke((MethodInvoker)(() => RichTextBoxControl.AppendText(Text))); }); } } '@ #endregion $ScriptBlock = { $treeview1.Nodes.Clear() | Out-Null Get-ChildItem Function: | Where-Object { $_.Name -NotLike "*:*" } | Select-Object -ExpandProperty Name | ForEach-Object { $Definition = Get-Content "function:$_" -ErrorAction Stop $SessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList "$_", $Definition $InitialSessionState.Commands.Add($SessionStateFunction) } $TopLevelDir = 'C:\Windows\System32' foreach ($FilePath in [System.Io.Directory]::EnumerateFiles($TopLevelDir, "*.dll", [System.IO.SearchOption]::AllDirectories)) { $counter = 0 $streamReader = [System.IO.StreamReader]::new($FilePath, [System.Text.Encoding]::Default) while ($null -ne ($line = $streamReader.ReadLine()) -and $counter -le 100) { #simulate read file work $counter++ } $streamReader.Close() $streamReader.Dispose() [RichTextBoxHelper]::AddText($SyncHash.richtextbox2, $FilePath) [TreeViewHelper]::AddNode($SyncHash.treeview1, $FilePath) # works from Runspace } } Start-RunspaceTask $ScriptBlock -ProxyVars @([PSObject]@{ VariableName = 'SyncHash'; VariableValue = $SyncHash }) #$ScriptBlock.invoke() #replace Start-RunspaceTask with this line if you want to debug code } $buttonRunPS_Click = { $ScriptBlock = { $treeview1.Nodes.Clear() | Out-Null Get-ChildItem Function: | Where-Object { $_.Name -NotLike "*:*" } | Select-Object -ExpandProperty Name | ForEach-Object { $Definition = Get-Content "function:$_" -ErrorAction Stop $SessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList "$_", $Definition $InitialSessionState.Commands.Add($SessionStateFunction) } $TopLevelDir = 'C:\Windows\System32' foreach ($FilePath in [System.Io.Directory]::EnumerateFiles($TopLevelDir, "*.dll", [System.IO.SearchOption]::AllDirectories)) { $counter = 0 $streamReader = [System.IO.StreamReader]::new($FilePath, [System.Text.Encoding]::Default) while ($null -ne ($line = $streamReader.ReadLine()) -and $counter -le 100) { #simulate read file work $counter++ } $streamReader.Close() $streamReader.Dispose() $SyncHash.richtextbox2.Invoke([System.Windows.Forms.MethodInvoker]{ $SyncHash.richtextbox2.AppendText($FilePath + "`n") }) # works from Runspace but very slow $SyncHash.treeview1.Invoke([System.Windows.Forms.MethodInvoker]{ $SyncHash.treeview1.Nodes.Add($FilePath) }) # works from Runspace but very slow } } Start-RunspaceTask $ScriptBlock -ProxyVars @([PSObject]@{ VariableName = 'SyncHash'; VariableValue = $SyncHash }) #$ScriptBlock.invoke() #replace Start-RunspaceTask with this line if you nwat to debug } #region Form Code $form1.SuspendLayout() $form1.Controls.Add($buttonRunPS) $form1.Controls.Add($buttonRunC) $form1.Controls.Add($richtextbox2) $form1.Controls.Add($richtextbox1) $form1.Controls.Add($treeview1) $form1.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13) $form1.AutoScaleMode = 'Font' $form1.ClientSize = New-Object System.Drawing.Size(548, 647) $form1.Name = 'form1' $form1.Text = 'Form' $buttonRunPS.Anchor = 'Bottom, Right' $buttonRunPS.Location = New-Object System.Drawing.Point(432, 612) $buttonRunPS.Name = 'buttonRunPS' $buttonRunPS.Size = New-Object System.Drawing.Size(104, 23) $buttonRunPS.TabIndex = 4 $buttonRunPS.Text = 'Run PS' $buttonRunPS.UseVisualStyleBackColor = $True $buttonRunPS.add_Click($buttonRunPS_Click) $buttonRunC.Anchor = 'Bottom, Left' $buttonRunC.Location = New-Object System.Drawing.Point(304, 612) $buttonRunC.Name = 'buttonRunC' $buttonRunC.Size = New-Object System.Drawing.Size(122, 23) $buttonRunC.TabIndex = 3 $buttonRunC.Text = 'Run C#' $buttonRunC.UseVisualStyleBackColor = $True $buttonRunC.add_Click($buttonRunC_Click) $richtextbox2.Anchor = 'Top, Bottom, Left, Right' $richtextbox2.Location = New-Object System.Drawing.Point(304, 295) $richtextbox2.Name = 'richtextbox2' $richtextbox2.Size = New-Object System.Drawing.Size(232, 311) $richtextbox2.TabIndex = 2 $richtextbox2.Text = '' $richtextbox1.Anchor = 'Top, Left, Right' $richtextbox1.Location = New-Object System.Drawing.Point(303, 12) $richtextbox1.Name = 'richtextbox1' $richtextbox1.Size = New-Object System.Drawing.Size(233, 276) $richtextbox1.TabIndex = 1 $richtextbox1.Text = '' $treeview1.Anchor = 'Top, Bottom, Left' $treeview1.Location = New-Object System.Drawing.Point(12, 12) $treeview1.Name = 'treeview1' $treeview1.Size = New-Object System.Drawing.Size(285, 623) $treeview1.TabIndex = 0 $form1.ResumeLayout() #endregion $form1.ShowDialog()
Editor is loading...