การเพิ่มการรายงานข้อผิดพลาดที่ไม่สิ้นสุดไปยัง 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