إنشاء واجهات المستخدم الرسومية باستخدام WPF PowerShell: الوظائف والمدخلات والنتائج

PowerShell هو أداة سطر الأوامر ولكن هل تعلم أنه يمكن استخدامه أيضًا كقاعدة للواجهات الرسومية؟ في بعض الأحيان ، قد لا تكون واجهة سطر الأوامر هي النوع الأفضل لحالة معينة. إن بناء واجهة PowerShell GUI لمكتب خدمة العملاء الخاص بك هو مثال رائع. هذه هي إحدى تلك الأوقات التي يكون فيها من المناسب أكثر بناء أدوات رسومية بدلاً من ذلك.

Not a reader? Watch this related video.

فرض التحقق من هوية المستخدم عند إعادة تعيين كلمات المرور في مكتب المساعدة. قلل من ثغرات الهندسة الاجتماعية الخاصة بك مع Specops Secure Service Desk. اتصل بنا للحصول على عرض توضيحي!

يمكن لـ PowerShell استخدام وعرض وظائف وميزات .NET. نتيجة لذلك ، فمن الممكن كتابة واجهات المستخدم الرسومية الأمامية للنصوص التي تقوم بإنشائها. قد يبدو بناء واجهات PowerShell GUI معقدًا ، خاصة إذا كنت مبتدئًا.

ولكن إذا كان لديك خبرة أساسية في كتابة النصوص باستخدام PowerShell ، فلا يوجد سبب لك عدم تعلم وتكييف ممارسة إنشاء واجهة المستخدم الرسومية للنصوص الخاصة بك.

في هذه المقالة ، ستتعلم كيفية إنشاء واجهة PowerShell باستخدام Windows Presentation Framework (WPF).

المتطلبات الأساسية

قبل أن تبدأ ، يرجى التأكد من تلبية المتطلبات التالية:

  1. Visual Studio 2017 أو الإصدارات الأحدث – ستستخدم هذا لإنشاء واجهة المستخدم الرسومية باستخدام WPF. يمكنك تنزيل الإصدار المجاني / المجتمع.
  2. A script editor – I use Visual Studio Code, but you can also use another text editor of your choice. Some other options are Notepad++ and the built-in PowerShell ISE
  3. A Windows 10 computer with Windows PowerShell 5.1.

بناء النص

في هذه المقالة، ستقوم بإنشاء سكريبت بسيط يسمى Main.ps1. في السكريبت، ستكتب الكود الذي سيستخرج معلومات القرص من النظام المحلي أو النظام البعيد عن طريق استعلام فئة WMI Win32_LogicalDisk.

ستحتاج إلى سكريبت لتضمين واجهة رسومية لأول مرة. اخترت استخدام سكريبت يتيح لك تقديم اسم الكمبيوتر واستعلام معلومات القرص. ومع ذلك، هذا ليس ضروريًا بأي حال من الأحوال لبناء واجهة رسومية. استخدم التقنيات التي تعلمتها في هذه المقالة لتكييف الواجهات الرسومية الخاصة بك مع سكريبتاتك الخاصة.

كمثال للسكريبت، سأقوم بإنشاء دالة تقوم بتنفيذ الإجراءات التالية:

  1. قبول إدخال اسم الكمبيوتر للاستعلام
  2. استعلام الكمبيوتر وتخزين معلومات الأقراص الثابتة في متغير
  3. إرجاع النتائج

كتابة الدالة

أدناه هو الدالة التي ستستخدمها لهذا المشروع، وهي تسمى بشكل مناسب Get-FixedDisk. الهدف من هذا المشروع هو الحصول على معلومات عن الأقراص الثابتة أو الأقراص الثابتة في الجهاز المستهدف.

على الرغم من أن هذا الجزء من الكود يمكن استخدامه كما هو، إلا أن إنشاء واجهة رسومية سيكون مفيدًا إذا كنت ترغب فقط في تنفيذ استعلام سريع دون الحاجة إلى استدعاء الدالة وكتابة الأوامر يدويًا في كل مرة.

