about_Try_Catch_Finally

適用於: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0, Windows PowerShell 5.0

主題

about_Try_Catch_Finally

簡短描述

描述如何使用 Try、Catch 和 Finally 區塊來處理終止錯誤。

詳細描述

您可以使用 Try、Catch 和 Finally 區塊,來回應或處理指令碼中的終止錯誤;也可以使用 Trap 陳述式來處理指令碼中的終止錯誤。如需詳細資訊,請參閱 about_Trap。

終止錯誤會導致陳述式停止執行。如果 Windows PowerShell® 基於任何原因而無法處理終止錯誤,Windows PowerShell 也會停止執行函式或使用目前管線的指令碼。在像是 C# 的其他語言中,終止錯誤稱為例外狀況。如需錯誤的詳細資訊,請參閱 about_Errors。

您可以使用 Try 區塊,定義要讓 Windows PowerShell 監視是否有錯誤的指令碼區段。當 Try 區塊中發生錯誤時,會先將錯誤儲存至 $Error 自動變數。然後 Windows PowerShell 會搜尋 Catch 區塊以處理錯誤。如果 Try 陳述式沒有相符的 Catch 區塊,Windows PowerShell 會繼續在父範圍中搜尋適當的 Catch 區塊或 Trap 陳述式。在 Catch 區塊完成之後,或者如果找不到任何適當的 Catch 區塊或 Trap 陳述式,則會執行 Finally 區塊。如果無法處理錯誤,則會將錯誤寫入錯誤資料流。

Catch 區塊可以包含用於追蹤失敗或復原預期指令碼流程的命令。Catch 區塊可以指定所要攔截的錯誤類型。Try 陳述式可以包含不同錯誤類型的多個 Catch 區塊。

Finally 區塊可用來釋放指令碼不再需要的任何資源。

Try、Catch 和 Finally 類似於 C# 程式設計語言中所使用的 Try、Catch 和 Finally 關鍵字。

語法

Try 陳述式包含一個 Try 區塊、零或多個 Catch 區塊,以及零或一個 Finally 區塊。Try 陳述式至少必須包含一個 Catch 區塊或一個 Finally 區塊。

Try 區塊語法如下所示:

          try {<statement list>}

Try 關鍵字後面接著以大括號括住的陳述式清單。如果在陳述式清單中的陳述式執行時發生終止錯誤,指令碼會將 Try 區塊中的錯誤物件傳遞給適當的 Catch 區塊。

Catch 區塊語法如下所示:

          catch [[<error type>][',' <error type>]*] {<statement list>}

錯誤類型會以方括號括住顯示。最外層的方括號表示此為選擇性元素。

Catch 關鍵字後面接著錯誤類型規格的選擇性清單和陳述式清單。如果在 Try 區塊中發生終止錯誤,Windows PowerShell 會搜尋是否有適當的 Catch 區塊。如果找到一個區塊,則會執行 Catch 區塊中的陳述式。

Catch 區塊可以指定一或多個錯誤類型。錯誤類型是 Microsoft .NET Framework 例外狀況或衍生自 .NET Framework 例外狀況的例外狀況。Catch 區塊會處理指定 .NET Framework 例外狀況類別或衍生自指定類別之任何類別的錯誤。

如果 Catch 區塊指定錯誤類型,該 Catch 區塊會處理該類型的錯誤。如果 Catch 區塊未指定錯誤類型,該 Catch 區塊會處理 Try 區塊中發生的任何錯誤。Try 陳述式可以包含指定不同錯誤類型的多個 Catch 區塊。

Finally 區塊語法如下所示:

          finally {<statement list>}

Finally 關鍵字後面接著陳述式清單,即使 Try 陳述式執行時未發生錯誤,或者 Catch 陳述式中攔截到錯誤,都會在每次執行指令碼時執行該清單。

請注意,按 CTRL+C 可停止管線。輸出時不會顯示傳送至管線的物件。因此,如果您包含要顯示的陳述式 (例如 "Finally block has run"),當您按下 CTRL+C 之後將不會顯示該陳述式,即使 Finally 區塊已執行亦然。

攔截錯誤

下列範例指令碼顯示 Try 區塊搭配 Catch 區塊:

          try { NonsenseString }
          catch { "An error occurred." }

Catch 關鍵字必須緊接在 Try 區塊或另一個 Catch 區塊之後。

Windows PowerShell 無法將 "NonsenseString" 辨識為 Cmdlet 或其他項目。執行這個指令碼會傳回下列結果:

          An error occurred.

當指令碼遇到 "NonsenseString" 時,會導致終止錯誤。Catch 區塊透過執行區塊中的陳述式清單來處理錯誤。

使用多個 CATCH 陳述式

Try 陳述式可以包含任意數目的 Catch 區塊。例如,下列指令碼包含 Try 區塊,該區塊會下載 MyFile.doc 並包含兩個 Catch 區塊:

          try
          {
             $wc = new-object System.Net.WebClient
             $wc.DownloadFile("https://www.contoso.com/MyDoc.doc")
          }
          catch [System.Net.WebException],[System.IO.IOException]
          {
              "Unable to download MyDoc.doc from https://www.contoso.com."
          }
          catch
          {
              "An error occurred that could not be resolved."
          }

第一個 Catch 區塊可處理 System.Net.WebException 和 System.IO.IOException 類型的錯誤。第二個 Catch 區塊未指定錯誤類型。第二個 Catch 區塊可處理發生的任何其他終止錯誤。

Windows PowerShell 符合繼承的錯誤類型。Catch 區塊會處理指定 .NET Framework 例外狀況類別或衍生自指定類別之任何類別的錯誤。下列範例包含攔截到「找不到命令」錯誤的 Catch 區塊:

          catch [System.Management.Automation.CommandNotFoundException] 
              {"Inherited Exception" }

指定的錯誤類型 CommandNotFoundException 繼承自 System.SystemException 類型。下列範例也會攔截「找不到命令」錯誤:

          catch [System.SystemException] {"Base Exception" }

這個 Catch 區塊會處理「找不到命令」錯誤和其他繼承自 SystemException 類型的錯誤。

如果您指定錯誤類別和其中一個衍生類別,請將該衍生類別的 Catch 區塊放到一般類別的 Catch 區塊之前。

使用 FINALLY 釋放資源

若要釋放指令碼所使用的資源,請將 Finally 區塊新增到 Try 和 Catch 區塊之後。不論 Try 區塊是否發生終止錯誤,Finally 區塊陳述式都會執行。Windows PowerShell 會執行 Finally 區塊,再終止指令碼或將目前的區塊移出範圍。

即使使用 CTRL+C 來停止指令碼,也會執行 Finally 區塊。如果 Exit 關鍵字停止 Catch 區塊中的指令碼,也會執行 Finally 區塊。

另請參閱

about_Break

about_Continue

about_Scopes

about_Throw

about_Trap