لفهم سبب تقييد Start-Process وجميع هذه الأوامر الأخرى، يجب أولاً أن تفهم كيفية عمل ملف EXE النموذجي. عند تشغيل ملف EXE، يقوم بأي إجراء تم تصميمه للقيام به؛ يقوم بعمل بينغ لشيء ما، يبدأ برنامج تثبيت (setup)، يبحث عن سجل DNS (nslookup)، وما إلى ذلك. لهذا الجزء و Start-Process و
الأوامر الأخرى لبدء عملية تعمل بشكل رائع. إنها بسيطة. يأتي القيد عندما يعيد ملف EXE بعض الإخراج.
يمكننا بدء عملية في PowerShell بعدة طرق مختلفة. لدينا أوامر Start-Process و Invoke-Expression
في PowerShell، يمكننا استدعاء البرنامج التنفيذي مباشرة أو استخدام علامة التعجب (&
) لاستدعاء التعابير. الطريقة الأكثر شيوعًا هي استخدام Start-Process
لأنها ربما تكون الأكثر بديهية. PowerShell معروف بطريقته المبتكرة في تسمية الأوامر و Start-Process هو خيار ممتاز. ومع ذلك، هذا الأمر محدود.
التدفقات
ملف EXE مثل العديد من ملفات التنفيذ الأخرى لا تقتصر على ويندوز لديه مفهوم للتدفقات القياسية. التدفقات القياسية هي كيفية عودة ملفات التنفيذ الإخراج. تأتي هذه التدفقات بثلاثة أنواع؛ stdin، stdout، و stderr. stdin هو التدفق الذي يمكن تمريره إلى الملف التنفيذي والذي لن نركز عليه هنا. stdout هو التدفق الذي يستخدمه الملف التنفيذي لإرسال الإخراج الطبيعي غير الخطأ.
في مصطلحات PowerShell، فكر في stdout كما يعود Write-Output
بإرجاعها. عند حدوث خطأ (اعتمادًا على ما إذا كتب مطور البرنامج التنفيذي ذلك بشكل صحيح)، يجب أن يقوم البرنامج التنفيذي بإرجاع الإخراج عبر stderr. هذا تيار مخصص لإرجاع أي معلومات خطأ.
هذه التيارات تسمح لمستخدمي هذه الملفات التنفيذية بالتفريق بين الإخراج النموذجي والخطأ. تستخدم التيارات منذ عقود وبالتالي فإن Windows و PowerShell يعرفان كل شيء عنها و قاموا بتبنيها بنفسهم.
رموز الخروج
رمز الخروج، أو رمز الإرجاع أو رمز النتيجة هو مفهوم آخر قديم يتبعه ملفات التنفيذي أيضًا. رمز الخروج هو عدد صحيح يسمح للملف التنفيذي بإشارة حالة للمستخدم عند الخروج.
هناك بعض رموز الخروج القياسية التي يفترض أن تتبعها البرامج مثل إذا كان رمز الخروج هو 0، فإن كل شيء على ما يرام، رمز الخروج 3010 يعني أنه يحتاج إلى إعادة تشغيل النظام وهكذا. يمكن لـ PowerShell التقاط هذا رمز الخروج بعدة طرق مختلفة مثل استخدام المتغير التلقائي $LastExitCode
. رموز الخروج هي طريقة أخرى يتواصل بها ملف التنفيذي مع المستخدم.
التقاط التيارات ورموز الخروج
الآن بمجرد فهمك لما نعمل به دعونا نستخدم مثالًا. لنبقيه بسيطًا، سأستخدم الأمر الجيد القديم ping.exe. أولا، سأقوم بعمل ping لـ google.com الذي سيعيد نتيجة ناجحة. لا نستخدم هنا عملية بدء PowerShell.
I’ll now purposefully ping a host that doesn’t resolve a DNS name and will fail. Notice the value of $LastExitCode
.
رأيت أن رمز الخروج يختلف لأن نتيجة ping كانت مختلفة ولكنك لم تر الجرار لأن PowerShell لا يفهم بشكل طبيعي الفارق عندما يتعلق الأمر بملفات التنفيذ. النص الذي تراه في واجهة الأوامر أبيض ؛ ليس النص الأحمر الخطأ الذي تعرفه وتحبه.
يمكننا التقاط الجرار وتوجيهها إلى ملفات بطرق مختلفة مثل استخدام >
و 2>
مثلما هو موضح أدناه. هذه هي الطريقة القديمة.
لاحظوا على الرغم من ذلك ، في هذه الحالة ، على الرغم من أن ping.exe يعود برمز خروج 1 (كما هو موضح أعلاه) ، إلا أن هذا الإخراج ما زال يذهب إلى stdout. هذا شائع. أي جرار ورمز خروج يعود يعتمد تمامًا على المطور ويأتي بأنماط مختلفة كثيرة ، للأسف.
إذا كنت ترغب في الانتقال بطريقة “المدرسة الجديدة” يمكنك استخدام Start-Process
واستخدام -RedirectStandardError
و -RedirectStandardOutput
، ولكنها ستذهب فقط إلى ملفات أيضًا.
قيود Start-Process
يمكنك أن ترى أن بدء عملية وإرجاع بعض الإخراج الشائع ليس أمرًا شائعًا جدًا. علاوة على ذلك ، لا يتعامل PowerShell بشكل جيد مع الجرار ورموز الخروج. إذا كنت سأستخدم Start-process لتشغيل ping.exe
وتريد تتبع ما حدث في النتيجة ، يجب أن أفعل شيئًا مثل هذا في كل مرة أريد تشغيل ملف قابل للتنفيذ.
I still wouldn’t get my error text either!
لنقم بتصحيح كل هذا. قم بتنزيل وظيفة صغيرة أنشأتها تسمى Invoke-Process
من PowerShell Gallery.
الآن قم بتشغيل ping باستخدام مضيف صالح وانظر ماذا يحدث.

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

الآن لاحظ أننا نحصل على نص خطأ أحمر اللون النموذجي كما نتوقع إذا كان هناك خطأ. يستخدم Invoke-Process
أمر Start-Process
تحت الغطاء لالتقاط stdout و stderr ورمز الخروج ، ثم يرسل الإخراج إلى الدفق الذي يفترض أن يكون فيه. هذا هو كيف يجب أن يكون!
من المؤسف أن PowerShell لم يجعل الأمور أسهل في التعامل مع الدفق ورموز الخروج من الملفات التنفيذية ، ولكن أعتقد أنه في الوقت الحالي ، يمكننا إضافة ذلك الآن بما أنه مفتوح المصدر!