Logo

معمل أنظمة التشغيل - الأسبوع 5: إدارة الـ Processes في C#

20 دقيقة قراءة
شرائح الدرس
1 / 15

معمل نظم التشغيل - الأسبوع الخامس: إدارة العمليات في C#

تشغيل العمليات الخارجية وفحصها والتحكم فيها باستخدام System.Diagnostics

جدول المحتويات

  1. مقدمة
  2. البدء مع الـ Processes
  3. أساسيات صنف Process
  4. شرح توابع Process
  5. ProcessStartInfo - الإعدادات المتقدمة
  6. التطوير عبر المنصات المختلفة
  7. أمثلة عملية كاملة
  8. تمارين المعمل
  9. دليل مرجعي سريع

مقدمة

ما هي الـ 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

الخصائص المهمة

الخاصيةالنوعالوصفمثال
ProcessNamestringاسم الـ process"notepad"
Idintمعرِّف الـ process الفريد (PID)12345
StartTimeDateTimeوقت بدء الـ process2025-11-03 10:30:00
HasExitedboolهل الـ process ما زالت قيد التشغيل؟false
WorkingSet64longاستخدام الذاكرة (بالبايت)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:#ffa500

1. 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 MB

4. 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:#ffd93d

5. 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);

الخصائص الرئيسية

الخاصيةالنوعالوصف
FileNamestringالبرنامج المراد تشغيله
Argumentsstringمُعطَيات سطر الأوامر
WorkingDirectorystringالمجلد الذي يتم التشغيل منه
UseShellExecuteboolاستخدام shell نظام التشغيل (true) أو التشغيل المباشر (false)
WindowStyleenumNormal، Maximized، Minimized، Hidden
CreateNoWindowboolعدم إنشاء نافذة طرفية (Console Window)
RedirectStandardOutputboolالتقاط المخرجات
RedirectStandardInputboolإرسال المدخلات
RedirectStandardErrorboolالتقاط الأخطاء

مثال: الإعدادات الأساسية

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);

التقاط مخرجات الأوامر

لالتقاط المخرجات، يجب عليك:

  1. ضبط UseShellExecute = false
  2. ضبط 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");
        }
    }
}

الفروق بين المنصات

المهمةWindowsLinux
محرر النصوصnotepad.exexed، nano، vim
الـ Shellcmd.exe، powershell.exe/bin/bash
علامة الـ Shell/c-c
المتصفحchrome.exegoogle-chrome، firefox
مدير الملفاتexplorer.exenautilus

مثال: محرر نصوص يعمل عبر المنصات

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 بسيط ⭐

الهدف: إنشاء مُشغِّل محرر نصوص يعمل عبر المنصات المختلفة.

المتطلبات:

  1. اكتشاف نظام التشغيل
  2. تشغيل محرر النصوص المناسب (notepad.exe أو xed)
  3. فتح الملف "lab5_output.txt"
  4. عرض رسالة نجاح

تلميحات:

  • استخدم RuntimeInformation.IsOSPlatform()
  • استخدم try-catch لمعالجة الأخطاء
  • ارجع إلى مثال "محرر نصوص يعمل عبر المنصات"

الناتج المتوقع:

Operating System: Linux
Opening text editor...
Opened: lab5_output.txt

تمرين 2: مراقب الـ Processes ⭐⭐

الهدف: إنشاء تطبيق لمراقبة الـ processes.

المتطلبات:

  1. عرض قائمة بجميع الـ processes العاملة
  2. عرض: الاسم، PID، الذاكرة (بالميجابايت)
  3. السماح للمستخدم بالبحث بالاسم
  4. عرض أعلى 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 ⭐⭐

الهدف: بناء منفِّذ أوامر يعمل عبر المنصات المختلفة.

المتطلبات:

  1. استقبال أوامر من المستخدم
  2. التنفيذ على الـ shell الصحيح
  3. عرض المخرجات
  4. معالجة الأخطاء

أوامر للاختبار:

  • Windows: dir، echo Hello، date /t
  • Linux: ls -la، echo Hello، pwd

تلميحات:

  • اضبط UseShellExecute = false
  • اضبط RedirectStandardOutput = true
  • التقط كلًّا من المخرجات والأخطاء

تمرين 4: التحكم في الـ Process ⭐⭐⭐

الهدف: توضيح استخدام WaitForExit وKill وClose.

المتطلبات:

  1. تشغيل محرر نصوص
  2. عرض معلومات الـ process
  3. خيارات القائمة:
    • الانتظار حتى الانتهاء
    • الإنهاء القسري بعد 10 ثوانٍ
    • إيقاف التتبُّع
  4. عرض الرسائل المناسبة

تلميحات:

  • استخدم Thread.Sleep(10000)
  • تحقق من HasExited قبل تنفيذ العمليات
  • اشرح الفرق بين Kill وClose

تمرين 5: مدير النُسَخ ⭐⭐⭐

الهدف: تحديد عدد النُسَخ العاملة بثلاث نُسَخ كحد أقصى.

المتطلبات:

  1. حساب عدد النُسَخ العاملة
  2. عرض كل PID
  3. السماح ببدء نسخة جديدة (إذا كان العدد أقل من 3)
  4. المنع عند الوصول إلى الحد الأقصى

تحدٍّ إضافي: أضِف خاصية إنهاء 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 1234

Linux:

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

أهم النقاط

  1. الـ processes هي البرامج التي تعمل على جهازك
  2. توفر System.Diagnostics في C# أدوات قوية للتعامل مع الـ processes
  3. تعامل مع الأخطاء دائمًا باستخدام try-catch
  4. الأكواد التي تعمل عبر منصات متعددة تحتاج إلى اكتشاف نظام التشغيل
  5. دالة Kill() خطيرة - استخدمها بحذر