سؤال

ها هي مشكلتي:أحتاج إلى إغلاق عملية قيد التشغيل بالفعل من برنامج C#.المشكلة هي أن العملية تعمل الآن كرمز (تقليل إلى شريط المهام) ، وما لم يفتح المستخدم مرة واحدة على الأقل (والتي لن تحدث أبدًا على الآلات غير المراقبة) ، فلن يكون لها نافذة رئيسية أبدًا.

الشرط الآخر الذي لدي هو أن يكون التطبيق مغلق لا قتل.أحتاجه لكتابة مخازن الذاكرة المؤقتة الخاصة به على القرص - ويؤدي قتله إلى فقدان البيانات.

إليك ما حاولت حتى الآن:

        foreach (Process proc in Process.GetProcesses())
        {
            if (proc.ProcessName.ToLower().StartsWith("myapp"))
            {
                if (proc.MainWindowHandle.ToInt32() != 0)
                {
                    proc.CloseMainWindow();
                    proc.Close();
                    //proc.Kill();  <--- not good!
                }
            }
        }

لقد أضفت لو الشرط، بعد اكتشاف ذلك MainWindowHandle == 0 عندما تم تصغير النافذة.إزالة لو لا يساعد.ولا إغلاقMainWindow() ولا يغلق() عمل.ال قتل() يفعل، ولكن كما ذكر أعلاه - ليس هذا ما أحتاج إليه.

سيتم قبول أي فكرة، بما في ذلك استخدام وظائف Win32 API الغامضة :)

هل كانت مفيدة؟

المحلول 3

وهذه بعض الإجابات والتوضيحات:

com.rpetrich:جربت طريقتك من قبل والمشكلة هي أنني لا أعرف اسم النافذة، فهي تختلف من مستخدم لآخر، ومن إصدار إلى إصدار - فقط اسم exe يظل ثابتًا.كل ما لدي هو اسم العملية.وكما ترون في الكود الموجود أعلى MainWindowHandle للعملية هو 0.

حاضر:نعم، أقصد منطقة إعلام شريط المهام - شكرًا على التوضيح.أنا يحتاج للاتصال بـ PostQuitMessage.أنا لا أعرف كيف، بالنظر إلى العمليات فقط، وليس النافذة.

كريج:يسعدني أن أشرح الموقف:يحتوي التطبيق على واجهة سطر أوامر، مما يسمح لك بتحديد المعلمات التي تملي ما سيفعله وأين سيتم حفظ النتائج.ولكن بمجرد تشغيله، فإن الطريقة الوحيدة لإيقافه والحصول على النتائج هي النقر بزر الماوس الأيمن فوقه في علبة الإشعارات وتحديد "خروج".

الآن يريد المستخدمون كتابة البرنامج النصي/دفعة التطبيق.لم يكن لديهم أي مشكلة على الإطلاق في بدء تشغيله من مجموعة (فقط حدد اسم exe ومجموعة من الأعلام) ولكنهم تعثروا بعد ذلك في عملية قيد التشغيل.بافتراض أنه لن يقوم أحد بتغيير العملية لتوفير واجهة برمجة التطبيقات (API) لإيقافها أثناء التشغيل (إنها قديمة جدًا)، فأنا بحاجة إلى طريقة لإغلاقها بشكل مصطنع.

وبالمثل، على أجهزة الكمبيوتر غير المراقبة، يمكن بدء البرنامج النصي لبدء العملية عن طريق جدولة المهام أو برنامج التحكم في العمليات، ولكن لا توجد طريقة لإيقاف العملية.

آمل أن يوضح ذلك وضعي، ومرة ​​أخرى، أشكر كل من يحاول المساعدة!

نصائح أخرى

يجب أن يعمل هذا:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

private const int WM_CLOSE = 0x10;
private const int WM_QUIT = 0x12;

public void SearchAndDestroy(string windowName) 
{
    IntPtr hWnd = FindWindow(null, windowName);
    if (hWnd == IntPtr.Zero)
        throw new Exception("Couldn't find window!");
    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}

لأن بعض النوافذ لا تستجيب WM_CLOSE, WM_QUIT قد يتعين إرسالها بدلاً من ذلك.يجب أن تعمل هذه الإعلانات على كل من 32 بت و64 بت.

إذا كان موجودًا على شريط المهام، فستحتوي على نافذة.أم أنك تقصد أنه موجود في منطقة الإعلام بشريط المهام (المعروف أيضًا باسم SysTray)؟في هذه الحالة، ستظل تحتوي على نافذة.

لا تحتوي تطبيقات Win32 على "نافذة رئيسية" حقًا، إلا حسب التقليد (النافذة الرئيسية هي التي تستدعي PostQuitMessage استجابةً لـ WM_DESTROY، مما يتسبب في إنهاء حلقة الرسالة).

أثناء تشغيل البرنامج، قم بتشغيل Spy++.للعثور على جميع النوافذ المملوكة لعملية ما، يجب عليك تحديد Spy -> Processes من القائمة الرئيسية.سيعرض هذا شجرة العمليات.ومن هناك، يمكنك الانتقال إلى المواضيع، ثم إلى النوافذ.سيخبرك هذا بالنوافذ التي تحتوي عليها العملية.قم بتدوين فئة النافذة والتسمية التوضيحية.باستخدام هذه العناصر، يمكنك استخدام FindWindow (أو EnumWindows) للعثور على مقبض النافذة في المستقبل.

باستخدام مقبض النافذة، يمكنك إرسال رسالة WM_CLOSE أو WM_SYSCOMMAND/SC_CLOSE (أي ما يعادل النقر فوق علامة "X" في التسمية التوضيحية للنافذة).يجب أن يتسبب هذا في إيقاف تشغيل البرنامج بشكل جيد.

لاحظ أنني أتحدث من وجهة نظر Win32 هنا.قد تحتاج إلى استخدام P/Invoc أو حيل أخرى لجعل هذا يعمل من خلال برنامج .NET.

سؤال لتوضيح سبب محاولتك ذلك:إذا كانت واجهة المستخدم الوحيدة في العملية هي رمز علبة النظام، فلماذا تريد إيقاف ذلك مع ترك العملية قيد التشغيل؟كيف يمكن للمستخدم الوصول إلى العملية؟وإذا كان الجهاز "غير مراقب"، فلماذا تهتم بأيقونة الدرج؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top