Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts

    PowerShell Call by Reference

    Hey Y'all,

    I've googled it and it should be possible but I just can't seem to get it to work

    I've got a Form with a Tab Control.
    Code:
    $tabHardware    = New-Object System.Windows.Forms.TabPage
    $tboxHardware   = New-Object System.Windows.Forms.Textbox
    Each tab has a Text Box.

    I have 9 tabs and of course 9 corresponding text boxes. That's a lot of repetitive code since each of the tabs & text boxes are identical with the exception of their Names, Captions, and Text.

    So I thought I could create a function where I would pass in the Control Objects by reference and have the function do all of the assignments for the standardized stuff.

    Code:
    function GenerateTab {
    
      param ( 
              [ref] $tabObjectName,
              [ref] $tboxObjectName,
              [string] $tabName
            )
    
      $tabObjectName.Name      = "$tabName"
      $tabObjectName.Location  = $tabLocation
      $tabObjectName.Padding   = $System_Windows_Forms_Padding
      $tabObjectName.Size      = $tabSize  
      $tabObjectName.TabIndex  = 0
      $tabObjectName.Text      = $TabName
    
      $tboxObjectName.Location   = $tboxLocation 
      $tboxObjectName.Size       = $tboxSize
      $tboxObjectName.MultiLine  = $True
      $tboxObjectName.ForeColor  = $tboxForeColor
      $tboxObjectName.BackColor  = $tboxBackColor
      $tboxObjectName.ScrollBars = 'Both'
      $tboxObjectName.Font       = $tboxFont
      $tboxObjectName.ReadOnly   = $True
    
    }   #--------------- End GenerateTab --------------------------
    So to make this work I do the following:
    Code:
    #-------------- Hardware Tab ---------------------------
      $fmt = @{Expression={$_.Item};Label="Item  ";width=25},
             @{Expression={$_.Value};Label="Value";Width=40}
    
      $HWInfo = $CITable.Rows[0..$($OSTabStartCnt-1)] | 
                        Format-Table $fmt | Out-String
    
    #Memory Info 
    
      $fmtMEM = @{Expression={$_.Speed};Label="Speed";width=5},
             @{Expression={$_.DataWidth};Label="Data Width";width=10},
             @{Expression={'{0:#.00}' -f ($_.Capacity/1gb)}; `
                               Label="Size / GB";width=9;align='right'},
             @{Expression={$_.DeviceLocator};Label="Slot";width=6},
             @{Expression={$_.SerialNumber};Label="Serial No.";width=10}
    
     
      $MemoryInfo = get-WMIObject -computer $compname Win32_PhysicalMemory | 
                    Sort-Object {$_.DeviceLocator} | Format-Table $fmtMEM | Out-String
    
      $MemTitle =  "Memory Information:`n`n" | Out-String
    
      GenerateTab -tabObjectName [ref]$tabHardware -tboxObjectName [ref]$tboxHardware -tabname "Hardware"
    
      $tboxHardware.Text = $HWInfo + $MemTitle + $MemoryInfo
    
      $MainTabControl.Controls.Add($tabHardware)
      $tabHardware.Controls.add($tboxHardware)
    This, of course, doesn't work or I wouldn't be posting.

    I've also read where you need to do the call like this:
    Code:
    GenerateTab([ref]$tabHardware)([ref]$tboxHardware)("Hardware")
    Doesn't work either.

    All I can say is HELP!

    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  2. #2
    Administrator
    Join Date
    Mar 2001
    Location
    St Louis, Missouri, USA
    Posts
    23,583
    Thanks
    5
    Thanked 1,058 Times in 927 Posts
    Did you see about_Ref in the TechNet PowerShell documentation?

    Do you get an error message?

    Joe

  3. #3
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Joe,

    No I hadn't seen that although, as you can see, I did see that Call style.

    It does not return any error messages it just doesn't render the tab correctly.
    PSByRef.JPG
    That first tab should say Hardware and show the hardware specs in a full tab textbox in Yellow on Blue like the following
    PSByRef2.JPG
    Last edited by RetiredGeek; 2015-09-01 at 22:20.
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  4. #4
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Hey Y'all,

    Well I have a solution but not the one I wanted. I spent several hours googling and searching forums w/o any help as to why the passing of references to objects didn't work. In that process I came across a post that offered a possible solution doing it a slightly different way so I gave that a whirl and success!

    So I changed the single call to two calls (GenerateTab & GenerateTextBox) both which return an Object and that seems to work just fine.
    Code:
    function GenerateTab ([string] $tabName) {
    
    $tabObjectName  = New-Object System.Windows.Forms.TabPage
    
      $tabObjectName.Name      = "$tabName"
      $tabObjectName.Location  = $tabLocation
      $tabObjectName.Padding   = $System_Windows_Forms_Padding
      $tabObjectName.Size      = $tabSize  
      $tabObjectName.TabIndex  = 0
      $tabObjectName.Text      = "$tabName"
      
    Return ,$tabObjectName
    
    }   #--------------- End GenerateTab ------------------------------------
    
    function GenerateTextBox {
    
      $tboxObjectName            = New-Object System.Windows.Forms.Textbox
    
      $tboxObjectName.Location   = $tboxLocation 
      $tboxObjectName.Size       = $tboxSize
      $tboxObjectName.MultiLine  = $True
      $tboxObjectName.ForeColor  = $tboxForeColor
      $tboxObjectName.BackColor  = $tboxBackColor
      $tboxObjectName.ScrollBars = 'Both'
      $tboxObjectName.Font       = $tboxFont
      $tboxObjectName.ReadOnly   = $True
    
      Return ,$tboxObjectName
    
    }   #---------------End GenerateTextBox ---------------------------------
    Calling Sequence:
    Code:
      $tabHardware  = GenerateTab "Hardware"
      $tboxHardware = GenerateTextBox
    
      $MainTabControl.Controls.Add($tabHardware)
      $tabHardware.Controls.Add($tboxHardware)
    
      $tboxHardware.Text = $HWInfo + $MemTitle + $MemoryInfo
    Maybe this will wind up helping someone else. I'd still like to know why the call by reference doesn't work.
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  5. #5
    5 Star Lounger
    Join Date
    Jan 2010
    Location
    Los Angeles, CA
    Posts
    828
    Thanks
    4
    Thanked 38 Times in 34 Posts
    One minor point: the param declaration for $tabObjectName and $tboxObjectName is incorrect, it should be:

    Code:
    function GenerateTab {
      param ( 
              [System.Windows.Forms.TabPage] $tabObjectName,
              [System.Windows.Forms.Textbox] $tboxObjectName,
              [string] $tabName
            )
    Given this change, my simple example yielded the correct tabs. I would have to see more of your code to see what went wrong, specifically where the tabs are declared, and I would have to see at least two cases where GenerateTab was called for two different tabs(your example has only one).

    Here is my extremely simple example:

    Code:
    [void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    [void] [System.Reflection.Assembly]::LoadWithPartialName('System.Drawing')
     
     function GenerateTab {
     param ( 
              [System.Windows.Forms.TabPage] $tabObjectName,
              [System.Windows.Forms.Textbox] $tboxObjectName,
              [string] $tabName
            )
    
      $tabObjectName.Name      = $tabName
      $tabObjectName.Text      = $tabName
    
      $tboxObjectName.Text = "Text for tab $tabName" 
    
      $tabObjectName.Controls.Add($tboxObjectName)
    }
    
    $f = New-Object System.Windows.Forms.Form
    $f.Text = $title
    $tab_contol1 = new-object System.Windows.Forms.TabControl
    
    $tabOne  = New-Object System.Windows.Forms.TabPage
    $tabTwo  = New-Object System.Windows.Forms.TabPage
    $textOne = new-object System.Windows.Forms.TextBox
    $textTwo = new-object System.Windows.Forms.TextBox
    
    GenerateTab ([ref]$tabOne) ([ref]$textOne) "One"
    GenerateTab ([ref]$tabTwo) ([ref]$textTwo) "Two"
    $tab_contol1.Controls.Add($tabOne)
    $tab_contol1.Controls.Add($tabTwo)
    $f.Controls.Add($tab_contol1)
    $f.ShowDialog()

  6. The Following User Says Thank You to cafed00d For This Useful Post:

    RetiredGeek (2015-09-03)

  7. #6
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Cafed00d,

    Once again you bail me out on this project!

    All it took was the correct Function Parameter definitions!

    I googled all over the place and never found that information or an example using that syntax. All I found were examples using the [ref].

    Working Code:
    Code:
    function GenerateTab {
    
     param ( 
              [System.Windows.Forms.TabPage] $tabObjectName,
              [System.Windows.Forms.Textbox] $tboxObjectName,
              [string] $tabName
            )
    
      $tabObjectName.Name      = "$tabName"
      $tabObjectName.Location  = $tabLocation
      $tabObjectName.Padding   = $System_Windows_Forms_Padding
      $tabObjectName.Size      = $tabSize  
      $tabObjectName.TabIndex  = 0
      $tabObjectName.Text      = $TabName
    
      $tboxObjectName.Location   = $tboxLocation 
      $tboxObjectName.Size       = $tboxSize
      $tboxObjectName.MultiLine  = $True
      $tboxObjectName.ForeColor  = $tboxForeColor
      $tboxObjectName.BackColor  = $tboxBackColor
      $tboxObjectName.ScrollBars = 'Both'
      $tboxObjectName.Font       = $tboxFont
      $tboxObjectName.ReadOnly   = $True
    
    #  $MainTabControl.Controls.Add($tabObjectName)
    #  $tabObjectName.Controls.add($tboxObjectName)
    
    }   #--------------- End GenerateTab --------------------------
    Calling Examples:
    Code:
    #---------------- Hardware Tab ------------------------------------
    
      GenerateTab ([ref]$tabHardware) ([ref]$tboxHardware) ("Hardware")
    
      $tboxHardware.Text = $HWInfo + $MemTitle + $MemoryInfo
      $MainTabControl.Controls.Add($tabHardware)
      $tabHardware.Controls.add($tboxHardware)
    
    #-------------- Windows Tab --------------------------------
    
        GenerateTab ([ref]$tabWindows) ([ref]$tboxWindows) ("Windows")
    
       $MainTabControl.Controls.add($tabwindows)
       $tabWindows.Controls.add($tboxWindows)
       $tboxWindows.Text = $WinInfo + $UATitle +  $uai
    Thanks Again!
    Last edited by RetiredGeek; 2015-09-04 at 10:10.
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  8. #7
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Cafed00d,

    I got to wondering if there was any speed advantage between versions (1 call vs 2 calls) as it seemed there should be. Since all the code is the same except for the form generation I placed this statement:
    Code:
    Write-Host  (get-date -format yyyy-mm-dd-HH:mm:ss)
    Before the call to GenerateForm and also before the ShowDialog() statements (didn't want to include any reaction time on my part.

    The 2 call version took 3 seconds while the 1 call version (thanks to you) took 2 seconds. May not seem like much but it is a 33% reduction in the time waiting for the dialog to appear!

    I'm just about done prettying things up and I'll post the entire program when completed.

    Thanks again for your help!
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  9. #8
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Hey Y'all,

    As promised (or threatened ) here's the finished (yeah it will never actually be finished) version.

    PowerShell: CMsPCInfo-FormVersion.zip

    Yes, I know there are a lot of programs which provide window configuration information. I did this as a PowerShell learning experience and just because I could. I also like having it my way!

    I'd be very interested in how this acts on different configurations. I've tested it on Win 10 & 8.1 and everything works. On Win 7 HP the Network Tab comes up blank...still investigating but I don't think V3 of PS supports the CMDLETS I'm using.

    Enjoy!
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  10. #9
    Administrator
    Join Date
    Mar 2001
    Location
    St Louis, Missouri, USA
    Posts
    23,583
    Thanks
    5
    Thanked 1,058 Times in 927 Posts
    Got three errors in the script. Running on Win10 Enterprise build 10532.

    PS_error_1.png

    PS_error_2.png

    PS_error_3.png

    Joe

  11. #10
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Joe,

    Thanks for testing!

    I noticed that all the errors are for Else commands that are on separate lines! Line continuation error?
    AFAICT you copied & pasted the code into a PS CMD windows? I do not get these errors when I run from the ISE or a Script file in the CMD window. So I tried doing that and I don't get errors on Win 8.1 Pro, Win 10 Home, nor on Win 10 Pro Insider Preview Build 10532.

    Something with Enterprise Ed.?

    BTW: I ran in regular mode as well As Administrator.

    Could you run the code from the ISE as that will return you to the ISE when done and also provide line numbers. Thanks!
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  12. #11
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Joe,

    My BAD! I did my testing with a version later than the one I posted (very minor change).

    Here's the version that doesn't cause the errors: CMsPCInfo-FormVersion.zip

    This was a case of a cascading error. An If statement to check for an empty object solved the problem.

    Thanks again for testing.
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  13. #12
    Administrator
    Join Date
    Mar 2001
    Location
    St Louis, Missouri, USA
    Posts
    23,583
    Thanks
    5
    Thanked 1,058 Times in 927 Posts
    RG,

    Still get the errors if I copy the script and paste into a PS window (both admin & non-admin). No errors when I run in ISE.

    Joe

  14. #13
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Quote Originally Posted by JoeP517 View Post
    RG,
    Still get the errors if I copy the script and paste into a PS window (both admin & non-admin). No errors when I run in ISE.
    Joe
    Very Interesting!

    You do get the dialog box with the system configuration information right?

    If you would, could you try running from a file in the PS CMD window?

    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  15. #14
    Administrator
    Join Date
    Mar 2001
    Location
    St Louis, Missouri, USA
    Posts
    23,583
    Thanks
    5
    Thanked 1,058 Times in 927 Posts
    Yep. The system config displays all the time.

    Ran in PS CMD window both admin and non-admin. Worked without errors both times.

    Joe

  16. #15
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Joe,

    Thanks again. Now I'm really puzzled why pasting it in to a PS CMD window causes errors ONLY in the Enterprise Versions as both my Home and Pro Versions work w/o errors. “Curiouser and curiouser!” Cried RG
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •