ค้นหาเว็บไซต์

การเพิ่มการรายงานข้อผิดพลาดที่ไม่สิ้นสุดไปยัง Cmdlet ของคุณ


Cmdlet ของสามารถรายงานข้อผิดพลาดที่ไม่สิ้นสุดได้โดยการเรียกเมธอด System.Management.Automation.Cmdlet.WriteError และยังคงดำเนินการต่อไปบนวัตถุอินพุตปัจจุบันหรือบนวัตถุไปป์ไลน์ขาเข้าเพิ่มเติม ส่วนนี้จะอธิบายวิธีการสร้าง cmdlet ที่รายงานข้อผิดพลาดที่ไม่ยุติจากวิธีการประมวลผลอินพุต

สำหรับข้อผิดพลาดที่ไม่ยุติ (เช่นเดียวกับข้อผิดพลาดในการยุติ) cmdlet จะต้องผ่านวัตถุ System.Management.Automation.ErrorRecord ที่ระบุข้อผิดพลาด บันทึกข้อผิดพลาดแต่ละรายการจะถูกระบุด้วยสตริงเฉพาะที่เรียกว่า "ตัวระบุข้อผิดพลาด" นอกจากตัวระบุแล้ว หมวดหมู่ของข้อผิดพลาดแต่ละรายการยังระบุด้วยค่าคงที่ที่กำหนดโดยการแจงนับ System.Management.Automation.ErrorCategory ผู้ใช้สามารถดูข้อผิดพลาดตามหมวดหมู่ได้โดยการตั้งค่าตัวแปร $ErrorView เป็น "CategoryView"

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับบันทึกข้อผิดพลาด โปรดดูที่บันทึกข้อผิดพลาดของ Windows PowerShell

การกำหนด Cmdlet

ขั้นตอนแรกในการสร้าง cmdlet คือการตั้งชื่อ cmdlet และประกาศคลาส .NET ที่ใช้ cmdlet เสมอ cmdlet นี้ดึงข้อมูลกระบวนการ ดังนั้นชื่อกริยาที่เลือกที่นี่คือ "รับ" (cmdlet เกือบทุกประเภทที่สามารถดึงข้อมูลสามารถประมวลผลอินพุตบรรทัดคำสั่งได้) สำหรับข้อมูลเพิ่มเติมเกี่ยวกับกริยา cmdlet ที่ได้รับอนุมัติ โปรดดูชื่อกริยา Cmdlet

ต่อไปนี้เป็นคำจำกัดความสำหรับ cmdlet นี้ Get-Proc รายละเอียดของคำจำกัดความนี้มีให้ในการสร้าง Cmdlet แรกของคุณ

