I'm having an issue with double hopping scriptblock for background job that either does nothing or freezes the script. Explenation below.
The idea for the script is to get a list of files (very large count, ~200k) and then process them in three individual ways (get hashcodes and get true duplicates, compare filenames and get pseudo duplicates, get zero length files). At this moment I'm working on hashes. The result of $job1
is a string (array?) that cannot be piped to get-filehash
. This results in $job2
looping through each string in order to get hashes. As background-jobs work on scriptblocks and foreach
loop has scriptblock
component a double hop is created. I've worked around that by using invoke-command
combined with [scriptblock]::Create()
method inside job scriptblock. That unfortunately freezes the form. My question to you is as follows. How do I force $job1
result to be of system.io.fileinfo
type OR how do I unfreeze script while Invoke-command is in progress?
Add-Type -AssemblyName System.Windows.Forms
add-type -AssemblyName system.drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
$path = "C:\"
$window = New-Object system.Windows.Forms.Form
$window.Size = New-Object system.Drawing.Size @(400,400)
$window.StartPosition = "CenterScreen"
$window.Font = New-Object System.Drawing.Font("Calibri",11,[System.Drawing.FontStyle]::Bold)
$window.Text = "STARTING UP"
$ProgressBar1 = New-Object System.Windows.Forms.ProgressBar
$ProgressBar1.Location = New-Object System.Drawing.Point(10, 10)
$ProgressBar1.Size = New-Object System.Drawing.Size(365, 20)
$ProgressBar1.Style = "Marquee"
$ProgressBar1.MarqueeAnimationSpeed = 20
$ProgressBar1.UseWaitCursor = $true
$ProgressBar1.Visible = $false
$button = New-Object System.Windows.Forms.Button
$button.size = New-Object system.drawing.size @(50,50)
$button.Location = New-Object System.Drawing.Point(20, 70)
$button.Text = "TEST"
$window.Controls.add($button)
$label = New-Object System.Windows.Forms.Label
$label.Size = New-Object System.Drawing.Size @(100, 50)
$label.Location = New-Object System.Drawing.Point (80, 70)
$label.BorderStyle = 'Fixed3D'
$label.ForeColor = 'green'
$label.TextAlign = 'middlecenter'
$window.Controls.Add($label)
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.add_Tick({$script:time2 =((get-date)-$script:time1).ToString("hh\:mm\:ss")
$label2.text = $script:time2
})
$button.add_Click(
{$1 = Get-Date
$Script:time1 = Get-Date
$timer.start()
$ProgressBar1.BringToFront()
$ProgressBar1.Show()
$this.Enabled = $false
$job = Start-Job -ScriptBlock {
Get-ChildItem -File -recurse $HOME -ErrorAction SilentlyContinue|select -ExpandProperty FullName
}
while($job.State -eq 'Running') {
[System.Windows.Forms.Application]::DoEvents()
}
$script:asd = $job | Receive-Job #-AutoRemoveJob -Wait
$ProgressBar1.Hide()
$this.Enabled = $true
$2 = ((get-date) - $1).ToString("hh\:mm\:ss")
$label.text = $2
$timer.stop()
}
)
$button2 = New-Object System.Windows.Forms.Button
$button2.Size = New-Object System.Drawing.Size @(50, 50)
$button2.Location = New-Object System.Drawing.Point (200, 70)
$button2.Text = 'Exit'
$window.Controls.Add($button2)
$button2.add_Click({$window.Close()})
$button3 = new-object System.Windows.Forms.Button
$button3.Size = New-Object System.Drawing.Size @(50, 50)
$button3.Location = New-Object System.Drawing.Point (20, 200)
$button3.Text = "Start"
$window.Controls.Add($button3)
$button3.add_Click({
$sb = foreach ($qwe in $Script:asd){Get-FileHash $qwe -Algorithm MD5|select -ExpandProperty Hash -OutVariable +Script:tester}
$ProgressBar2.BringToFront()
$ProgressBar2.Show()
$this.Enabled = $false
$job2 = start-job -Name 'asd' -scriptblock {
param($sb)
$sb = [scriptblock]::Create($sb)
Invoke-command -ScriptBlock $sb
}
while($job2.State -eq 'Running') {
[System.Windows.Forms.Application]::DoEvents()
}
Write-Host $Script:tester
$ProgressBar2.Hide()
$this.Enabled = $true
})
$label2 = New-Object System.Windows.Forms.Label
$label2.size = New-Object System.Drawing.Size @(100, 50)
$label2.Location = New-Object System.Drawing.Point (80, 200)
$label2.BorderStyle = 'Fixed3D'
$label2.ForeColor = 'green'
$label2.TextAlign = 'middlecenter'
$window.Controls.Add($label2)
$ProgressBar2 = New-Object System.Windows.Forms.ProgressBar
$ProgressBar2.Location = New-Object System.Drawing.Point(10, 330)
$ProgressBar2.Size = New-Object System.Drawing.Size(365, 20)
$ProgressBar2.Style = "Marquee"
$ProgressBar2.MarqueeAnimationSpeed = 20
$ProgressBar2.UseWaitCursor = $true
$ProgressBar2.Visible = $false
$window.Controls.Add($ProgressBar2)
$groupbox = New-Object System.Windows.Forms.GroupBox
$groupbox.size = New-Object system.drawing.size @(377, 365)
$groupbox.Location = New-Object System.Drawing.point (4, -5)
$window.Controls.Add($groupbox)
$window.Controls.Add($ProgressBar1)
$window.ShowDialog()|out-null
For anyone interested. The answer was piping $job
results to set-variable
- $job|Wait-job|Receive-Job|Set-Variable -Name JOB_RESULT -Scope Script
.
Then using $using:
scope in $job2
scriptblock - $job2 = start-job -scriptblock { $using:JOB_RESULT|Get-FileHash -Algorithm MD5}