על מנת להבין למה Start-Process וכל הפקודות הללו מוגבלות, עליך להבין תחילה איך קובץ EXE טיפיקלי פועל. כאשר קובץ EXE נפתח, הוא מבצע את הפעולה שנוצבע לו; הוא יכול לשלוח פינג (ping), להתחיל מתקין תוכנה (setup), לחפש רשומת DNS (nslookup), וכו'. לכן, עבור חלק זה ועבור פקודות כמו Start-Process, הפעולה יעילה. זה פשוט. ההגבלה מתגלה כאשר ה-EXE מחזיר פלט.
אנו יכולים להתחיל תהליך ב-PowerShell בכמה דרכים שונות. יש לנו את ה-Start-Process של PowerShell ואת ה-Invoke-Expression
, נוכל לקרוא לקובץ הנוצר ישירות או להשתמש ב-ampersand (&
) כדי להפעיל ביטויים. הדרך הנפוצה ביותר היא להשתמש ב-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
.
ראית שקוד היציאה שונה מכיוון שתוצאת הפינג הייתה שונה אבל לא ראית נתונים כי פוורשל לא מבין את ההבדל כשמדובר בקבצי ניתוב תכנותיים. הטקסט שאתה רואה במסוף הוא לבן; לא הטקסט השגיאה האדום שאתה מכיר ואוהב.
נוכל לתפוס את הנתונים ולהפנות אותם לקבצים בכמה דרכים שונות כמו שימוש ב־>
ו־2>
כמו שמוצג למטה. זהו הדרך הישנה.
שים לב עם זאת, במקרה זה, אף על פי ש־ping.exe מחזיר קוד יציאה של 1 (כפי שמוצג לעיל), הפלט עדיין הולך ל־stdout. זה די נפוץ. איזה נתון וקוד יציאה שמוחזרים זה נעצר על ידי המפתח ומגיעים בסגנונות רבים שונים, למרבה המצטער.
אם תרצה ללכת לדרך "החדשה" תוכל להשתמש ב־Start-Process
ולהשתמש בפרמטרים -RedirectStandardError
ו־-RedirectStandardOutput
, אך הם עדיין יישלחו רק לקבצים.
מגבלות של Start-Process
תראה שהתחלת תהליך והחזרת פלט מקובץ לא נפוץ במיוחד. בנוסף, פוורשל לא מטפל בנתונים ובקודי יציאה בצורה טובה מדי. אם הייתי רוצה להשתמש ב־Start-process כדי להריץ ping.exe
ולרצות לעקוב מה קרה בתוצאה, יהיה עליי לעשות משהו כמו זה כל פעם שארצה להריץ קובץ ניתוב.
I still wouldn’t get my error text either!
בוא נתקן את כל זה. הורד פונקציה קטנה שיצרתי בשם Invoke-Process
מגלריית PowerShell.
עכשיו הרץ את הפינג באמצעות מארח תקין וצפה מה יקרה.

השם לִכְתוֹבֶת הַאֲיַפָּיָים אוֹ השם הַנוֹתֵן מִדַּעַת פֵּלָא, אֲם אֵינְךָ בָּטוֹחַ בְּהִיעָרוֹת, אֶל תְּבַצֵּעַ פְּעוּלָה זוֹ.
עַכְשָׁיו הַרְץ פִּינְג בְּאַמְצָעוּיוֹת שֶׁלֹּא חוּקִית.

עַכְשָׁו תַּפְסִיק שְׁנֵהֶגֶיה לָאָדוֹם הַטִקסט שֶׁגַּם זֶה נָכוֹן לְצַפוֹת בּוֹ כְּאָמוּר.Invoke-Process
מַשְׁתִּמֵשׁ Start-Process
תַּחְתִּיו לְתָפוּס stdout, stderr, וְקוֹד יְצִיאָה וְאָז שׁוֹלֵחַ אֶת הַפַּלט לַזְרוֹם שֶׁהוּא צָרִיך לָלֶכֶת אֵלָיו. זֶה כְּךָ הוּא!
חָבְל שֶׁפֹּוֵורְשֶׁלַפֵוֶר לֹא עָשָׂה זֶה קָל יוֹתֵר לַעֲבוֹד עִם זַרְמִים וּקוֹדֵי יְצִיאָה מִקוֹבְצִים בִּיצוּר, אֲבָל אֲנִי מְנַחֵשׁ שֶׁיֵּשׁ לְהוֹסִיף אֶת זֶה שָׁם עַכְשָׁו שֶׁזֶה פָּתוּחַ!