[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
    Inherits Cmdlet

การกำหนดพารามิเตอร์

หากจำเป็น cmdlet ของคุณจะต้องกำหนดพารามิเตอร์สำหรับการประมวลผลอินพุต Get-Proc cmdlet นี้กำหนดพารามิเตอร์ ชื่อ ตามที่อธิบายไว้ในการเพิ่มพารามิเตอร์ที่ประมวลผลอินพุตบรรทัดคำสั่ง

นี่คือการประกาศพารามิเตอร์สำหรับพารามิเตอร์ ชื่อ ของ Get-Proc cmdlet นี้

[Parameter(
           Position = 0,
           ValueFromPipeline = true,
           ValueFromPipelineByPropertyName = true
)]
[ValidateNotNullOrEmpty]
public string[] Name
{
  get { return processNames; }
  set { processNames = value; }
}
private string[] processNames;
<Parameter(Position:=0, ValueFromPipeline:=True, _
ValueFromPipelineByPropertyName:=True), ValidateNotNullOrEmpty()> _
Public Property Name() As String()
    Get
        Return processNames
    End Get

    Set(ByVal value As String())
        processNames = value
    End Set

End Property

การเอาชนะวิธีการประมวลผลอินพุต

cmdlet ทั้งหมดต้องแทนที่วิธีประมวลผลอินพุตอย่างน้อยหนึ่งวิธีที่ได้รับจากคลาส System.Management.Automation.Cmdlet วิธีการเหล่านี้จะกล่าวถึงในการสร้าง Cmdlet แรกของคุณ

บันทึก

cmdlet ของคุณควรจัดการแต่ละบันทึกอย่างอิสระที่สุด

Get-Proc cmdlet นี้จะแทนที่เมธอด System.Management.Automation.Cmdlet.ProcessRecord เพื่อจัดการพารามิเตอร์ ชื่อ สำหรับอินพุตที่ผู้ใช้หรือสคริปต์ให้มา วิธีนี้จะรับกระบวนการสำหรับชื่อกระบวนการที่ร้องขอแต่ละรายการหรือกระบวนการทั้งหมดหากไม่มีการระบุชื่อ รายละเอียดของการแทนที่นี้มีให้ในการสร้าง Cmdlet แรกของคุณ

สิ่งที่ต้องจำเมื่อรายงานข้อผิดพลาด

วัตถุ System.Management.Automation.ErrorRecord ที่ cmdlet ส่งผ่านเมื่อเขียนข้อผิดพลาดจำเป็นต้องมีข้อยกเว้นที่แกนหลัก ปฏิบัติตามหลักเกณฑ์ .NET เมื่อพิจารณาข้อยกเว้นที่จะใช้ โดยทั่วไป ถ้าข้อผิดพลาดมีความหมายเหมือนกับข้อยกเว้นที่มีอยู่ cmdlet ควรใช้หรือสืบทอดมาจากข้อยกเว้นนั้น มิฉะนั้น ควรได้รับข้อยกเว้นใหม่หรือลำดับชั้นของข้อยกเว้นโดยตรงจากคลาส System.Exception

เมื่อสร้างตัวระบุข้อผิดพลาด (เข้าถึงผ่านคุณสมบัติ FullyQualifiedErrorId ของคลาส ErrorRecord) โปรดคำนึงถึงสิ่งต่อไปนี้

  • ใช้สตริงที่มีการกำหนดเป้าหมายเพื่อวัตถุประสงค์ในการวินิจฉัย ดังนั้นเมื่อตรวจสอบตัวระบุแบบเต็ม คุณจะสามารถระบุได้ว่าข้อผิดพลาดคืออะไรและข้อผิดพลาดมาจากไหน

  • ตัวระบุข้อผิดพลาดที่มีคุณสมบัติครบถ้วนที่มีรูปแบบสมบูรณ์อาจเป็นดังนี้

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

โปรดสังเกตว่าในตัวอย่างก่อนหน้านี้ ตัวระบุข้อผิดพลาด (โทเค็นแรก) จะระบุว่าข้อผิดพลาดคืออะไร และส่วนที่เหลือจะระบุว่าข้อผิดพลาดมาจากไหน

  • สำหรับสถานการณ์ที่ซับซ้อนมากขึ้น ตัวระบุข้อผิดพลาดอาจเป็นโทเค็นที่คั่นด้วยจุดซึ่งสามารถแยกวิเคราะห์ได้ในการตรวจสอบ ซึ่งช่วยให้คุณแยกส่วนต่างๆ ของตัวระบุข้อผิดพลาด รวมถึงตัวระบุข้อผิดพลาดและหมวดหมู่ข้อผิดพลาดได้เช่นกัน

cmdlet ควรกำหนดตัวระบุข้อผิดพลาดเฉพาะให้กับเส้นทางโค้ดที่แตกต่างกัน โปรดคำนึงถึงข้อมูลต่อไปนี้เพื่อกำหนดตัวระบุข้อผิดพลาด:

  • ตัวระบุข้อผิดพลาดควรคงที่ตลอดวงจรชีวิตของ cmdlet อย่าเปลี่ยนความหมายของตัวระบุข้อผิดพลาดระหว่างเวอร์ชัน cmdlet
  • ใช้ข้อความสำหรับตัวระบุข้อผิดพลาดที่สอดคล้องกับข้อผิดพลาดที่กำลังรายงานอย่างเคร่งครัด อย่าใช้ช่องว่างหรือเครื่องหมายวรรคตอน
  • ให้ cmdlet ของคุณสร้างเฉพาะตัวระบุข้อผิดพลาดที่สามารถทำซ้ำได้ ตัวอย่างเช่น ไม่ควรสร้างตัวระบุที่มีตัวระบุกระบวนการ ตัวระบุข้อผิดพลาดมีประโยชน์สำหรับผู้ใช้เฉพาะเมื่อตรงกับตัวระบุที่ผู้ใช้รายอื่นพบปัญหาเดียวกัน

PowerShell ไม่พบข้อยกเว้นที่ไม่สามารถจัดการได้ในเงื่อนไขต่อไปนี้:

  • หาก cmdlet สร้างเธรดใหม่และโค้ดที่ทำงานอยู่ในเธรดนั้นทำให้เกิดข้อยกเว้นที่ไม่สามารถจัดการได้ PowerShell จะไม่ตรวจจับข้อผิดพลาดและจะยุติกระบวนการ
  • หากวัตถุมีรหัสอยู่ในตัวทำลายหรือวิธีการกำจัดที่ทำให้เกิดข้อยกเว้นที่ไม่สามารถจัดการได้ PowerShell จะไม่ตรวจจับข้อผิดพลาดและจะยุติกระบวนการ

การรายงานข้อผิดพลาดที่ไม่สิ้นสุด

วิธีการประมวลผลอินพุตวิธีใดวิธีหนึ่งสามารถรายงานข้อผิดพลาดที่ไม่สิ้นสุดไปยังสตรีมเอาต์พุตได้โดยใช้วิธี System.Management.Automation.Cmdlet.WriteError

นี่คือตัวอย่างโค้ดจาก Get-Proc cmdlet ที่แสดงให้เห็นการเรียกไปยัง System.Management.Automation.Cmdlet.WriteError จากภายในการแทนที่ของเมธอด System.Management.Automation.Cmdlet.ProcessRecord ในกรณีนี้ การเรียกจะเกิดขึ้นถ้า cmdlet ไม่พบกระบวนการสำหรับตัวระบุกระบวนการที่ระบุ

protected override void ProcessRecord()
{
  // If no name parameter passed to cmdlet, get all processes.
  if (processNames == null)
  {
    WriteObject(Process.GetProcesses(), true);
  }
    else
    {
      // If a name parameter is passed to cmdlet, get and write
      // the associated processes.
      // Write a non-terminating error for failure to retrieve
      // a process.
      foreach (string name in processNames)
      {
        Process[] processes;

        try
        {
          processes = Process.GetProcessesByName(name);
        }
        catch (InvalidOperationException ex)
        {
          WriteError(new ErrorRecord(
                     ex,
                     "NameNotFound",
                     ErrorCategory.InvalidOperation,
                     name));
          continue;
        }

        WriteObject(processes, true);
      } // foreach (...
    } // else
  }

สิ่งที่ต้องจำเกี่ยวกับการเขียนข้อผิดพลาดที่ไม่สิ้นสุด

สำหรับข้อผิดพลาดที่ไม่ยุติ cmdlet ต้องสร้างตัวระบุข้อผิดพลาดเฉพาะสำหรับแต่ละออบเจ็กต์อินพุตเฉพาะ

cmdlet มักจำเป็นต้องแก้ไขการกระทำของ PowerShell ที่เกิดจากข้อผิดพลาดที่ไม่สิ้นสุด ซึ่งสามารถทำได้โดยการกำหนดพารามิเตอร์ ErrorAction และ ErrorVariable หากกำหนดพารามิเตอร์ ErrorAction cmdlet จะแสดงตัวเลือกผู้ใช้ System.Management.Automation.ActionPreference คุณยังสามารถมีอิทธิพลต่อการดำเนินการโดยตรงด้วยการตั้งค่าตัวแปร $ErrorActionPreference

cmdlet สามารถบันทึกข้อผิดพลาดที่ไม่ยุติลงในตัวแปรโดยใช้พารามิเตอร์ ErrorVariable ซึ่งไม่ได้รับผลกระทบจากการตั้งค่า ErrorAction ความล้มเหลวสามารถผนวกเข้ากับตัวแปรข้อผิดพลาดที่มีอยู่ได้โดยการเพิ่มเครื่องหมายบวก (+) ที่ด้านหน้าของชื่อตัวแปร

ตัวอย่างโค้ด

สำหรับโค้ดตัวอย่าง C# ที่สมบูรณ์ โปรดดูตัวอย่าง GetProcessSample04

กำหนดประเภทวัตถุและการจัดรูปแบบ

PowerShell ส่งข้อมูลระหว่าง cmdlets โดยใช้วัตถุ .NET ด้วยเหตุนี้ cmdlet อาจจำเป็นต้องกำหนดประเภทของตัวเอง หรือ cmdlet อาจจำเป็นต้องขยายประเภทที่มีอยู่ซึ่งมาจาก cmdlet อื่น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดประเภทใหม่หรือการขยายประเภทที่มีอยู่ โปรดดูการขยายประเภทออบเจ็กต์และการจัดรูปแบบ

การสร้าง Cmdlet

หลังจากใช้ cmdlet คุณต้องลงทะเบียนกับ Windows PowerShell ผ่านทางสแนปอิน Windows PowerShell สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการลงทะเบียน cmdlets ดูวิธีการลงทะเบียน Cmdlets ผู้ให้บริการ และแอปพลิเคชันโฮสต์

การทดสอบ Cmdlet

เมื่อ cmdlet ของคุณได้รับการลงทะเบียนกับ PowerShell แล้ว คุณสามารถทดสอบได้โดยการรันบนบรรทัดคำสั่ง มาทดสอบตัวอย่าง Get-Proc cmdlet เพื่อดูว่ารายงานข้อผิดพลาดหรือไม่:

  • เริ่ม PowerShell และใช้ Get-Proc cmdlet เพื่อดึงกระบวนการที่ชื่อ "TEST"

    get-proc -name test
    

    ผลลัพธ์ต่อไปนี้จะปรากฏขึ้น

    get-proc : Operation is not valid due to the current state of the object.
    At line:1 char:9
    + get-proc  <<<< -name test
    

ดูเพิ่มเติม

  • การเพิ่มพารามิเตอร์ที่ประมวลผลอินพุตไปป์ไลน์

  • การเพิ่มพารามิเตอร์ที่ประมวลผลอินพุตบรรทัดคำสั่ง

  • การสร้าง Cmdlet แรกของคุณ

  • การขยายประเภทวัตถุและการจัดรูปแบบ

  • วิธีลงทะเบียน Cmdlets ผู้ให้บริการ และแอปพลิเคชันโฮสต์

  • การอ้างอิง Windows PowerShell

  • ตัวอย่าง Cmdlet

บทความที่เกี่ยวข้อง