我试图让进度条在表单上工作,但我他妈的无法让它工作。这里的主要焦点是下载文件,并在显示下载进度的表单上有一个进度条。表单和代码在不同的运行空间中运行,因此进度条控件似乎没有从“代码运行空间”更新。我绝不是编码员或 PowerShell 专家。这是我主要从这个网站整理出来的,然后用谷歌搜索所有的废话。
如果有人可以帮助甚至指出我正确的方向,那将有所帮助。
下面是我的脚本。
#Hash table for runspaces
$hash = [hashtable]::Synchronized(@{})
#FUNCIONS
#Append output to text box display.
Function Add-OutputBoxLine {
Param ($Message)
$hash.results.AppendText("$Message")
$hash.results.Refresh()
$script:hash.results.ScrollToCaret()
$script:hash.results.SelectionStart = $hash.results.Text.Length
$hash.results.Selectioncolor = "WindowText"
$hash.Form.Refresh()
}
Function closeForm()
{ $hash.form.close() }
Function RunAppCode {
$scriptRun = {
#Suppress Errors as to not interrupt the GUI experience. Comment these out when debugging.
$script:ErrorActionPreference = 'SilentlyContinue'
#$script:ProgressPreference = 'SilentlyContinue'
$hash.results.Clear()
$hash.start_button.Enabled = $false
$hash.start_button.IsAccessible = $false
#VARIABLES WITHIN scriptRun
#Download link for stuff
$Url = 'https://releases.ubuntu.com/22.04.2/ubuntu-22.04.2-desktop-amd64.iso'
#Variable for downloads directory
$downloadhome = (New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
#Variable for where stuff zip file will be downloaded to
$downloadzipfile = $downloadhome + "\stuff.iso"
#Download latest stuff
$hash.results.AppendText("`r`n<:.info.:> Downloading latest stuff")
Get-ChildItem -Path $downloadhome -Filter stuff.iso | Remove-Item -Force
$global:ProgressPreference = "Continue"
Start-Sleep -Seconds 3
$hash.label1.text = "Downloading..."
#$hash.form.controls.AddRange(@($hash.progressbar1,$hash.label1))
#$hash.label1.Visible
#$hash.progressbar1.Visible
#Start-Sleep 20
#exit
#Funtion is here because I can't get it to work when not in this runspace
function DownloadFile($url1, $targetFile) {
$uri = New-Object "System.Uri" "$url1"
$request = [System.Net.HttpWebRequest]::Create($uri)
$request.set_Timeout(15000) #15 second timeout
$response = $request.GetResponse()
$totalLength = [System.Math]::Floor($response.get_ContentLength() / 1024)
$responseStream = $response.GetResponseStream()
$targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $targetFile, Create
$buffer = new-object byte[] 10KB
$count = $responseStream.Read($buffer, 0, $buffer.length)
$downloadedBytes = $count
while ($count -gt 0) {
$targetStream.Write($buffer, 0, $count)
$count = $responseStream.Read($buffer, 0, $buffer.length)
$downloadedBytes = $downloadedBytes + $count
Write-Progress -activity "Downloading file '$($url1.split('/') | Select -Last 1)'" -status "Downloaded ($([System.Math]::Floor($downloadedBytes/1024))K of $($totalLength)K): " -PercentComplete ((([System.Math]::Floor($downloadedBytes / 1024)) / $totalLength) * 100)
}
Write-Progress -activity "Finished downloading file '$($url1.split('/') | Select -Last 1)'"
$targetStream.Flush()
$targetStream.Close()
$targetStream.Dispose()
$responseStream.Dispose()
}
$download =
try {
#Invoke-WebRequest -Uri $Url -OutFile $downloadzipfile -ErrorAction Stop
DownloadFile $url $downloadzipfile
}
catch {
$err = $_
$results.text += "`r`n" + "<:.erro.:> $err"
}
$job = Start-Job -ScriptBlock { $download }
do { [System.Windows.Forms.Application]::DoEvents() } until ($job.State -eq "Completed")
Remove-Job -Job $job -Force
$hash.label1.Text = "Download Complete"
$hash.label1.Hide()
$hash.progressbar1.Hide()
Start-Sleep -Seconds 3
} #Close the $scriptRun brackets for the runspace
#Configure max thread count for RunspacePool.
$maxthreads = [int]$env:NUMBER_OF_PROCESSORS
#Create a new session state for parsing variables ie hashtable into our runspace.
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'hash', $hash, $Null
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
#Add the variable to the RunspacePool sessionstate
$InitialSessionState.Variables.Add($hashVars)
#Create our runspace pool. We are entering three parameters here min thread count, max thread count and host machine of where these runspaces should be made.
$script:runspace = [runspacefactory]::CreateRunspacePool(1, $maxthreads, $InitialSessionState, $Host)
#Create a PowerShell instance.
$script:powershell = [powershell]::Create()
#Open a RunspacePool instance.
$script:runspace.Open()
#Add our main code to be run via $scriptRun within our RunspacePool.
$script:powershell.AddScript($scriptRun)
$script:powershell.RunspacePool = $script:runspace
#Run our RunspacePool.
$script:handle = $script:powershell.BeginInvoke()
#Cleanup our RunspacePool threads when they are complete ie. GC.
if ($script:handle.IsCompleted) {
$script:powershell.EndInvoke($script:handle)
$script:powershell.Dispose()
$script:runspace.Dispose()
$script:runspace.Close()
[System.GC]::Collect()
}
}
#Closing the function.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# Main Form
$hash.form = New-Object system.Windows.Forms.Form
$hash.form.ClientSize = New-Object System.Drawing.Point(811, 483)
$hash.form.text = "Stuff"
$hash.form.TopMost = $false
$hash.form.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
$hash.form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
$hash.form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$hash.okla_logo = New-Object system.Windows.Forms.PictureBox
$hash.okla_logo.width = 454
$hash.okla_logo.height = 159
$hash.okla_logo.location = New-Object System.Drawing.Point(43, -2)
$hash.okla_logo.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$hash.okla_logo.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
$hash.aao_logo = New-Object system.Windows.Forms.PictureBox
$hash.aao_logo.width = 129
$hash.aao_logo.height = 99
$hash.aao_logo.location = New-Object System.Drawing.Point(652, 370)
$hash.aao_logo.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$hash.exit_button = New-Object system.Windows.Forms.Button
$hash.exit_button.text = "Exit"
$hash.exit_button.width = 112
$hash.exit_button.height = 35
$hash.exit_button.location = New-Object System.Drawing.Point(536, 214)
$hash.exit_button.Font = New-Object System.Drawing.Font('Calibri', 10, [System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))
$hash.exit_button.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
$hash.exit_button.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#ffffff")
$hash.start_button = New-Object system.Windows.Forms.Button
$hash.start_button.text = "Download"
$hash.start_button.width = 112
$hash.start_button.height = 35
$hash.start_button.location = New-Object System.Drawing.Point(536, 162)
$hash.start_button.Font = New-Object System.Drawing.Font('Calibri', 10, [System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))
$hash.start_button.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
$hash.start_button.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#ffffff")
$hash.results = New-Object System.Windows.Forms.TextBox
$hash.results.multiline = $true
$hash.results.Scrollbars = "Vertical"
$hash.results.width = 509
$hash.results.height = 248
$hash.results.location = New-Object System.Drawing.Point(14, 162)
$hash.results.Font = New-Object System.Drawing.Font('Lucida Console', 8)
$hash.results.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
$hash.results.ReadOnly = $True
$hash.progressbar1 = New-Object System.Windows.Forms.ProgressBar
$hash.progressbar1.width = 508
$hash.progressbar1.height = 10
$hash.progressbar1.location = New-Object System.Drawing.Point(14, 413)
#$hash.progressbar1.Style = "Marquee"
$hash.progressbar1.Style = "Continuous"
$hash.progressbar1.MarqueeAnimationSpeed = 20
#$hash.progressbar1.Hide()
#$hash.progressbar1.Visible = $false
$hash.label1 = New-Object system.Windows.Forms.Label
$hash.label1.text = "Waiting..."
$hash.label1.AutoSize = $false
$hash.label1.width = 200
$hash.label1.height = 15
$hash.label1.location = New-Object System.Drawing.Point(28, 424)
$hash.label1.Font = New-Object System.Drawing.Font('Calibri', 8, [System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))
$hash.label1.ForeColor = 'red'
$hash.label1.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
#$hash.label1.Hide()
#$hash.label1.Visible = $false
$hash.disclaimer = New-Object system.Windows.Forms.TextBox
$hash.disclaimer.multiline = $true
$hash.disclaimer.text = "BLA BLA BLA BLA BLA BLA"
$hash.disclaimer.width = 429
$hash.disclaimer.height = 20
$hash.disclaimer.location = New-Object System.Drawing.Point(53, 442)
$hash.disclaimer.Font = New-Object System.Drawing.Font('Calibri', 10, [System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))
$hash.disclaimer.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#ff0000")
$hash.disclaimer.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#000000")
$hash.form.controls.AddRange(@($hash.okla_logo, $hash.aao_logo, $hash.exit_button, $hash.start_button, $hash.results, $hash.disclaimer, $hash.progressbar1, $hash.label1))
$hash.start_button.Add_Click({ RunAppCode })
$hash.exit_button.Add_Click({ closeForm
$hash.Form.Tag = $hash.Form.close()
#$script:powershell.EndInvoke($script:handle)
#$script:powershell.Close()
#$script:powershell.Dispose()
#$script:runspace.Close()
#$script:runspace.Dispose()
#[System.GC]::Collect()
})
$formresult = $hash.Form.ShowDialog()
if ($formresult -eq [System.Windows.Forms.DialogResult]::Cancel) {
Exit
}
#Region Logic
##All done!
#endregion