سؤال

وأحتاج لكتابة رمز قوي في .NET لتمكين خدمة ويندوز (خادم 2003) إعادة تشغيل نفسه. ما هي أفضل طريقة لذلك هذا؟ هناك بعض API. NET للقيام بذلك؟

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

المحلول

وتعيين خدمة إعادة تشغيل بعد فشل (انقر نقرا مزدوجا فوق الخدمة في لوحة التحكم وإلقاء نظرة حول على تلك علامات التبويب - أنسى اسم منه). ثم، في أي وقت تريد الخدمة لإعادة تشغيل، ما عليك سوى الاتصال Environment.Exit(1) (أو أي غير صفر العودة) وسوف OS إعادة تشغيله بالنسبة لك.

نصائح أخرى

Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()

ولا يمكنك أن تكون على يقين من أن حساب المستخدم الذي الخدمة الخاص بك يعمل تحت حتى لديه أذونات للتوقف وإعادة تشغيل الخدمة.

ويمكنك إنشاء عملية هو أمر موجه DOS أن إعادة تشغيل نفسك:

 Process process = new Process();
 process.StartInfo.FileName = "cmd";
 process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\"";
 process.Start();
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);

وحيث SERVICENAME هو اسم الخدمة (التنصيص شملت لحساب المسافات في اسم الخدمة، يمكن حذف خلاف ذلك).

والنظيفة، أي تكوين إعادة التشغيل التلقائي لزم الأمر.

والامر يتوقف على ماذا تريد أن إعادة تشغيل نفسه.

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

إذا كنت تبحث عن وسيلة لإعادة على فشل - المضيف الخدمة نفسها يمكن أن توفر هذه القدرة عندما يكون الإعداد

وهكذا لماذا تحتاج إلى إعادة تشغيل الخادم؟ ماذا تحاول تحقيقه؟

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

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

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

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

لذلك تحتاج إلى تعيين إشارة قبل إنهاء الذي يروي طريقة OnStop للخروج مع رمز الخطأ. ثم SCM يعرف أن الخدمة تحتاج إلى إعادة التشغيل. من دون هذا العلم أنك لن تكون قادرا على إيقاف الخدمة يدويا من SCM. وهذا يفترض أيضا قمت بإعداد الخدمة لإعادة تشغيل على خطأ.

إليك يا رمز الإيقاف:

...

bool ABORT;

protected override void OnStop()
{
    Logger.log("Stopping service");
    WorkThreadRun = false;
    WorkThread.Join();
    Logger.stop();
    // if there was a problem, set an exit error code
    // so the service manager will restart this
    if(ABORT)Environment.Exit(1);
}

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

...

if(NeedToRestart)
{
    ABORT = true;
    new Thread(RestartThread).Start();
}

void RestartThread()
{
    ServiceController sc = new ServiceController(ServiceName);
    try
    {
        sc.Stop();
    }
    catch (Exception) { }
}

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

وعلى خلاف ذلك، سيكون لديك لإنشاء "يرعى" العملية التي يقوم بذلك نيابة عنك.

وأنا لا أعتقد أنه يمكن. عندما الخدمة "توقف"، فإنه يحصل على تفرغ تماما.

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

وهذا أول رد على سؤال هو أبسط الحلول: "Environment.Exit (1)" أنا أستخدم هذا على Windows Server 2008 R2 وأنها تعمل تماما. خدمة توقف نفسها، وO / S ينتظر 1 دقيقة، ثم إعادة ذلك.

وإنشاء appdomain منفصل لاستضافة رمز التطبيق. عندما يتطلب إعادة التشغيل، فإننا لا يمكن تفريغ وإعادة تحميل في AppDomain بدلا عملية (خدمة ويندوز). هذه هي الطريقة التي يعمل IIS تجمع التطبيقات، فإنها لا التطبيق asp.net تشغيل مباشرة، فإنها تستخدم appdmain منفصلة.

قد يكون طريقة أفضل للاستفادة من خدمة NT كما مجمع للتطبيق الخاص بك. عند بدء تشغيل خدمة NT، التطبيق الخاص بك يمكن البدء في وضع "الخمول" في انتظار الأوامر لبدء (أو يتم تكوين لبدء تلقائيا).

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

ومجرد مرور: ووالفكر أود أن أضيف بعض المعلومات الاضافية ...

ويمكنك أيضا بطرح استثناء، هذه الإرادة السيارات تغلق خدمة ويندوز، والسيارات خيارات إعادة بدء مجرد ركلة. المسألة الوحيدة مع ذلك هو أنه إذا كان لديك بيئة ديف على جهاز الكمبيوتر الخاص بك، ثم يحاول أن JIT ركلة، وسوف تحصل على وجه السرعة قائلا التصحيح Y / N. نقول لا وبعد ذلك سيتم إغلاق، ومن ثم إعادة بدء التشغيل بشكل صحيح. (على جهاز الكمبيوتر مع أي JIT أنها مجرد جميع الأعمال). والتصيد الدردشة السبب، وهذا هو JIT هو جديد على الفوز 7 (كان عليه أن تعمل بشكل جيد مع XP الخ) وايم محاولة لايجاد وسيلة لتعطيل JIT .... أنا قد حاول الأسلوب Environment.Exit المذكورة هنا نرى كيف الذي يعمل أيضا.

وكريستيان: بريستول، المملكة المتحدة

وإنشاء ملف restart.bat مثل هذا

@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%

schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%

وثم حذف المهمة٪ taskname٪ عندما الخاص بك خدمة٪٪ يبدأ

وقضية التوقيع كبيرة جدا. انها لن تفعل كل هذا بالنسبة لك

وأسهل طريقة هي أن يكون ملف دفعي مع:

وتوقف الشبكة صافي بداية

وإضافة الملف إلى جدولة مع الخاص بك الفاصل الزمني المطلوب

private static void  RestartService(string serviceName)
    {
        using (var controller = new ServiceController(serviceName))
        {
            controller.Stop();
            int counter = 0;
            while (controller.Status != ServiceControllerStatus.Stopped)
            {
                Thread.Sleep(100);
                controller.Refresh();
                counter++;
                if (counter > 1000)
                {
                    throw new System.TimeoutException(string.Format("Could not stop service: {0}", Constants.Series6Service.WindowsServiceName));
                }
            }

            controller.Start();
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top