none
powershell listbox freezes in version 2 but not version 4 RRS feed

  • Question

  • I have been experimenting with Powershell and some simple gui scripts using windows.forms. With the following test script using Powershell 4 it works like I would expect, but with Powershell 2 it does not.

    I want the following 5 commands to be written to the listbox in real time as they are run when the button is activated

    $listbox.Items.add('test')
    $listbox.items.add((Get-WmiObject softwarelicensingproduct | Where-Object {($_.applicationid -eq "55c92734-d682-4d71-983e-d6ec3f16059f") -and ($_.partialproductkey)} | foreach {$_.partialproductkey}))
    $listbox.Items.add('test')
    $listbox.items.add((Get-WmiObject softwarelicensingproduct | Where-Object {($_.applicationid -eq "55c92734-d682-4d71-983e-d6ec3f16059f") -and ($_.partialproductkey)} | foreach {$_.partialproductkey}))
    $listbox.Items.add('test')

    when I run the code from Powershell 4 it writes to the listbox as each of the 5 commands complete. When I run the same code from powershell 2, it does not list anything for a while, then just writes to the listbox in one blob after the final command competes. For compatibility I would prefer to figure out how to make it run properly using powershell 2

    here is all the code if you would like to test it. all it does it gets a partial product key and displays it

    [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
    [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
    
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "test"
    $drawing_size = New-Object System.Drawing.Size
    $drawing_size.Width = 500
    $drawing_size.Height = 600
    $form.ClientSize = $drawing_size
    
    #this code creates the listbox object
    $listbox = New-Object System.Windows.Forms.ListBox
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 400
    $System_Drawing_Size.Height = 400
    $listBox.Size = $System_Drawing_Size
    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 50
    $System_Drawing_Point.Y = 50
    $listBox.Location = $System_Drawing_Point                                   
    $form.Controls.Add($listbox)
    
    $buttonhandler =
    {
    $listbox.Items.add('test')
    $listbox.items.add((Get-WmiObject softwarelicensingproduct | Where-Object {($_.applicationid -eq "55c92734-d682-4d71-983e-d6ec3f16059f") -and ($_.partialproductkey)} | foreach {$_.partialproductkey}))
    $listbox.Items.add('test')
    $listbox.items.add((Get-WmiObject softwarelicensingproduct | Where-Object {($_.applicationid -eq "55c92734-d682-4d71-983e-d6ec3f16059f") -and ($_.partialproductkey)} | foreach {$_.partialproductkey}))
    $listbox.Items.add('test')
    }
    
    
    $button = New-Object System.Windows.Forms.Button
    $button.Text = "test"
    $drawing_point = New-Object System.Drawing.Point
    $drawing_point.x = 10
    $drawing_point.y = 500
    $drawing_size = New-Object System.Drawing.Size
    $drawing_size.width = 75
    $drawing_size.Height = 35
    $button.Size = $drawing_size
    $button.Location = $drawing_point
    $button.add_Click($buttonhandler)
    $form.Controls.Add($button)
    
    $form.ShowDialog() | Out-Null

    Saturday, December 12, 2015 3:26 AM

Answers

  • Change  the threading type of PS2.  Better yet.  Upgrade as PS2 is now almost obsolete.  When the full release of PS 5 comes in a month P2 will no longer be supported

    \_(ツ)_/



    • Edited by jrv Saturday, December 12, 2015 3:59 AM
    • Marked as answer by pete pete Sunday, December 13, 2015 9:04 PM
    Saturday, December 12, 2015 3:58 AM
  • Start PowerShell like this:

    powershell -sta


    \_(ツ)_/

    • Marked as answer by pete pete Sunday, December 13, 2015 9:02 PM
    • Unmarked as answer by pete pete Sunday, December 13, 2015 9:03 PM
    • Marked as answer by pete pete Sunday, December 13, 2015 9:04 PM
    Saturday, December 12, 2015 4:43 AM

All replies

  • Change  the threading type of PS2.  Better yet.  Upgrade as PS2 is now almost obsolete.  When the full release of PS 5 comes in a month P2 will no longer be supported

    \_(ツ)_/



    • Edited by jrv Saturday, December 12, 2015 3:59 AM
    • Marked as answer by pete pete Sunday, December 13, 2015 9:04 PM
    Saturday, December 12, 2015 3:58 AM
  • Thanks! 

    I am writing some scripts which need to run on a default  install of windows 7, so I am stuck with version 2. Could you eleberate a little more on changing the threading type? 

    • Marked as answer by pete pete Sunday, December 13, 2015 9:02 PM
    • Unmarked as answer by pete pete Sunday, December 13, 2015 9:02 PM
    Saturday, December 12, 2015 4:24 AM
  • Start PowerShell like this:

    powershell -sta


    \_(ツ)_/

    • Marked as answer by pete pete Sunday, December 13, 2015 9:02 PM
    • Unmarked as answer by pete pete Sunday, December 13, 2015 9:03 PM
    • Marked as answer by pete pete Sunday, December 13, 2015 9:04 PM
    Saturday, December 12, 2015 4:43 AM
  • I fixed much of the unnecessary code and tested.  I see no difference between V2 and V4 with this code,

    Add-Type -AssemblyName System.Windows.Forms
    
    $form = New-Object System.Windows.Forms.Form
    $form.Text = 'test'
    $form.Size='500,600'
    
    $listbox = New-Object System.Windows.Forms.ListBox
    $form.Controls.Add($listbox)
    $listBox.Size = '400,400'
    $listBox.Location = '50,50'
    
    $button = New-Object System.Windows.Forms.Button
    $form.Controls.Add($button)
    $button.Text = "test"
    $button.Size = '75,25'
    $button.Location = '10,500'
    $button.add_Click({
    	$app = Get-WmiObject SoftwareLicensingProduct -filter 'applicationid = "55c92734-d682-4d71-983e-d6ec3f16059f" AND PartialProductKey Is Not null'
    	$listbox.Items.add('test')
    	$listbox.Items.Add($app.PartialProductKey)
    	$listbox.Items.add('test')
    	$listbox.Items.Add($app.PartialProductKey)
    	$listbox.Items.add('test')
    })
    
    $form.ShowDialog()

    Try not to write so many lines of unnecessary code.  Test one line at a time until you understand what it does.


    \_(ツ)_/

    Saturday, December 12, 2015 5:07 AM
  • Thank you very much for your help! I am really amazed that you do not need to use an object for both location and size like I saw in all of the other code examples

    is what scenarios are these necessary in? 

    new-object system.drawing.size
    new-object system.drawing.point

     

    Saturday, December 12, 2015 11:46 PM
  • This kind of conversion is a result of a lack of understanding of both programming and Net. It is also due to trying to convert C# examples to PowerShell without understanding how PowerShell works.

    While use of these constructs is not specifically wrong they are completely unnecessary in PowerShell.  PowerShell does an auto-cast in most instances.  Also if you really understand the objects then you would see why this is not necessary in C# or PowerShell.

    $form.Size='100,200'

    OR

    $size=New-Object System.Drawing.Size(100,200)

    OR

    $size = New-Object System.Drawing.Size
    $size.Width=100
    $size.Height=200

    Now a cast:

    [System.Drawing.Size]'100,200'

    Now look at the form "Size" declaration:

    PS C:\scripts> $form.Size.GetType()

    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Size                                     System.ValueType

    Note that it is a "Size" type of object.

    So..

    $form.Size=[System.Drawing.Size]'100,200' # calls the static constructor

    is equivalent to ...

    $form.Size='100,200'

    Which is because the cast is implied in the definition.  The same thing is true - with caveats - in C#.

    PowerShell makes many things more convenient compared to classical programming.  That is one purpose of a scripting system.


    \_(ツ)_/


    • Edited by jrv Sunday, December 13, 2015 12:05 AM
    • Marked as answer by pete pete Sunday, December 13, 2015 9:03 PM
    • Unmarked as answer by pete pete Sunday, December 13, 2015 9:03 PM
    Sunday, December 13, 2015 12:03 AM
  • Thank you very much for taking the time to explain that. I am such a novice coder with just a start of an understanding of powershell and .net  programming. This is all very new to me. My background is very basic python and batch scripting. 
    Sunday, December 13, 2015 3:36 AM
  • I was trying to clean up some other code I had,using your examples, but I noticed my forms were changing sizes. 

    this code make a different size form

    Add-Type -AssemblyName System.Windows.Forms
    
    $form = New-Object System.Windows.Forms.Form
    $form.Text = 'test'
    $form.Size="500,500"
    
    $form.ShowDialog()

    than this code. 

    Add-Type -AssemblyName System.Windows.Forms
    
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "test"
    $drawing_size = New-Object System.Drawing.Size
    $drawing_size.Width = 500
    $drawing_size.Height = 500
    $form.ClientSize = $drawing_size
    
    $form.ShowDialog() | Out-Null

    I apologize if I am taking to much of your time.

    Sunday, December 13, 2015 6:29 PM
  • "Size" and "ClientSize" are two different properties.  A "Size" object is not needed for either.

    \_(ツ)_/

    Sunday, December 13, 2015 7:49 PM
  • "Size" and "ClientSize" are two different properties.  A "Size" object is not needed for either.

    \_(ツ)_/

    I did not realize I did that. I thought I used "Size" for both. Thanks for pointing that out.
    Sunday, December 13, 2015 8:54 PM