Function Get-FixedDisk {
    [CmdletBinding()]
    # هذا الكتلة param() يشير إلى بداية تعريف المعلمات
    param (
        <# 
            تقبل هذه المعلمة اسم الكمبيوتر المستهدف.
            كما يتم تعيينها كإجبارية لضمان عدم تنفيذ الوظيفة دون تحديد القيمة.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        أمر استعلام WMI الذي يحصل على قائمة جميع الأقراص المنطقية ويحفظ النتائج في متغير يسمى $DiskInfo
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
   $DiskInfo
}

يمكن رؤية أنني قمت بإضافة كتلة param() في الكود. يتم ذلك لإرشاد الوظيفة لقبول المدخلات بناءً على نوع البيانات المحدد.

في المثال، قمت بإضافة معلمة Computer التي تقبل قيمة سلسلة نصية. أيضًا، عن طريق إضافة سمة المعلمة Mandatory، يتم ضمان عدم تشغيل الوظيفة إذا لم يتم تحديد معلمة Computer أثناء التشغيل.

بعد ذلك، يوضح السطر 18 الأمر الفعلي لاستعلام WMI الذي يحصل على قائمة جميع الأقراص المنطقية ويحفظ النتائج في متغير يسمى $DiskInfo. قمت أيضًا بإضافة عامل تصفية للحصول فقط على الأقراص التي تحتوي على DriveType=3. يضمن هذا العامل تصفية عرض معلومات فقط عن الأقراص الثابتة المحلية.

استيراد الكود (Dot Sourcing)

في هذه النقطة، لديك الآن نص برمجي يعمل وأنت مستعد لاختباره. ولكن قبل أن تتمكن من اختبار النص البرمجي، تحتاج إلى استيراد الشفرة إلى جلسة PowerShell. طريقة واحدة لتحميل الشفرة في جلسة PowerShell هي عن طريق استخدام نقطة المصدر.

لكي تقوم بنقطة المصدر للنص البرمجي، اكتب نقطة (.) ثم مسافة قبل مسار النص البرمجي. إذا كان النص البرمجي في المجلد C:\PoshGUI-sample، فيمكنك نقطة المصدر على النحو التالي.

PS C:\PoshGUI-sample> . .\Main.ps1

يمكنك أيضًا تحديد المسار الكامل إذا كنت لست في دليل العمل الحالي. في الشفرة المثالية أدناه، يمكنك رؤية المسار الكامل للنص البرمجي.

PS C:>. C:\PoshGUI-sample\Main.ps1

الآن بعد أن قمنا بتحميل الشفرة في الذاكرة، يمكننا المتابعة في اختبار الدالة التي قمنا بإنشائها. في المثال أدناه، يتم استخدام الدالة Get-FixedDisk للاستعلام عن الكمبيوتر poshLabExc.

PS51> Get-FixedDisk -Computer poshLabExc

DeviceID     : C:
DriveType    : 3
ProviderName :
FreeSpace    : 53037772800
Size         : 135838822400
VolumeName   : Windows

DeviceID     : D:
DriveType    : 3
ProviderName :
FreeSpace    : 14872641536
Size         : 17178750976
VolumeName   : Temporary Storage

DeviceID     : E:
DriveType    : 3
ProviderName :
FreeSpace    : 488202240
Size         : 524283904
VolumeName   : System Reserved

بناء واجهة المستخدم الرسومية لـ PowerShell

في هذه النقطة، لقد قمت بإنشاء ملف النص البرمجي بالاسم Main.ps1، وداخل النص البرمجي قمت بإنشاء الدالة Get-FixedDisk. وكنت قادرًا أيضًا على اختبار وتأكيد عمل الدالة.

الآن بعد أن تعلمت أن النص البرمجي يعمل، يمكنك البدء في بناء واجهة المستخدم الرسومية.

تصميم نموذج PowerShell لواجهة المستخدم

قم أولاً بتخطيط كيف ترغب في أن تبدو واجهة المستخدم الرسومية والعناصر التي ترغب في استخدامها. لهذا المثال البسيط، ستحتوي واجهة المستخدم الخاصة بنا على:

  • a text box where the computer name can be entered
  • a button to execute the function
  • a text box where we can display the results

بعد ذلك، يمكنك البدء في بنائها!

لبدء إنشاء واجهة المستخدم الرسومية، افتح برنامج Visual Studio وأنشئ مشروعًا جديدًا.

بمجرد فتح برنامج Visual Studio ، انقر على ملف (1) -> جديد (2) -> مشروع (3).

Creating a new Visual Studio project

تحت نافذة مشروع جديد ، اختر Visual C# (1) ، حدد تطبيق WPF (.NET Framework) (2)، قم بتغيير الاسم إلى PoshGUI-sample (3) وانقر فوق موافق.

Choosing a Visual Studio project

بمجرد إنشاء المشروع ، سيتم عرض نموذج فارغ بالاسم MainWindow.xaml.

Visual Studio MainWindow.xaml

الآن تحتاج إلى تهيئة هذا النموذج ليلائم متطلباتنا. أدناه هي عناصر التحكم والتنسيق التي ستحتاج إلى إضافتها.

  • نافذة
    • العنوان: معلومات القرص
    • الارتفاع: 326
    • العرض: 403
  • عناصر التحكم (4)
    • تسمية
      • المحتوى: “اسم الكمبيوتر:”
      • الهوامش: 10، 10، 0، 0
    • مربع نص
      • الاسم: txtComputer
      • النص: “”
      • الارتفاع: 23
      • العرض: 174
    • زر
      • الاسم: btnQuery
      • المحتوى: استعلام
      • الهوامش: 0، 13، 12، 0
    • مربع نص
      • الاسم: txtResults
      • النص: “”
      • القراءة فقط: صحيح
      • الهوامش: 10، 60، 0، 0
      • الارتفاع: 225
      • العرض: 373

يجب أن يكون مظهر النموذج النهائي مشابهًا لما هو موضح في الصورة أدناه. يمكنك إعادة ترتيب تخطيط النافذة بشكل مختلف. كن مبدعًا!

PowerShell GUI Template

الجمع بين البرنامج النصي وواجهة المستخدم الرسومية PowerShell

بمجرد أن تكون راضيًا عن التصميم الخاص بك، يمكنك الآن البدء في دمجه مع البرنامج النصي.

لا يمكن لـ PowerShell عرض النماذج بشكل أصلي. لكي نتمكن من عرض النموذج، نحتاج إلى إضافة سطر من الشفرة إلى الجزء العلوي جدًا من البرنامج النصي لدعم تقديم نموذج WPF.

Add-Type -AssemblyName PresentationFramework

ثم أضف الشفرة لأداء الإجراءات التالية:

  1. استيراد وقراءة كود XAML للنموذج.
  2. إنشاء متغيرات بشكل ديناميكي معينة لكل عناصر التحكم المسماة
  3. عرض النموذج

فيما يلي الشيفرة المحدثة داخل البرنامج النصي الخاص بك.

ملاحظة: تأكد من تعديل السطر $xamlFile وتحويله إلى المسار الكامل لملف MainWindow.xaml الخاص بك.

Add-Type -AssemblyName PresentationFramework

Function Get-FixedDisk {
    [CmdletBinding()]
    # يشير هذا الكتلة param() إلى بداية تعريف المعلمات
    param (
        <# 
            هذا المعلمة يقبل اسم الكمبيوتر المستهدف.
            تم تعيينه أيضًا كإلزامي حتى لا يتم تنفيذ الوظيفة بدون تحديد القيمة.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        أمر استعلام WMI الذي يحصل على قائمة جميع الأقراص المنطقية ويحفظ النتائج في متغير يسمى $DiskInfo
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
    $DiskInfo
}

# أين يوجد ملف XAML؟
$xamlFile = "C:\PoshGUI-sample\MainWindow.xaml"

# إنشاء نافذة
$inputXML = Get-Content $xamlFile -Raw
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[XML]$XAML = $inputXML

# قراءة XAML
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
    $window = [Windows.Markup.XamlReader]::Load( $reader )
} catch {
    Write-Warning $_.Exception
    throw
}

# إنشاء متغيرات استنادًا إلى أسماء عناصر نموذج التحكم.
# سيتم تسمية المتغير بـ 'var_<اسم عنصر التحكم>'

$xaml.SelectNodes("//*[@Name]") | ForEach-Object {
    #"محاولة العنصر $($_.Name)"
    try {
        Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name) -ErrorAction Stop
    } catch {
        throw
    }
}
Get-Variable var_*

