kg2137
July 28, 2020, 12:00pm
1
Trying to figure out how I can output the results of a function to show in a listview in my winforms GUI?
I have the following setup to create a listview and want to know what I need to add to get a function I will be creating to output to the listview window. I am a bit new to this so I am not really sure where to start.
Add-Type -assembly System.Windows.Forms
$main_form = New-Object System.Windows.Forms.Form
$main_form.ClientSize = '600,400'
$List = New-Object System.Windows.Forms.ListView
$List.Location = New-Object System.Drawing.Point(20,175)
$List.Width = 200
$List.Height = 200
$main_form.Controls.Add($List)
$main_form.ShowDialog()
I just helped somebody with something similar on Reddit yesterday. Perhaps this can help get you started.
function Show-DirectoryTree {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
[string]$RootFolder
)
# recursive helper function to add folder nodes to the treeview
function Add-Node {
param (
[System.Windows.Forms.TreeNode]$parentNode,
[System.IO.DirectoryInfo]$Folder
)
Write-Verbose "Adding node $($Folder.Name)"
$subnode = New-Object System.Windows.Forms.TreeNode
$subnode.Text = $Folder.Name
[void]$parentNode.Nodes.Add($subnode)
Get-ChildItem -Path $Folder.FullName -Directory | ForEach-Object {
Add-Node $subnode $_
}
Add-Files $subnode $folder
}
function Add-Files {
param (
[System.Windows.Forms.TreeNode]$parentNode,
[System.IO.DirectoryInfo]$Folder
)
Get-childitem -path $Folder.FullName -file | ForEach-Object {
$subnode = New-Object System.Windows.Forms.TreeNode
$subnode.Text = $_.name
[void]$parentNode.Nodes.Add($subnode)
}
}
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Files and Folders"
$Form.Size = New-Object System.Drawing.Size(390, 420)
$TreeView = New-Object System.Windows.Forms.TreeView
$TreeView.Location = New-Object System.Drawing.Point(48, 12)
$TreeView.Size = New-Object System.Drawing.Size(280, 322)
$Form.Controls.Add($TreeView)
$rootnode = New-Object System.Windows.Forms.TreeNode
# get the name of the rootfolder to use for the root node
$rootnode.Text = [System.IO.Path]::GetFileName($RootFolder.TrimEnd('\')) #'# or use: (Get-Item -Path $RootFolder).Name
$rootnode.Name = "Root"
[void]$TreeView.Nodes.Add($rootnode)
# expand just the root node
$rootNode.Expand()
# get all subdirectories inside the root folder and
# call the recursive function on each of them
Get-ChildItem -Path $RootFolder -Directory | ForEach-Object {
Add-Node $rootnode $_
}
Add-Files $rootnode $RootFolder
$accept = New-Object System.Windows.Forms.Button
$accept.Text = "OK"
$accept.Location = New-Object System.Drawing.Point(230, 345)
$cancel = New-Object System.Windows.Forms.Button
$cancel.Text = "Cancel"
$cancel.Location = New-Object System.Drawing.Point(70, 345)
$accept.Add_Click({$script:selected = "$rootfolder$($treeview.SelectedNode.FullPath)";$form.Close()})
$cancel.Add_Click({$form.Close()})
$form.controls.AddRange(@($accept,$cancel))
$Form.Add_Shown({$Form.Activate()})
[void]$Form.ShowDialog()
$script:selected
# remove the form when done with it
$Form.Dispose()
}
# call the function to show the directory tree
# take off the -Verbose switch if you do not want console output
Show-DirectoryTree -RootFolder 'C:\Temp'
kg2137
July 29, 2020, 4:04am
3
Not sure I really follow what is happening in your code sadly. Not sure what is actually putting the results of the function into the forms element as text.
I actually thinking for my purpose a multi-line textbox is better to use that listview now. My function is just checking multiple servers and reporting back if a service is running or stopped so I won’t need to interact with the data in the box.
I read it wrong anyways, my example is for a treeview. Here is a snippet from another script that demonstrates listview
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '519,594'
$Form.text = "Some fancy title"
$Form.icon #= "c:\path\to\fancyicon.ico"
$namecolumn = New-Object System.Windows.Forms.ColumnHeader
$namecolumn.Name = "name"
$namecolumn.DisplayIndex = 1
$namecolumn.Text = "Name"
$namecolumn.Width = 175
$usercolumn = New-Object System.Windows.Forms.ColumnHeader
$usercolumn.Name = "samaccountname"
$usercolumn.DisplayIndex = 2
$usercolumn.Text = "Login Name"
$usercolumn.Width = 155
$statuscolumn = New-Object System.Windows.Forms.ColumnHeader
$statuscolumn.Name = "status"
$statuscolumn.DisplayIndex = 3
$statuscolumn.Text = "Status"
$statuscolumn.Width = 75
$listView = New-Object System.Windows.Forms.ListView
$listView.View = 'Details'
$listView.Size = New-Object System.Drawing.Size(426,376)
$listView.Location = New-Object System.Drawing.Point(20,62)
$listView.Font = "$($Listview.Font.FontFamily),12"
$null = $listView.Columns.AddRange(@($namecolumn,$usercolumn,$statuscolumn))
$form.controls.Add($listView)
$null = Get-Aduser -filter * |
select name,samaccountname,enabled |
Sort-Object -Property samaccountname |
Out-GridView -Title "Ken, please pick some users" -PassThru |
foreach {
$itemname = New-Object System.Windows.Forms.ListViewItem($_.name)
$itemname.SubItems.Add($_.samaccountname)
if ($_.enabled -eq $true) {
$itemname.SubItems.Add("Enabled")
}else{
$itemname.SubItems.Add("Disabled")
}
$listView.Items.Add($itemname)
}
$form.ShowDialog()
kg2137
July 29, 2020, 4:51am
5
Still a bit confused…
I don’t see a function in the example so not sure entirely how its showing what a function would output to the console and putting it into the form element. I decided to use a textbox instead of a listview.
My goal is take my function that is checking servers to see if specific services are running and outputting that data to the textbox when a button is clicked.