BITS Transfer with GUI Progress Bar

This topic contains 0 replies, has 1 voice, and was last updated by Profile photo of Jonathan Bailey Jonathan Bailey 1 year, 9 months ago.

  • Author
    Posts
  • #22675
    Profile photo of Jonathan Bailey
    Jonathan Bailey
    Participant

    So I'd like to first thank anyone who can help out with my problem although it's not entirely mission critical, it is interesting to figure out, and I'd like some help refactoring this code.
    The problem is regarding BITS transfers. BITS is an amazing service and for anyone doing local network transfers it's tits and you need to start using it. Here's a great example of how you can use BITS to store a background job transferring multiple files through the network, and if an error occurs, automatically restart the job:

    get-module bitstransfer
    Start-BitsTransfer -Destination \\pathto\transfer -Source d:\files*.* -Asynchronous -Credential (Get-Credential) -Priority  -RetryTimeout 60 -RetryInterval 120
    
    $bits = Get-BitsTransfer -Name "BITS Transfer"
    
    while ($bits.JobState -eq "Transferring" -or $bits.JobState -eq "TransientError" -or $bits.JobState -eq "Connecting" -or $bits.jobstate -eq "Error"  -and $pct -ne 100){
        if ($bits.jobstate -eq "Error"){
            Resume-BitsTransfer -BitsJob $bits
        }
    
        $pct = ($bits.BytesTransferred / $bits.BytesTotal)*100
        Write-Host "Percent complete: $pct" 
        Start-Sleep 5
    }

    As you can see, it also updates you with the percent transferred. It's rough around the edges but it works. While you could just substitute that with write-progress, you could actually add a GUI progress bar and be all spiffy with a gui tool (script repurposed from [url]http://mcpmag.com/articles/2014/02/18/progress-bar-to-a-graphical-status-box.aspx[/url] ):

    Add-Type -assembly System.Windows.Forms
    
    #title for the winform
    $Title = "BITS Transfer Progress"
    #winform dimensions
    $height=100
    $width=400
    #winform background color
    $color = "White"
    
    #create the form
    $form1 = New-Object System.Windows.Forms.Form
    $form1.Text = $title
    $form1.Height = $height
    $form1.Width = $width
    $form1.BackColor = $color
    
    $form1.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle 
    #display center screen
    $form1.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    
    # create label
    $label1 = New-Object system.Windows.Forms.Label
    $label1.Text = "not started"
    $label1.Left=5
    $label1.Top= 10
    $label1.Width= $width - 20
    #adjusted height to accommodate progress bar
    $label1.Height=15
    $label1.Font= "Verdana"
    #optional to show border 
    #$label1.BorderStyle=1
    
    #add the label to the form
    $form1.controls.add($label1)
    
    $progressBar1 = New-Object System.Windows.Forms.ProgressBar
    $progressBar1.Name = 'progressBar1'
    $progressBar1.Value = 0
    $progressBar1.Style="Continuous"
    
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = $width - 40
    $System_Drawing_Size.Height = 20
    $progressBar1.Size = $System_Drawing_Size
    
    $progressBar1.Left = 5
    $progressBar1.Top = 40
    $form1.Controls.Add($progressBar1)
    $form1.Show()| out-null
    
    #give the form focus
    $form1.Focus() | out-null
    
    #update the form
    $label1.Text = "Preparing to send files"
    $form1.Refresh()
    
    start-sleep -Seconds 1
    
    get-module bitstransfer
    Start-BitsTransfer -Destination \\pathto\transfer\ -Source d:\file*.* -Asynchronous -Credential (Get-Credential) -Priority Normal -RetryTimeout 60 -RetryInterval 120 -DisplayName "AutoTransfer" -Description "GUI Test"
    
    $bits = Get-BitsTransfer -Name "AutoTransfer"
    $pct = 0
    while ($bits.JobState -ne "Transferred"  -and $pct -ne 100){
        if ($bits.jobstate -eq "Error" -or $bits.JobState -eq "TransientError" ){
            Resume-BitsTransfer -BitsJob $bits
        }
    
        $pct = ($bits.BytesTransferred / $bits.BytesTotal)*100
        $progressbar1.Value = $pct
        Start-Sleep -Milliseconds 100
        $label1.text="Sending files..."
        $form1.Refresh()
    }
    
    $form1.Close()

    As a proof of concept, I was pretty impressed. But here's where I hit a wall. I tried to integrate it into a script of my own but I can't seem to get the BITS transfer to run as a background task.
    The problem is that as soon I integrate the task into a function, the BITS transfer doesn't seem to play nice with the rest of the progress bar logic. I have the problem script attached as a file. It's a large script but it's mostly because of the gui elements. The problem lies in the functions set-progress and copy-cpslist I think. In debugging the script, I found that what happens is that the BITS transfer job starts and completes before the while loop begins. Even when using start-job the same issue arises. I'm pretty sure that BITS runs in the foreground because it's being called inside a function. However, I'd rather not presume and find out for sure. It would be very interesting to know what's going on in the background. Thanks ahead of time.

You must be logged in to reply to this topic.