$Null = $window.ShowDialog()

ملاحظة: يجب أن يكون $Null = $window.ShowDialog() هو آخر سطر في الكود داخل النص البرمجي الخاص بك.

عند تشغيل هذا الكود عن طريق تنفيذ النص البرمجي Main.ps1 ، يجب أن ترى النتائج المثالية أدناه.

PowerShell GUI variable and field mappings

كما يمكنك ملاحظة أن العناصر الثلاثة المحددة تم تعيينها لمتغيراتها. سيتم الرجوع إلى أسماء هذه المتغيرات في وقت لاحق في النص البرمجي عند إضافة رمز منطق التحكم في العناصر.

  • var_btnQuery
  • var_btnComputer
  • var_txtResults

لاحظ أن البرنامج النصي في هذه النقطة يمكنه فقط عرض النموذج، ولكن العناصر التحكم غير مفيدة لأنك لم تضف الكود بعد.

إضافة كود حدث النقر على الزر

الآن بعد أن قمت بتعديل البرنامج النصي بنجاح لاستيراد وعرض واجهة المستخدم الرسومية، قم بإضافة الكود إلى عناصر التحكم لاسترجاع وعرض بيانات معلومات القرص.

في هذا المشروع، سيتم تعيين إجراء فقط لزر btnQuery. ستكون العناصر التحكم الأخرى فقط عناصر إدخال وعرض/إخراج. هذا يعني أننا نحتاج فقط لإضافة كود حدث النقر إلى btnQuery.

