我想要實作的目標:
創建檔案串列,顯示它們的名稱和版本并按字母順序排序。
我的嘗試:
class File_Information
{
[ValidateNotNullOrEmpty()][string]$Name
[ValidateNotNullOrEmpty()][string]$FileVersion
}
$FileList = New-Object System.Collections.Generic.List[File_Information]
foreach ($file in Get-Item("*.dll")){
$C = [File_Information]@{
Name = $file.Name
FileVersion = $file.VersionInfo.FileVersion
}
$FileList = $FileList.Add($C)
}
foreach ($file in Get-Item("*.exe")){
$C = [File_Information]@{
Name = $file.Name
FileVersion = $file.VersionInfo.FileVersion
}
$FileList = $FileList.Add($C)
}
Write-Output $FileList | Sort-Object -Property "Name" | Format-Table
我的 Powershell 版本:
Prompt> Get-Host | Select-Object Version
Version
-------
5.1.19041.1320
我的問題和/或問題(第一個是主要問題,第二個和第三個是可選的):
我不知道如何初始化自定義物件串列(我一直在尋找網站,但這個問題只提供了使用現有值初始化的可能性,而我想初始化為一個空串列)。
我收到的錯誤是:You cannot call a method on a null-valued expression. At line:... char:... $FileList = $FileList.Add($C) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CategoryInfo : InvalidOperation: (:) [], RuntimeException FullyQualifiedErrorId : InvokeMethodOnNull目前我兩次要求同樣的事情:我試過了
Get-Item(*.dll,*.exe),Get-Item(*.dll;*.exe)但Get-Item(*.dll|*.exe)沒有一個奏效。
甚至可以搜索不同的模式嗎?直到現在我都在努力
Write-Output $FileList作業。其他兩個命令 (Sort-Object -Property "Name",Format-Table) 是否正確?
uj5u.com熱心網友回復:
為什么要為此使用一個類和一個 List 物件?您可以只使用Select-Object您收集的感興趣的檔案,Get-ChildItem并在那里輸出所需的屬性:
# capture the resulting objects in a variable $result
$result = Get-ChildItem -Path 'X:\path\to\the\files' -File -Include '*.dll','*.exe' -Recurse |
Select-Object Name, @{Name = 'FileVersion'; Expression = {$_.VersionInfo.FileVersion}}
# output on screen
$result | Sort-Object Name | Format-Table -AutoSize
要在 上使用兩種不同的名稱模式Get-ChildItem,您還需要添加 switch-Recurse或附加\*到路徑。
如果您不想遞回,則需要添加Where-Object如下子句:
$result = Get-ChildItem -Path 'X:\path with spaces' | Where-Object {$_.Extension -match '\.(dll|exe)'} |
Select-Object Name, @{Name = 'FileVersion'; Expression = {$_.VersionInfo.FileVersion}}
uj5u.com熱心網友回復:
您的代碼實際上運行良好,但有兩個小例外。
問題 #1:過度限制的屬性屬性會導致錯誤
首先,在您的自定義類中,您應該非常確定要附加此屬性[ValidateNotNullOrEmpty()],因為當您嘗試新建一個類的實體時,如果任何具有此屬性的屬性是空值。
例如,在我的 PC 上,我有一兩個具有空file.VersionInfo.FileVersion屬性的 dll。發生這種情況時,PowerShell 將無法創建物件,然后嘗試將物件添加到串列中也會失敗,因為沒有物件。很混亂。
修復:洗掉 ValidateNotNullOrEmpty 的屬性,除非您 100% 肯定此資訊存在。
接下來,這里真正的問題是,在您的每個 for-each 回圈中,您不小心破壞了您FileList在代碼中正確設定的物件。
問題#2:小的語法問題導致您的串列被清空,導致第一個操作之后的每個操作都出錯。
問題發生在下面的這一行中,我將對此進行解釋。
$FileList = $FileList.Add($C)
List.Add() 方法的回傳型別是 void 或整數(當您提供通用物件時,它只是一個 int,如果您提供為串列指定的型別,在您的情況下是您的自定義類File_Information,它提供了一個空白。)
void 與 null 相同。我們可以確認 .Add 的輸出$null與以下代碼相同。
PS> $FileList.Add($c) -eq $null
True
.Add()您只需輸入不帶引數的方法名稱,就可以詳細查看各種呼叫方式的輸出,如下所示。
PS> $FileList.Add
OverloadDefinitions
-------------------
void Add(File_Information item) #< the one you're using!
void ICollection[File_Information].Add(File_Information item)
int IList.Add(System.Object value)
因此,實際上您的 for each 回圈正在將一個專案添加到串列中,然后將變數 $FileList 重新保存到 .Add 方法的輸出中,即 void 或 null 換句話說。你正在扼殺你自己的名單!
我們不需要隨時重新保存$FileList,因為串列的目的是在代碼中填充,我們唯一要做的就是呼叫該.Add()方法。
修復:通過更改代碼中的這些行來停止在回圈中殺死您的串列物件。
#before
$FileList = $FileList.Add($C)
#after
$FileList.Add($C)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/434558.html
標籤:电源外壳 收藏品 初始化 自定义对象 powershell-5.1
上一篇:如何在運算式中使用cmdlet
