到目前为止,原始脚本/工具是1000多行,所以我做了一个代表我的问题的模拟。
这段代码的基本功能是创建一个带有GUI的父线程,其开始按钮创建子线程,用于复制和执行远程计算机上的文件。我希望那些子线程用结果更新父线程的文本框。在代码中,我标记了我的尝试。
我已经阅读过如何在子线程中创建GUI并通过父线程进行操作但是如果我这样做,我想我必须移动所有与GUI有关的函数和事件,到那个孩子的话题。然后“开始”按钮(子线程创建器)将创建第二代子线程?它只是把我放在一个循环中,所以我无法使用这种方法。或者我可以让Child GUI线程以某种方式启动父线程中的进程? idk ...是否可以在父线程中创建GUI的函数/事件,但是从子线程执行? IDK的...
请提供我可以考虑的任何建议或解决方案来实现这一目标。
编辑:回顾一下问题是子线程不会更新父线程文本框。
#GUI
[XML]$XAML =
@"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Window" Title="Some tool you've never heard of" Height="450" Width="450" ResizeMode="CanMinimize">
<Grid>
<TextBox Name="Results" IsReadOnly="True" Margin="5,5,5,75" TextWrapping="Wrap" Background="Black" Foreground="White"/>
<Button Name="Start" Content="Start" Margin="5,350,5,5" Cursor="Hand"/>
</Grid>
</Window>
"@
[System.Void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
$GUI = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $XAML))
ForEach ($Node in ($XAML.SelectNodes("//*[@Name]")))
{
Set-Variable -Name "$($Node.Name)" -Value $GUI.FindName($Node.Name) -Scope Global
}
#Sync Hash Table - Attempt 2
$Global:SyncUIHash = [hashtable]::Synchronized(@{})
$Global:SyncUIHash.Window = $Window
$Global:SyncUIHash.Results = $Results
#RunSpacePool
$RunSpacePool = [RunSpaceFactory]::CreateRunspacePool(1,5)
$RunSpacePool.ApartmentState = "STA"
$RunSpacePool.Open()
#GUI Events
$Start.Add_Click({Start-Function})
#Functions
Function Start-Function
{
($PowerShell = [Powershell]::Create()).RunSpacePool = $RunspacePool
$Parameters = @{
Computer = "ComputerName"
FileToExecute = "FilePath to file that will be executed"
Arguments = "Arguments to be used on FileToExecute"
TempDir = "Remote Computer's TempDir to Copy To"
Results = $Results #Does not Work - Attempt 1
SyncUIHash = $Global:SyncUIHash #Does not work - Attempt 3
}
[System.Void]$PowerShell.AddScript({
Param (
$Computer,
$FileToExecute,
$Arguments,
$TempDir,
$Results, #Does not work - Attempt 1
$SyncUIHash #Does not work - Attempt 3
)
#Basically: Copy File to Remote Computer then Execute File
$Results.Text += "Results of whole process." #Does not work - Attempt 1
$SyncUIHash.Results.Text += "Results of whole process." # Does not work - Attempt 2 & 3
}).AddParameters($Parameters)
$PowerShell.BeginInvoke()
}
#Shows GUI
[System.Void] $GUI.ShowDialog()