معمل أنظمة التشغيل - الأسبوع 5: إدارة الـ Processes في C#
جدول المحتويات
- مقدمة
- البدء مع الـ Processes
- أساسيات صنف Process
- شرح توابع Process
- ProcessStartInfo - الإعدادات المتقدمة
- التطوير عبر المنصات المختلفة
- أمثلة عملية كاملة
- تمارين المعمل
- دليل مرجعي سريع
مقدمة
ما هي الـ Process؟
الـ process هي نسخة قيد التشغيل من برنامج ما. عندما تنقر نقرًا مزدوجًا على تطبيق، ينشئ نظام التشغيل عملية (process) خاصة به.
تمتلك كل process:
- مساحة ذاكرة خاصة بها (معزولة عن باقي الـ processes)
- معرِّف عملية فريد (Process ID - PID)
- موارد (ملفات، اتصالات شبكة، إلخ)
- حالة تنفيذ (قيد التشغيل، قيد الانتظار، إلخ)
مثال: عندما تفتح برنامج Notepad، ينشئ نظام التشغيل عملية باسم "notepad.exe".
graph TD
A[Your C# Application] -->|Process.Start| B[External Process]
A -->|Monitor| C[Running Processes]
A -->|Control| D[Process Lifecycle]
B --> E[Operating System]
C --> E
D --> E
style A fill:#4a90e2
style E fill:#50c878لماذا تتعلم إدارة الـ Processes؟
تُتيح إدارة الـ processes لتطبيقات C# الخاصة بك:
- ✅ تشغيل تطبيقات أخرى (فتح محررات النصوص، المتصفحات، الآلة الحاسبة)
- ✅ مراقبة عمليات النظام (تتبع استخدام الذاكرة، استخدام المعالج)
- ✅ التحكم في دورة حياة الـ process (البدء، الإيقاف، الانتظار حتى انتهاء الـ process)
- ✅ تنفيذ أوامر الـ shell (تشغيل أوامر النظام برمجيًا)
- ✅ أتمتة المهام (إدارة النظام، الاختبار، النشر)
استخدامات واقعية:
- أدوات مراقبة النظام
- أطر عمل الاختبار الآلي
- سكريبتات النشر (Deployment)
- أتمتة المهام
- أدوات إدارة النظام
البدء مع الـ Processes
أول برنامج لك يتعامل مع Process
لنبدأ بأبسط مثال ممكن:
Windows - فتح Notepad:
using System.Diagnostics;
class Program
{
static void Main()
{
Process.Start("notepad.exe");
}
}Linux - فتح محرر نصوص:
using System.Diagnostics;
class Program
{
static void Main()
{
Process.Start("xed");
}
}هذا كل ما في الأمر! هذا السطر الواحد يخبر نظام التشغيل ببدء process جديدة.
فتح ملف باستخدام تطبيق معيّن
Windows:
using System.Diagnostics;
class Program
{
static void Main()
{
Process.Start("notepad.exe", "example.txt");
}
}Linux:
using System.Diagnostics;
class Program
{
static void Main()
{
Process.Start("xed", "example.txt");
}
}الحصول على معلومات عن الـ Process الخاصة بك
Windows:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process process = Process.Start("notepad.exe");
Console.WriteLine($"Process Name: {process.ProcessName}");
Console.WriteLine($"Process ID: {process.Id}");
Console.WriteLine("\nPress Enter to close the program...");
Console.ReadLine();
}
}Linux:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process process = Process.Start("xed");
Console.WriteLine($"Process Name: {process.ProcessName}");
Console.WriteLine($"Process ID: {process.Id}");
Console.WriteLine("\nPress Enter to close the program...");
Console.ReadLine();
}
}مثال على الناتج (Windows):
Process Name: notepad
Process ID: 12345
Press Enter to close the program...مثال على الناتج (Linux):
Process Name: xed
Process ID: 12345
Press Enter to close the program...أساسيات صنف Process
مساحة الاسم System.Diagnostics
توجد جميع وظائف إدارة الـ process في مساحة الاسم System.Diagnostics:
using System.Diagnostics; // Always include thisنظرة عامة على صنف Process
classDiagram
class Process {
+ProcessName : string
+Id : int
+StartTime : DateTime
+HasExited : bool
+WorkingSet64 : long
+Start() : Process
+Kill() : void
+WaitForExit() : void
+Close() : void
}
class ProcessStartInfo {
+FileName : string
+Arguments : string
+WorkingDirectory : string
+UseShellExecute : bool
}
Process --> ProcessStartInfo : usesالخصائص المهمة
| الخاصية | النوع | الوصف | مثال |
|---|---|---|---|
ProcessName | string | اسم الـ process | "notepad" |
Id | int | معرِّف الـ process الفريد (PID) | 12345 |
StartTime | DateTime | وقت بدء الـ process | 2025-11-03 10:30:00 |
HasExited | bool | هل الـ process ما زالت قيد التشغيل؟ | false |
WorkingSet64 | long | استخدام الذاكرة (بالبايت) | 15728640 |
مثال: الوصول إلى خصائص Process
Windows:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process process = Process.Start("notepad.exe");
Console.WriteLine("=== Process Information ===");
Console.WriteLine($"Process Name: {process.ProcessName}");
Console.WriteLine($"Process ID: {process.Id}");
Console.WriteLine($"Start Time: {process.StartTime}");
Console.WriteLine($"Memory (KB): {process.WorkingSet64 / 1024}");
Console.WriteLine($"Has Exited: {process.HasExited}");
Console.WriteLine("\nClose Notepad to continue...");
process.WaitForExit();
Console.WriteLine("\nNotepad has been closed!");
Console.WriteLine($"Has Exited: {process.HasExited}");
}
}Linux:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process process = Process.Start("xed");
Console.WriteLine("=== Process Information ===");
Console.WriteLine($"Process Name: {process.ProcessName}");
Console.WriteLine($"Process ID: {process.Id}");
Console.WriteLine($"Start Time: {process.StartTime}");
Console.WriteLine($"Memory (KB): {process.WorkingSet64 / 1024}");
Console.WriteLine($"Has Exited: {process.HasExited}");
Console.WriteLine("\nClose xed to continue...");
process.WaitForExit();
Console.WriteLine("\nxed has been closed!");
Console.WriteLine($"Has Exited: {process.HasExited}");
}
}شرح توابع Process
توابع استرجاع المعلومات
graph LR
A[Process Methods] --> B[GetProcesses]
A --> C[GetCurrentProcess]
A --> D[GetProcessesByName]
A --> E[GetProcessById]
B --> F[All Running Processes]
C --> G[Your Application]
D --> H[Find by Name]
E --> I[Find by ID]
style A fill:#4a90e2
style F fill:#ffa500
style G fill:#ffa500
style H fill:#ffa500
style I fill:#ffa5001. GetProcesses() - عرض جميع الـ Processes
يحصل على كل process قيد التشغيل على النظام.
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process[] processes = Process.GetProcesses();
Console.WriteLine($"Total processes: {processes.Length}\n");
// Show first 10 processes
for (int i = 0; i < 10 && i < processes.Length; i++)
{
Console.WriteLine($"{processes[i].ProcessName} (PID: {processes[i].Id})");
}
}
}مثال على الناتج:
Total processes: 287
System (PID: 4)
svchost (PID: 756)
explorer (PID: 2184)
chrome (PID: 5432)
notepad (PID: 8912)
...2. GetCurrentProcess() - تطبيقك الحالي
يحصل على الـ process الخاصة بتطبيقك أنت.
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process me = Process.GetCurrentProcess();
Console.WriteLine("=== My Process Info ===");
Console.WriteLine($"Name: {me.ProcessName}");
Console.WriteLine($"PID: {me.Id}");
Console.WriteLine($"Memory: {me.WorkingSet64 / 1024} KB");
Console.WriteLine($"Threads: {me.Threads.Count}");
}
}3. GetProcessesByName() - البحث بالاسم
يبحث عن جميع الـ processes التي تحمل اسمًا محددًا.
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
string name = "chrome"; // Process name to search
Process[] processes = Process.GetProcessesByName(name);
Console.WriteLine($"Found {processes.Length} instance(s) of {name}\n");
foreach (Process p in processes)
{
double memoryMB = p.WorkingSet64 / (1024.0 * 1024.0);
Console.WriteLine($"PID {p.Id}: {memoryMB:F2} MB");
}
}
}مثال على الناتج:
Found 3 instance(s) of chrome
PID 5432: 125.34 MB
PID 6128: 89.21 MB
PID 7456: 112.67 MB4. GetProcessById() - البحث بمعرِّف الـ Process
يبحث عن process محددة باستخدام معرِّفها (PID).
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
try
{
int pid = 1234; // Replace with actual PID
Process process = Process.GetProcessById(pid);
Console.WriteLine($"Found process:");
Console.WriteLine($"Name: {process.ProcessName}");
Console.WriteLine($"ID: {process.Id}");
}
catch (ArgumentException)
{
Console.WriteLine("Process not found!");
}
}
}توابع التحكم في الـ Process
graph TD
A[Process Control] --> B[WaitForExit]
A --> C[Kill]
A --> D[Close]
B --> E[Wait for natural exit]
C --> F[Force terminate]
D --> G[Release tracking]
style A fill:#4a90e2
style B fill:#50c878
style C fill:#ff6b6b
style D fill:#ffd93d5. WaitForExit() - الانتظار حتى انتهاء الـ Process
الانتظار إلى أن تنتهي - Windows:
Process process = Process.Start("notepad.exe");
Console.WriteLine("Waiting for Notepad...");
process.WaitForExit(); // Blocks until Notepad closes
Console.WriteLine("Notepad closed!");الانتظار إلى أن تنتهي - Linux:
Process process = Process.Start("xed");
Console.WriteLine("Waiting for xed...");
process.WaitForExit(); // Blocks until xed closes
Console.WriteLine("xed closed!");الانتظار بمهلة زمنية محددة - Windows:
Process process = Process.Start("notepad.exe");
bool exited = process.WaitForExit(5000); // Wait max 5 seconds
if (exited)
{
Console.WriteLine("Process exited within 5 seconds");
}
else
{
Console.WriteLine("Process still running after 5 seconds");
}الانتظار بمهلة زمنية محددة - Linux:
Process process = Process.Start("xed");
bool exited = process.WaitForExit(5000); // Wait max 5 seconds
if (exited)
{
Console.WriteLine("Process exited within 5 seconds");
}
else
{
Console.WriteLine("Process still running after 5 seconds");
}6. Kill() - الإنهاء القسري
⚠️ تحذير: ينهي Kill() الـ process فورًا دون أي تنظيف (Cleanup)!
Windows:
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main()
{
Process process = Process.Start("notepad.exe");
Console.WriteLine("Notepad will be killed in 5 seconds...");
Thread.Sleep(5000);
process.Kill();
process.WaitForExit();
Console.WriteLine("Notepad terminated!");
}
}Linux:
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main()
{
Process process = Process.Start("xed");
Console.WriteLine("xed will be killed in 5 seconds...");
Thread.Sleep(5000);
process.Kill();
process.WaitForExit();
Console.WriteLine("xed terminated!");
}
}7. Close() - تحرير الموارد
يُحرِّر Close() تتبُّع تطبيقك للـ process، لكن الـ process تبقى قيد التشغيل.
Windows:
Process process = Process.Start("notepad.exe");
Console.WriteLine("Notepad started");
process.Close(); // Your app stops tracking it
Console.WriteLine("Tracking released (Notepad still running)");Linux:
Process process = Process.Start("xed");
Console.WriteLine("xed started");
process.Close(); // Your app stops tracking it
Console.WriteLine("Tracking released (xed still running)");الفرق:
Kill(): يُنهي الـ process ❌Close(): يتوقف عن تتبُّع الـ process، لكنها تظل قيد التشغيل ✅
ProcessStartInfo - الإعدادات المتقدمة
ما هو ProcessStartInfo؟
يمنحك ProcessStartInfo تحكمًا دقيقًا في كيفية بدء الـ process.
الاستخدام الأساسي:
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "notepad.exe",
Arguments = "example.txt"
};
Process.Start(startInfo);الخصائص الرئيسية
| الخاصية | النوع | الوصف |
|---|---|---|
FileName | string | البرنامج المراد تشغيله |
Arguments | string | مُعطَيات سطر الأوامر |
WorkingDirectory | string | المجلد الذي يتم التشغيل منه |
UseShellExecute | bool | استخدام shell نظام التشغيل (true) أو التشغيل المباشر (false) |
WindowStyle | enum | Normal، Maximized، Minimized، Hidden |
CreateNoWindow | bool | عدم إنشاء نافذة طرفية (Console Window) |
RedirectStandardOutput | bool | التقاط المخرجات |
RedirectStandardInput | bool | إرسال المدخلات |
RedirectStandardError | bool | التقاط الأخطاء |
مثال: الإعدادات الأساسية
Windows:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "notepad.exe",
Arguments = "example.txt",
WindowStyle = ProcessWindowStyle.Maximized
};
Process.Start(startInfo);
Console.WriteLine("Notepad opened (maximized)");
}
}Linux:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "xed",
Arguments = "example.txt",
WindowStyle = ProcessWindowStyle.Maximized
};
Process.Start(startInfo);
Console.WriteLine("xed opened (maximized)");
}
}أنماط النوافذ (Window Styles)
graph LR
A[WindowStyle] --> B[Normal]
A --> C[Maximized]
A --> D[Minimized]
A --> E[Hidden]
B --> F[Default size]
C --> G[Fullscreen]
D --> H[Taskbar only]
E --> I[No window]
style A fill:#4a90e2مثال:
Windows:
// Normal window
new ProcessStartInfo { FileName = "notepad.exe", WindowStyle = ProcessWindowStyle.Normal };
// Maximized window
new ProcessStartInfo { FileName = "notepad.exe", WindowStyle = ProcessWindowStyle.Maximized };
// Minimized window
new ProcessStartInfo { FileName = "notepad.exe", WindowStyle = ProcessWindowStyle.Minimized };
// Hidden window
new ProcessStartInfo { FileName = "notepad.exe", WindowStyle = ProcessWindowStyle.Hidden };Linux:
// Normal window
new ProcessStartInfo { FileName = "xed", WindowStyle = ProcessWindowStyle.Normal };
// Maximized window
new ProcessStartInfo { FileName = "xed", WindowStyle = ProcessWindowStyle.Maximized };
// Minimized window
new ProcessStartInfo { FileName = "xed", WindowStyle = ProcessWindowStyle.Minimized };
// Hidden window
new ProcessStartInfo { FileName = "xed", WindowStyle = ProcessWindowStyle.Hidden };شرح UseShellExecute
هذه الخاصية مهمة جدًا لفهم كيفية بدء الـ processes.
UseShellExecute = true (القيمة الافتراضية):
- ✅ يمكنها فتح الروابط (https://google.com)
- ✅ يمكنها فتح المستندات بالبرامج الافتراضية
- ❌ لا يمكنها إعادة توجيه الإدخال/الإخراج
UseShellExecute = false:
- ✅ يمكنها إعادة توجيه الإدخال/الإخراج
- ✅ تنفيذ مباشر للبرنامج
- ❌ لا يمكنها فتح الروابط مباشرةً
مثال - فتح رابط (يتطلب true):
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "https://www.google.com",
UseShellExecute = true // Required for URLs
};
Process.Start(startInfo);التقاط مخرجات الأوامر
لالتقاط المخرجات، يجب عليك:
- ضبط
UseShellExecute = false - ضبط
RedirectStandardOutput = true
مثال Windows:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c date /t", // Get current date
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
Process process = Process.Start(startInfo);
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
Console.WriteLine("Command output:");
Console.WriteLine(output);
}
}مثال Linux:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = "-c \"date\"", // Get current date
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
Process process = Process.Start(startInfo);
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
Console.WriteLine("Command output:");
Console.WriteLine(output);
}
}إعادة توجيه الإدخال والإخراج والأخطاء
sequenceDiagram
participant App as Your Application
participant Proc as External Process
participant OS as Operating System
App->>Proc: Start with Redirect = true
App->>Proc: Send commands (StandardInput)
Proc->>OS: Execute commands
OS->>Proc: Return output
Proc->>App: Output (StandardOutput)
Proc->>App: Errors (StandardError)مثال كامل:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe", // Windows
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
Process process = Process.Start(startInfo);
// Send commands
process.StandardInput.WriteLine("echo Hello World!");
process.StandardInput.WriteLine("date /t");
process.StandardInput.WriteLine("exit");
// Read output
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();
process.WaitForExit();
Console.WriteLine("=== Output ===");
Console.WriteLine(output);
if (!string.IsNullOrEmpty(errors))
{
Console.WriteLine("\n=== Errors ===");
Console.WriteLine(errors);
}
}
}التطوير عبر المنصات المختلفة
اكتشاف نظام التشغيل
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Console.WriteLine("Running on Windows");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Console.WriteLine("Running on Linux");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
Console.WriteLine("Running on macOS");
}
}
}الفروق بين المنصات
| المهمة | Windows | Linux |
|---|---|---|
| محرر النصوص | notepad.exe | xed، nano، vim |
| الـ Shell | cmd.exe، powershell.exe | /bin/bash |
| علامة الـ Shell | /c | -c |
| المتصفح | chrome.exe | google-chrome، firefox |
| مدير الملفات | explorer.exe | nautilus |
مثال: محرر نصوص يعمل عبر المنصات
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
OpenTextEditor("example.txt");
}
static void OpenTextEditor(string fileName)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
startInfo.FileName = "notepad.exe";
startInfo.Arguments = fileName;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
startInfo.FileName = "xed";
startInfo.Arguments = fileName;
}
else
{
Console.WriteLine("Unsupported OS");
return;
}
try
{
Process.Start(startInfo);
Console.WriteLine($"Opened: {fileName}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}مثال: متصفح يعمل عبر المنصات
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
OpenBrowser("https://www.google.com");
}
static void OpenBrowser(string url)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = url,
UseShellExecute = true
};
Process.Start(startInfo);
Console.WriteLine($"Opened: {url}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}مثال: تنفيذ أوامر Shell عبر المنصات
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
string output = ExecuteCommand("echo Hello World!");
Console.WriteLine(output);
}
static string ExecuteCommand(string command)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c {command}";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
startInfo.FileName = "/bin/bash";
startInfo.Arguments = $"-c \"{command}\"";
}
else
{
return "Unsupported OS";
}
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = true;
try
{
Process process = Process.Start(startInfo);
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return output;
}
catch (Exception ex)
{
return $"Error: {ex.Message}";
}
}
}أمثلة عملية كاملة
المثال 1: مراقب الـ Processes
مراقبة عمليات النظام وعرض أكثر العمليات استهلاكًا للذاكرة.
using System;
using System.Diagnostics;
using System.Linq;
class Program
{
static void Main()
{
Console.WriteLine("=== PROCESS MONITOR ===\n");
Process[] processes = Process.GetProcesses();
var topProcesses = processes
.OrderByDescending(p => p.WorkingSet64)
.Take(10);
Console.WriteLine("Top 10 processes by memory:\n");
Console.WriteLine("{0,-30} {1,-10} {2,15}", "Name", "PID", "Memory (MB)");
Console.WriteLine(new string('-', 60));
foreach (var p in topProcesses)
{
try
{
double mb = p.WorkingSet64 / (1024.0 * 1024.0);
Console.WriteLine("{0,-30} {1,-10} {2,15:F2}",
p.ProcessName, p.Id, mb);
}
catch { }
}
}
}المثال 2: أداة البحث عن Process
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Console.Write("Enter process name to search: ");
string name = Console.ReadLine();
Process[] processes = Process.GetProcessesByName(name);
if (processes.Length == 0)
{
Console.WriteLine($"\nNo processes found: {name}");
return;
}
Console.WriteLine($"\nFound {processes.Length} process(es):\n");
Console.WriteLine("{0,-10} {1,15} {2,20}", "PID", "Memory (MB)", "Start Time");
Console.WriteLine(new string('-', 50));
foreach (var p in processes)
{
try
{
double mb = p.WorkingSet64 / (1024.0 * 1024.0);
Console.WriteLine("{0,-10} {1,15:F2} {2,20}",
p.Id, mb, p.StartTime.ToString("HH:mm:ss"));
}
catch { }
}
}
}المثال 3: مدير نُسَخ الـ Process
تحديد عدد النُسَخ العاملة من تطبيقك بثلاث نُسَخ كحد أقصى.
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process current = Process.GetCurrentProcess();
Process[] instances = Process.GetProcessesByName(current.ProcessName);
Console.WriteLine($"=== INSTANCE MANAGER ===");
Console.WriteLine($"Running instances: {instances.Length}\n");
// Show all instances
foreach (var inst in instances)
{
string marker = inst.Id == current.Id ? " (This one)" : "";
Console.WriteLine($"PID: {inst.Id}{marker}");
}
// Check limit
if (instances.Length < 3)
{
Console.Write("\nStart new instance? (y/n): ");
if (Console.ReadLine()?.ToLower() == "y")
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = Environment.ProcessPath,
UseShellExecute = true
};
Process.Start(startInfo);
Console.WriteLine("New instance started!");
}
}
else
{
Console.WriteLine("\nMaximum instances (3) reached!");
}
Console.WriteLine("\nPress Enter to exit...");
Console.ReadLine();
}
}المثال 4: منفِّذ الأوامر التفاعلي
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
Console.WriteLine("=== COMMAND EXECUTOR ===");
Console.WriteLine("Type commands (or 'exit' to quit)\n");
while (true)
{
Console.Write("> ");
string command = Console.ReadLine();
if (command?.ToLower() == "exit")
break;
if (string.IsNullOrWhiteSpace(command))
continue;
string output = ExecuteCommand(command);
Console.WriteLine(output);
}
}
static string ExecuteCommand(string command)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c {command}";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
startInfo.FileName = "/bin/bash";
startInfo.Arguments = $"-c \"{command}\"";
}
else
{
return "Unsupported OS";
}
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.CreateNoWindow = true;
try
{
Process process = Process.Start(startInfo);
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();
process.WaitForExit();
return string.IsNullOrEmpty(errors) ? output : $"{output}\nErrors:\n{errors}";
}
catch (Exception ex)
{
return $"Error: {ex.Message}";
}
}
}تمارين المعمل
تمرين 1: مُشغِّل Process بسيط ⭐
الهدف: إنشاء مُشغِّل محرر نصوص يعمل عبر المنصات المختلفة.
المتطلبات:
- اكتشاف نظام التشغيل
- تشغيل محرر النصوص المناسب (notepad.exe أو xed)
- فتح الملف "lab5_output.txt"
- عرض رسالة نجاح
تلميحات:
- استخدم
RuntimeInformation.IsOSPlatform() - استخدم
try-catchلمعالجة الأخطاء - ارجع إلى مثال "محرر نصوص يعمل عبر المنصات"
الناتج المتوقع:
Operating System: Linux
Opening text editor...
Opened: lab5_output.txtتمرين 2: مراقب الـ Processes ⭐⭐
الهدف: إنشاء تطبيق لمراقبة الـ processes.
المتطلبات:
- عرض قائمة بجميع الـ processes العاملة
- عرض: الاسم، PID، الذاكرة (بالميجابايت)
- السماح للمستخدم بالبحث بالاسم
- عرض أعلى 5 processes من حيث استهلاك الذاكرة
تلميحات:
- استخدم
Process.GetProcesses() - استخدم LINQ
.OrderByDescending(p => p.WorkingSet64) - الصيغة:
WorkingSet64 / (1024.0 * 1024.0)
قائمة نموذجية:
=== PROCESS MONITOR ===
1. List all processes
2. Search by name
3. Top 5 by memory
0. Exit
Choice:تمرين 3: منفِّذ أوامر Shell ⭐⭐
الهدف: بناء منفِّذ أوامر يعمل عبر المنصات المختلفة.
المتطلبات:
- استقبال أوامر من المستخدم
- التنفيذ على الـ shell الصحيح
- عرض المخرجات
- معالجة الأخطاء
أوامر للاختبار:
- Windows:
dir،echo Hello،date /t - Linux:
ls -la،echo Hello،pwd
تلميحات:
- اضبط
UseShellExecute = false - اضبط
RedirectStandardOutput = true - التقط كلًّا من المخرجات والأخطاء
تمرين 4: التحكم في الـ Process ⭐⭐⭐
الهدف: توضيح استخدام WaitForExit وKill وClose.
المتطلبات:
- تشغيل محرر نصوص
- عرض معلومات الـ process
- خيارات القائمة:
- الانتظار حتى الانتهاء
- الإنهاء القسري بعد 10 ثوانٍ
- إيقاف التتبُّع
- عرض الرسائل المناسبة
تلميحات:
- استخدم
Thread.Sleep(10000) - تحقق من
HasExitedقبل تنفيذ العمليات - اشرح الفرق بين Kill وClose
تمرين 5: مدير النُسَخ ⭐⭐⭐
الهدف: تحديد عدد النُسَخ العاملة بثلاث نُسَخ كحد أقصى.
المتطلبات:
- حساب عدد النُسَخ العاملة
- عرض كل PID
- السماح ببدء نسخة جديدة (إذا كان العدد أقل من 3)
- المنع عند الوصول إلى الحد الأقصى
تحدٍّ إضافي: أضِف خاصية إنهاء process باستخدام الـ PID.
تلميحات:
- استخدم
Process.GetCurrentProcess() - استخدم
Process.GetProcessesByName() - استخدم
Environment.ProcessPath
دليل مرجعي سريع
عمليات Process الشائعة
بدء process:
Windows:
Process.Start("notepad.exe");
Process.Start("notepad.exe", "file.txt");Linux:
Process.Start("xed");
Process.Start("xed", "file.txt");الحصول على معلومات الـ process:
Windows:
Process p = Process.Start("notepad.exe");
Console.WriteLine($"{p.ProcessName} - PID: {p.Id}");Linux:
Process p = Process.Start("xed");
Console.WriteLine($"{p.ProcessName} - PID: {p.Id}");الانتظار حتى الانتهاء:
process.WaitForExit(); // Wait forever
bool exited = process.WaitForExit(5000); // 5 second timeoutإنهاء الـ process:
Windows:
process.Kill();
process.WaitForExit();Linux:
process.Kill();
process.WaitForExit();(نفس الطريقة في كلتا المنصتين)
عرض جميع الـ processes:
Process[] all = Process.GetProcesses();البحث بالاسم:
Process[] chrome = Process.GetProcessesByName("chrome");الـ process الحالية:
Process me = Process.GetCurrentProcess();التقاط مخرجات الأوامر
Windows:
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c dir",
UseShellExecute = false,
RedirectStandardOutput = true
};
Process p = Process.Start(startInfo);
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();Linux:
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = "-c \"ls -la\"",
UseShellExecute = false,
RedirectStandardOutput = true
};
Process p = Process.Start(startInfo);
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();اكتشاف المنصة
using System.Runtime.InteropServices;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Windows code
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
// Linux code
}أمثلة سريعة جاهزة للنسخ واللصق
عرض جميع الـ processes:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
foreach (var p in Process.GetProcesses())
{
Console.WriteLine($"{p.ProcessName} - {p.Id}");
}
}
}أعلى 5 processes من حيث استهلاك الذاكرة:
using System;
using System.Diagnostics;
using System.Linq;
class Program
{
static void Main()
{
var top = Process.GetProcesses()
.OrderByDescending(p => p.WorkingSet64)
.Take(5);
foreach (var p in top)
{
double mb = p.WorkingSet64 / (1024.0 * 1024.0);
Console.WriteLine($"{p.ProcessName}: {mb:F2} MB");
}
}
}الحصول على الـ process الحالية:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process me = Process.GetCurrentProcess();
Console.WriteLine($"Name: {me.ProcessName}");
Console.WriteLine($"PID: {me.Id}");
Console.WriteLine($"Memory: {me.WorkingSet64 / 1024} KB");
}
}البحث عن processes:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Process[] procs = Process.GetProcessesByName("chrome");
Console.WriteLine($"Found {procs.Length} instances");
foreach (var p in procs)
{
Console.WriteLine($"PID: {p.Id}");
}
}
}الإنهاء بعد مهلة زمنية:
Windows:
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main()
{
Process p = Process.Start("notepad.exe");
Console.WriteLine("Killing in 5 seconds...");
Thread.Sleep(5000);
p.Kill();
p.WaitForExit();
Console.WriteLine("Killed!");
}
}Linux:
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main()
{
Process p = Process.Start("xed");
Console.WriteLine("Killing in 5 seconds...");
Thread.Sleep(5000);
p.Kill();
p.WaitForExit();
Console.WriteLine("Killed!");
}
}أوامر مفيدة للمعمل
Windows:
dotnet build
dotnet run
tasklist
taskkill /PID 1234Linux:
dotnet build
dotnet run
ps aux
ps aux | grep processname
kill 1234
pkill processname
topأفضل الممارسات
✅ افعل دائمًا:
- استخدم
try-catchلعمليات الـ process - استدعِ
Dispose()أو استخدم عباراتusing - تحقق من
HasExitedقبل الوصول إلى الخصائص - استخدم اكتشاف المنصة للأكواد التي تعمل عبر منصات متعددة
⚠️ كن حذرًا:
Kill()ينهي الـ process دون تنظيف- تحتاج بعض الـ processes إلى صلاحيات مرتفعة (Elevated Privileges)
- أسماء الـ processes حساسة لحالة الأحرف (Case-Sensitive) على Linux
❌ لا تفعل أبدًا:
- تنفيذ مدخلات مستخدم غير موثوقة
- نسيان الانتظار بعد استدعاء Kill()
- تجاهل الاستثناءات (Exceptions)
ملخص
ما تعلمته
✅ أساسيات الـ Process: فهم ماهية الـ processes
✅ صنف Process: الخصائص والتوابع
✅ بدء الـ Processes: طرق بسيطة ومتقدمة
✅ معلومات الـ Process: الحصول عليها ومراقبتها
✅ التحكم في الـ Process: Wait وKill وClose
✅ ProcessStartInfo: الإعدادات المتقدمة
✅ إعادة توجيه الإدخال/الإخراج: التقاط المخرجات
✅ العمل عبر منصات متعددة: دعم Windows وLinux
mindmap
root((Process Management))
Basics
What is a Process
Process.Start
Properties
Methods
GetProcesses
GetCurrentProcess
GetProcessesByName
GetProcessById
Control
WaitForExit
Kill
Close
Advanced
ProcessStartInfo
I/O Redirection
Cross-Platformأهم النقاط
- الـ processes هي البرامج التي تعمل على جهازك
- توفر System.Diagnostics في C# أدوات قوية للتعامل مع الـ processes
- تعامل مع الأخطاء دائمًا باستخدام try-catch
- الأكواد التي تعمل عبر منصات متعددة تحتاج إلى اكتشاف نظام التشغيل
- دالة Kill() خطيرة - استخدمها بحذر