C # - إعادة تشغيل الصراعات التطبيق مع "برنامج التشغيل بالفعل" خطأ

StackOverflow https://stackoverflow.com/questions/1647811

  •  22-07-2019
  •  | 
  •  

سؤال

عند استدعاء الأسلوب Application.Restart ()، ويأتي الخطأ حتى أن يكتشف ما إذا كان التطبيق قيد التشغيل حاليا. هناك على أية حال حول هذا؟

    static void Main(string[] args)
    {
        string proc = Process.GetCurrentProcess().ProcessName;
        Process[] processes = Process.GetProcessesByName(proc);
        if (processes.Length > 1)
        {
            MessageBox.Show("Program is already running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
هل كانت مفيدة؟

المحلول

وأنجع وسيلة لتحقيق ذلك هي أن ترث من <أ href على VB.Net ل= "http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.applicationservices.windowsformsapplicationbase.aspx" يختلط = "نوفولو noreferrer"> WindowsFormsApplicationBase الطبقة، والتي يمكن أن تستخدم أيضا في C #، ووضع في الملكية IsSingleInstance لtrue. هذا يستخدم مزامنة وستواصل العمل إذا تم إعادة تسمية الملف EXE.

نصائح أخرى

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

وكان لي مشكلة مماثلة، ولكن تم المتعلقة بالألغام إلى تسرب الذاكرة لا يمكن السيطرة عليها التي لم أتمكن من العثور على أحد التطبيقات التي لديها لتشغيل 24/7. مع العميل وافقت ذلك الوقت آمنة لإعادة تشغيل التطبيق و03:00 إذا كان استهلاك الذاكرة على قيمة محددة.

وحاولت Application.Restart، ولكن نظرا لأنه يبدو أن استخدام بعض آلية الذي يبدأ مثيل جديد أثناء تشغيله بالفعل، ذهبت لمخطط آخر. لقد استخدمت الحيلة التي لا تزال قائمة مقابض نظام الملفات حتى تموت العملية التي قامت بإنشائها. لذلك، من التطبيق، ط انخفض الملف إلى القرص، ولم Dispose() المقبض. لقد استخدمت ملف لإرسال "نفسي" للتنفيذ وبدء الدليل أيضا (لإضافة المرونة).

والرمز:

_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
    FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
    WorkingDirectory = Application.StartupPath,
    Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();

وClose() في نهاية ستشرع التطبيق الاغلاق، وسيكون التعامل مع ملف استعملتها لStreamWriter هنا تعقد مفتوحة حتى تموت عملية حقا. ثم ...

وRestarter.exe يأتي إلى العمل. كان يحاول قراءة الملف في وضع خاص، ومنعه من الوصول حتى كان التطبيق الرئيسي لم يمت، ثم يبدأ التطبيق الرئيسي، حذف الملفات وجدت. أعتقد أنه لا يمكن أن يكون أكثر بساطة:

static void Main(string[] args)
{
    string filename = args[0];
    DateTime start = DateTime.Now;
    bool done = false;
    while ((DateTime.Now - start).TotalSeconds < 30 && !done)
    {
        try
        {
            StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
            string[] runData = new string[2];
            runData[0] = sr.ReadLine();
            runData[1] = sr.ReadLine();
            Thread.Sleep(1000);
            Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
            sr.Dispose();
            File.Delete(filename);
            done = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Thread.Sleep(1000);
    }
}

وحاول تركيب كود إعادة تشغيل لفي Application.ApplicationExit الحدث كوسيلة المستمع. فإنك سوف ندعو Application.Exit أن يسبب رمز لتشغيل بشكل غير مباشر.

تعديل : لإضافة نموذج التعليمات البرمجية:

وعلى سبيل المثال، عندما يقوم المستخدم بالنقر على زر إعادة التشغيل أو التطبيق تقرر إعادة تشغيل استدعاء هذا الأسلوب RestartMeSmartly (). سوف لا يكون لديك ما يدعو للقلق الخداع - أنها ستعمل

void RestartMeSmartly() {
    Application.ApplicationExit += BeforeExiting;
    Application.Exit();
}

void BeforeExiting(object sender, EventArgs args) {
    Application.Restart();
}

وأبسط طريقة للقيام بذلك هي لإضافة تأخير قبل الإقلاع عن التدخين.

وبعبارة أخرى،

string proc = Process.GetCurrentProcess().ProcessName;
if (Process.GetProcessesByName(proc).Length > 1) {
    Thread.Sleep(500);      //500 milliseconds; you might need to wait longer
    if (Process.GetProcessesByName(proc).Length > 1) {
        MessageBox.Show("Program is already running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
}    //no else
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top