I'm having trouble with an error when I try to run my PowerShell script from the command line:
Unable to find type [System.Windows.Forms.ListViewItem]
I have tried different ways to import the required classes:
using assembly System.Windows.Forms
using namespace System.Windows.Forms
using namespace System.Drawing
Add-Type System.Windows.Forms
In PowerShell ISE, I can run my script without any errors. But when I try to execute my script from CMD it doesn't work. It's exactly the same code and the same script files. This is the command I use to execute the script in CMD followed by the error messages:
C:\Users\Admin>powershell -File "C:\Folder\Main.ps1"
At C:\Folder\Main.ps1:35 char:30
+ ... return (([int](([System.Windows.Forms.ListViewItem]$a).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
At C:\Folder\Main.ps1:35 char:114
+ ... umnIndex].Text)) - ([int](([System.Windows.Forms.ListViewItem]$b).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
At C:\Folder\Main.ps1:37 char:41
+ ... return ([String]::Compare(([System.Windows.Forms.ListViewItem]$a).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
At C:\Folder\Main.ps1:37 char:115
+ ... [$this.columnIndex].Text, ([System.Windows.Forms.ListViewItem]$b).Sub ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.ListViewItem].
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TypeNotFound
The error messages refer to the code below. This is my only class in that script:
class ListViewItemComparer : System.Collections.IComparer {
[int]$sortOrder
[String]$columnType
[int]$columnIndex
ListViewItemComparer() {
$this.sortOrder = 1
$this.columnType = "String"
$this.columnIndex = 0
}
ListViewItemComparer([int]$sortOrder, [String]$columnType, [int]$columnIndex) {
$this.sortOrder = $sortOrder
$this.columnType = $columnType
$this.columnIndex = $columnIndex
}
[void] ChangeSorting([int]$columnIndex, [String]$columnType) {
if($this.columnIndex -eq $columnIndex) {
$this.sortOrder *= -1
} else {
$this.columnIndex = $columnIndex
$this.sortOrder = 1
}
$this.columnType = $columnType
}
[int] Compare([Object]$a, [Object]$b) {
if($this.columnType -eq "Number") {
return (([int](([System.Windows.Forms.ListViewItem]$a).SubItems[$this.columnIndex].Text)) - ([int](([System.Windows.Forms.ListViewItem]$b).SubItems[$this.columnIndex].Text))) * $this.sortOrder
} else {
return ([String]::Compare(([System.Windows.Forms.ListViewItem]$a).SubItems[$this.columnIndex].Text, ([System.Windows.Forms.ListViewItem]$b).SubItems[$this.columnIndex].Text)) * $this.sortOrder
}
}
}
I'm using the type System.Windows.Forms.ListViewItem at other places too in my code, but there is no problem outside of a class. I don't even have to write the whole class path, just ``ListViewItem` works as well.
Can somebody tell me why the type System.Windows.Forms.ListViewItem is not recognized?
Why is it recognized outside the ListViewItemComparer class in the same script file?
Why does this error occur when I run the script from CMD and not in PowerShell ISE?
Class definitions will be parsed prior to any execution of your script. You can wrap your class with an Invoke-Expression command like so:
add-type -AssemblyName System.Windows.Forms
iex @'
class ListViewItemComparer : Collections.IComparer
{
....
}
'@
This will defer compilation until the required assembly is loaded.
Note that errors in your class will now be reported relative to the beginning of the iex string. If you want the class to report proper file/line info then it's better to put it into a separate file like so:
add-type -AssemblyName System.Windows.Forms
. .\ListViewItemComparer.ps1
It depends on how you want to go about logging and error reporting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With