لإضافة إجراء النقر إلى btnQuery، قم بتعيين الكود أدناه لاسم المتغير المقابل $var_btnQuery. قم بنسخ الكود أدناه وأدخله بين إشارات الكود Get-Variable var_* و $Null = $window.ShowDialog() في البرنامج النصي.

$var_btnQuery.Add_Click( {
   #مسح مربع النتيجة
   $var_txtResults.Text = ""
       if ($result = Get-FixedDisk -Computer $var_txtComputer.Text) {
           foreach ($item in $result) {
               $var_txtResults.Text = $var_txtResults.Text + "DeviceID: $($item.DeviceID)`n"
               $var_txtResults.Text = $var_txtResults.Text + "VolumeName: $($item.VolumeName)`n"
               $var_txtResults.Text = $var_txtResults.Text + "FreeSpace: $($item.FreeSpace)`n"
               $var_txtResults.Text = $var_txtResults.Text + "Size: $($item.Size)`n`n"
           }
       }       
   })

$var_txtComputer.Text = $env:COMPUTERNAME

اختبار واجهة المستخدم لـ PowerShell المكتملة

مع تغطية جميع الأجزاء، فيما يلي البرنامج النصي المكتمل لدينا الذي يتضمن الوظيفة وواجهة المستخدم لـ PowerShell التي قمنا بتصميمها.

Add-Type -AssemblyName PresentationFramework

Function Get-FixedDisk {
    [CmdletBinding()]
    # يشير هذا الكتلة param () إلى بداية تعريف المعلمات
    param (
        <#
            يقبل هذا المعلمة اسم الكمبيوتر المستهدف.
            كما يتم تعيينها إلى إلزامي حتى لا يتم تنفيذ الوظيفة بدون تحديد القيمة.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        أمر استعلام WMI الذي يحصل على قائمة جميع الأقراص المنطقية ويحفظ النتائج في متغير يسمى $DiskInfo
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
   $DiskInfo
}

#أين يوجد ملف XAML؟
$xamlFile = "C:\Users\june\source\repos\PoshGUI-sample\PoshGUI-sample\MainWindow.xaml"

#إنشاء نافذة
$inputXML = Get-Content $xamlFile -Raw
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[xml]$XAML = $inputXML
#قراءة XAML

$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
    $window = [Windows.Markup.XamlReader]::Load( $reader )
}
catch {
    Write-Warning $_.Exception
    throw
}

#إنشاء متغيرات استنادًا إلى أسماء عناصر التحكم في النموذج.
#سيتم تسمية المتغير بـ 'var_<اسم عنصر التحكم>'

$xaml.SelectNodes("//*[@Name]") | ForEach-Object {
    #"جاري تجربة العنصر $($_.Name)";
    try {
        Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name) -ErrorAction Stop
    } catch {
        throw
   }
}

Get-Variable var_*

$var_btnQuery.Add_Click( {
   #مسح مربع النتيجة
   $var_txtResults.Text = ""
       if ($result = Get-FixedDisk -Computer $var_txtComputer.Text) {
           foreach ($item in $result) {
               $var_txtResults.Text = $var_txtResults.Text + "DeviceID: $($item.DeviceID)`n"
               $var_txtResults.Text = $var_txtResults.Text + "VolumeName: $($item.VolumeName)`n"
               $var_txtResults.Text = $var_txtResults.Text + "FreeSpace: $($item.FreeSpace)`n"
               $var_txtResults.Text = $var_txtResults.Text + "Size: $($item.Size)`n`n"
           }
       }       
   })

$var_txtComputer.Text = $env:COMPUTERNAME
$Null = $window.ShowDialog()

كما يمكنك رؤية ذلك أدناه ، بعد استدعاء النص في PowerShell ، ظهرت نوافذ واجهة المستخدم الرسومية لـ PowerShell. بعد ذلك ، يمكنك إدخال اسم كمبيوتر صالح لاختبار الوظائف.

PowerShell GUI Example Result

تحقق بأمان من المتصلين باستخدام طرق المصادقة التي تزيل فرصة انتحال الشخصية من المستخدم. قم بحجب قراصنة مكتب المساعدة بواسطة Specops Secure Service Desk. جربه مجانا!

ملخص

في هذه المقالة، تعلمت كيفية إنشاء وظيفة بسيطة تقبل إدخالًا وتُرجِع النتائج. كما تعلمت كيفية إنشاء واجهة مستخدم PowerShell الأساسية باستخدام WPF وكيفية استيرادها لتعمل كواجهة أمامية للنص البرمجي PowerShell الذي أنشأته.

هذا مجرد مزيج بسيط من النص البرمجي وواجهة المستخدم. يمكن القيام بالعديد من التحسينات مثل:

من المسؤولية الخاصة بك تعديل وإضافة وظائف استنادًا إلى متطلباتك.

قراءة إضافية

Source:
https://adamtheautomator.com/powershell-gui/