←→ Underneath: Background Apps · كل أدلة Mac

لماذا يعود تطبيق بعد إعادة تشغيل Mac

أنهيته. بل أنهيته إنهاءً إجباريًا في «مراقب النشاط». وبعد ثانيتين، أو بعد إعادة التشغيل التالية، عاد يعمل من جديد. شيء ما يشغّله عن قصد. وعلى Mac، يكون هذا الشيء في الغالب launchd.

الإجابة المختصرة: للتطبيق مهمة launchd. المفتاح RunAtLoad يشغّلها عند كل تسجيل دخول، وKeepAlive يشغّلها مجددًا كلما توقفت. إنهاء العملية لا يغيّر المهمة. لإيقافها نهائيًا، عطّل المهمة، لا العملية.

ما هو launchd

launchd هو أول عملية يبدأها macOS (معرّف العملية 1). وهو يبدأ كل شيء آخر تقريبًا. يقرأ ملفات .plist صغيرة تُسمّى مهام، تحدد ما يجب تشغيله ومتى. لكل مهمة معرّف (label)، وهو اسم فريد مثل com.google.keystone.agent.

تثبّت التطبيقات المهام في ~/Library/LaunchAgents أو /Library/LaunchAgents أو /Library/LaunchDaemons، أو تسجّلها من داخل حزمة التطبيق نفسها.

المفاتيح التي تعيد التطبيق

إليك وكيل تشغيل نموذجيًا:

<key>Label</key>
<string>com.example.helper</string>
<key>ProgramArguments</key>
<array>
  <string>/Applications/Example.app/Contents/MacOS/Helper</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
المفتاحالتأثيرما تراه
RunAtLoadيبدأ المهمة فور تحميلها، أي عند كل تسجيل دخول (للوكلاء) أو بدء تشغيل (للخدمات الخلفية)تجده يعمل بعد كل إعادة تشغيل
KeepAlive = trueيعيد تشغيل العملية كلما انتهتالإنهاء الإجباري لا يجدي؛ يعود خلال ثوانٍ
KeepAlive مع شروطيعيد التشغيل في حالات معينة فقط، مثل بعد التعطل (SuccessfulExit = false) أو ما دامت الشبكة متصلةيعود أحيانًا، لا دائمًا
StartIntervalيعمل كل N ثانيةيظهر، ويعمل لفترة قصيرة، ويختفي، ويتكرر ذلك
StartCalendarIntervalيعمل في أوقات محددة، مثل cronيظهر في الوقت نفسه كل يوم
WatchPathsيعمل عند تغيّر ملف أو مجلديظهر بعد أن تفعل شيئًا لا علاقة له به

ينتظر launchd نحو 10 ثوانٍ بين مرات إعادة تشغيل مهمة تستمر في الانتهاء، لذا قد تبدو مهمة KeepAlive كأنها «تومض».

أسباب أخرى لعودة التطبيق

اعرف أيها السبب

  1. اعثر على معرّف المهمة. نفّذ launchctl list | grep -i example، مستخدمًا جزءًا من اسم التطبيق أو المطوّر. العمود الثالث هو المعرّف.
  2. اقرأ المهمة:
    launchctl print gui/$(id -u)/com.example.helper
    ابحث عن path (ملف plist)، وstate، وruns (عدد مرات بدئها)، وlast exit code. العدد الكبير لمرات التشغيل يعني عادةً KeepAlive.
  3. افتح ملف plist وتحقق من RunAtLoad وKeepAlive ومفاتيح الفترات الزمنية.
  4. إذا لم توجد مهمة، فتحقق من «الفتح عند تسجيل الدخول» ومن إعدادات التطبيق نفسه.

الإيقاف مقابل التعطيل

ما تفعلههل يعود؟
إنهاء العملية أو إنهاؤها إجباريًانعم: فورًا إذا كان KeepAlive، وعند تسجيل الدخول التالي إذا كان RunAtLoad
launchctl bootout gui/$(id -u)/labelليس الآن. نعم عند تسجيل الدخول التالي إذا كان RunAtLoad
launchctl disable gui/$(id -u)/label + bootoutلا، حتى تنفّذ launchctl enable
نقل ملف plist خارج LaunchAgents + bootoutلا، حتى تعيده إلى مكانه
الإيقاف في «السماح في الخلفية»لا، حتى تعيد تشغيله

الأوامر خطوة بخطوة موجودة في كيف تعطّل وكلاء التشغيل بأمان.

الأسئلة الشائعة

لماذا تُعاد عملية للعمل فور إنهائها في «مراقب النشاط»؟

لأن مهمة launchd الخاصة بها مضبوط فيها KeepAlive. يراقب launchd العملية ويشغّلها مجددًا عندما تنتهي. أوقف المهمة باستخدام launchctl bootout بدلًا من إنهاء العملية.

ماذا يعني RunAtLoad؟

RunAtLoad مفتاح في ملف plist الخاص بـ launchd. عندما تكون قيمته true، يبدأ launchd المهمة فور تحميل ملف plist، وهذا يعني بالنسبة إلى وكيل التشغيل: في كل مرة تسجّل فيها الدخول.

ماذا يعني KeepAlive؟

يطلب KeepAlive من launchd إبقاء المهمة قيد التشغيل. إذا انتهت العملية أو قُتلت، يشغّلها launchd مجددًا. ويمكن أن يكون أيضًا مجموعة شروط، مثل إعادة التشغيل بعد التعطل فقط.

ما الفرق بين إيقاف وكيل التشغيل وتعطيله؟

الإيقاف (launchctl bootout) يُلغي تحميل المهمة حتى تسجيل الدخول التالي أو إعادة التشغيل. أما التعطيل (launchctl disable، أو نقل ملف plist خارج LaunchAgents) فيمنع تحميلها مجددًا بعد إعادة التشغيل.