2

I am fighting with a problem in my PowerShell 4.0 script. I constructed a user interface using the windows Forms namespace but need to do some time consuming processing which is why I adopted for a BackgroundWorker to keep my GUI responsive.

Once I started I used the $Worker.Add_DoWork({}) method to add an event subscription but this does not work. That is why I used the Register-ObjectEvent instead. Now my DoWork event is only executed once I close my Form and I don't get why this is happening. My code is below, can anyone help me with this issue?

#Create worker object
$Worker = new-object System.ComponentModel.BackgroundWorker;
$Worker.WorkerReportsProgress = $true;

#Handles $Worker.ReportProgress event
$ReportProgress = {$Progressbar.PerformStep()}; 

#Handles $Worker.DoWork event
$DoWork = { write-host("do work event fired")};

#Add eventhandlers
Register-ObjectEvent -InputObject $Worker -EventName DoWork -Action $DoWork ;
Register-ObjectEvent -InputObject $Worker -EventName ProgressChanged -Action $ReportProgress; 

If I call the $Worker.RunWorkerAsync() method in my script, no output is generated. If I close my form which called the $Worker.RunWorkerAsync() method the text "Do work event fired" is output into the PowerShell console.

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151

1 Answers1

3

To answer my own question, here is the file-copy example which updates a progressbar. The Copy-File method was taken from the example given by stej in the thread Progress during large file copy (Copy-Item & Write-Progress?) which I modified for my own needs. Just listen for events from the background job in the main script.

#Register event
Register-EngineEvent -SourceIdentifier Progress -Action {
                        $Progressbar.Value = $event.MessageData; 
                        $StatusText.Text = "Copying VHD File - " + $event.MessageData + " % complete"; 
                        $Form.Refresh();} >null

#Create worker and perform the work
$worker = start-job -name "Work" -scriptblock {    
Register-EngineEvent -SourceIdentifier Progress -Forward;

function Copy-File 
{
    param( [string]$from, [string]$to)
    $ffile = [io.file]::OpenRead($from)
    $tofile = [io.file]::OpenWrite($to)

    try {

        [byte[]]$buff = new-object byte[] 4096 #(4096*1024)
        [long]$total = [long]$count = 0
        do {
            $count = $ffile.Read($buff, 0, $buff.Length)
            $tofile.Write($buff, 0, $count)
            $total += $count
            [int]$pctcomp = ([int]($total/$ffile.Length* 100));
            if ($total % 1mb -eq 0) {
                   New-Event -SourceIdentifier Progress -MessageData  $pctcomp;
            }
        } while ($count -gt 0)

    }

    finally {
         $ffile.Close();
         $tofile.Close();
        }
}

Copy-File -from ("F:\HIS0402_C.wim") -to ("X:\JT\HIS0164.vhd");
};
Community
  • 1
  • 1