मुझे स्वयं को पुनः आरंभ करने के लिए विंडोज़ सेवा (सर्वर 2003) को सक्षम करने के लिए .NET में मजबूत कोड लिखने की आवश्यकता है। इसका सबसे अच्छा तरीका क्या है? क्या ऐसा करने के लिए कुछ .NET एपीआई है?
मुझे स्वयं को पुनः आरंभ करने के लिए विंडोज़ सेवा (सर्वर 2003) को सक्षम करने के लिए .NET में मजबूत कोड लिखने की आवश्यकता है। इसका सबसे अच्छा तरीका क्या है? क्या ऐसा करने के लिए कुछ .NET एपीआई है?
जवाबों:
विफलता के बाद सेवा को पुनरारंभ करने के लिए सेट करें (नियंत्रण पैनल में सेवा पर डबल क्लिक करें और उन टैब पर चारों ओर एक नज़र डालें - मैं इसका नाम भूल जाता हूं)। फिर, कभी भी आप सेवा को पुनः आरंभ करना चाहते हैं, बस कॉल करें Environment.Exit(1)
(या कोई गैर-शून्य रिटर्न) और OS आपके लिए इसे पुनः आरंभ करेगा।
Service.ExitCode = 1
और फिर Service.Stop()
चेकबॉक्स को सक्षम करने के साथ-साथ सर्विस रिकवरी सेटिंग स्क्रीन पर त्रुटियों के साथ स्टॉप के लिए कार्रवाई सक्षम करें ’। इस तरह से करना एक उचित शटडाउन की अनुमति देता है और फिर भी पुनरारंभ को चालू करता है।
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()
आप यह सुनिश्चित नहीं कर सकते हैं कि आपकी सेवा जिस उपयोगकर्ता खाते के तहत चल रही है, उसके पास सेवा को रोकने और पुनः आरंभ करने की अनुमति भी है।
आप एक प्रक्रिया बना सकते हैं जो एक डॉस कमांड प्रॉम्प्ट है जो खुद को पुनरारंभ करता है:
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
आपकी सेवा का नाम है (सेवा नाम में रिक्त स्थान के लिए शामिल किए गए दोहरे उद्धरण, अन्यथा अन्यथा छोड़े जा सकते हैं)।
स्वच्छ, कोई ऑटो-पुनरारंभ कॉन्फ़िगरेशन आवश्यक नहीं है।
यह इस बात पर निर्भर करेगा कि आप यह क्यों स्वयं को पुनः आरंभ करना चाहते हैं।
यदि आप समय-समय पर सेवा को स्वयं साफ करने का तरीका ढूंढ रहे हैं, तो आप सेवा में एक टाइमर चला सकते हैं जो समय-समय पर एक शुद्ध दिनचर्या का कारण बनता है।
यदि आप विफलता पर पुनः आरंभ करने का एक तरीका ढूंढ रहे हैं - सेवा होस्ट स्वयं सेटअप होने पर वह क्षमता प्रदान कर सकता है।
तो आपको सर्वर को पुनरारंभ करने की आवश्यकता क्यों है? आप क्या हासिल करने का प्रयास कर रहे हैं?
मुझे नहीं लगता कि आप एक स्व-निहित सेवा में हो सकते हैं (जब आप रिस्टार्ट कहते हैं, तो यह सेवा को रोक देगा, जो रीस्टार्ट कमांड को बाधित करेगा, और यह फिर से शुरू नहीं होगा)। यदि आप एक दूसरा .exe (एक कंसोल ऐप जो ServiceManager वर्ग का उपयोग करता है) जोड़ सकते हैं, तो आप स्टैंडअलोन .exe को बंद कर सकते हैं और सेवा को पुनरारंभ कर सकते हैं और फिर बाहर निकल सकते हैं।
दूसरे विचार पर, शायद आप सेवा शुरू करने के लिए सेवा को एक अनुसूचित कार्य (कमांड-लाइन का उपयोग करके 'कमांड, उदाहरण के लिए) रजिस्टर कर सकते हैं और फिर इसे स्वयं रोक सकते हैं; वह शायद काम करेगा।
एक बैच फ़ाइल या EXE के लिए शेलिंग के साथ समस्या यह है कि किसी सेवा में बाहरी ऐप को चलाने के लिए आवश्यक अनुमतियाँ हो सकती हैं या नहीं भी हो सकती हैं।
ऐसा करने का सबसे साफ तरीका जो मुझे मिला है वह है ऑनस्टॉप () पद्धति का उपयोग करना, जो सेवा नियंत्रण प्रबंधक के लिए प्रवेश बिंदु है। फिर आपका सभी सफाई कोड चलेगा, और आपके पास कोई भी लटकाने वाला सॉकेट या अन्य प्रक्रिया नहीं होगी, यह मानते हुए कि आपका स्टॉप कोड अपना काम कर रहा है।
ऐसा करने के लिए आपको समाप्त करने से पहले एक ध्वज सेट करने की आवश्यकता होती है जो त्रुटि कोड के साथ बाहर निकलने के लिए 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) { }
}
मैं आपकी सेवा को पुनः आरंभ करने के लिए Windows समयबद्धक का उपयोग करूंगा। समस्या यह है कि आप स्वयं को पुनः आरंभ नहीं कर सकते, लेकिन आप स्वयं को रोक सकते हैं। (आप अनिवार्य रूप से उस शाखा को देख चुके हैं, जिस पर आप बैठे हैं ... यदि आपको मेरी उपमा मिल गई है) तो आपको इसे करने के लिए एक अलग प्रक्रिया की आवश्यकता है। विंडोज शेड्यूलर एक उपयुक्त है। तुरंत निष्पादित करने के लिए अपनी सेवा (यहां तक कि स्वयं सेवा के भीतर से) को पुनरारंभ करने के लिए एक बार के कार्य को शेड्यूल करें।
अन्यथा, आपको एक "चरवाहा" प्रक्रिया बनानी होगी जो इसे आपके लिए करती है।
प्रश्न का पहला उत्तर सबसे सरल समाधान है: "पर्यावरण। एक्सिट (1)" मैं इसका उपयोग विंडोज सर्वर 2008 R2 पर कर रहा हूं और यह पूरी तरह से काम करता है। सेवा स्वयं बंद हो जाती है, ओ / एस 1 मिनट इंतजार करता है, फिर इसे पुनरारंभ करता है।
बेहतर तरीका यह हो सकता है कि आप एनटी सेवा का उपयोग अपने आवेदन के लिए एक आवरण के रूप में कर सकते हैं। जब NT सेवा शुरू की जाती है, तो आपका एप्लिकेशन एक "निष्क्रिय" मोड में शुरू हो सकता है जो कमांड के शुरू होने की प्रतीक्षा कर रहा है (या स्वचालित रूप से शुरू करने के लिए कॉन्फ़िगर किया जा सकता है)।
एक कार के बारे में सोचो, जब यह शुरू होता है तो यह एक निष्क्रिय स्थिति में शुरू होता है, आपके आदेश के आगे या रिवर्स होने की प्रतीक्षा करता है। यह अन्य लाभों के लिए भी अनुमति देता है, जैसे कि बेहतर दूरस्थ प्रशासन, जैसा कि आप चुन सकते हैं कि अपने आवेदन को कैसे उजागर किया जाए।
बस गुजर रहा है: और सोचा कि मैं कुछ अतिरिक्त जानकारी जोड़ूंगा ...
आप एक अपवाद भी फेंक सकते हैं, यह विंडोज़ सेवा को बंद कर देगा, और ऑटो री-स्टार्ट विकल्प सिर्फ किक करेंगे। इसके साथ एकमात्र मुद्दा यह है कि यदि आपके पीसी पर एक देव एनवायरमेंट है तो जेआईटी को किक करने की कोशिश करता है। और आपको डिबग Y / N कहने का संकेत मिलेगा। नहीं, और तब यह बंद हो जाएगा, और फिर ठीक से फिर से शुरू होगा। (बिना किसी JIT वाले पीसी पर यह सब काम करता है)। कारण im im trolling, क्या यह JIT विन 7 के लिए नया है (यह XP आदि के साथ ठीक काम करता था) और im JIT को अक्षम करने का एक तरीका खोजने की कोशिश कर रहा है .... मैं यहां पर्यावरण की कोशिश कर सकता हूं। इस विधि का उल्लेख यहां देखें वह भी काम करता है।
क्रिस्टियन: ब्रिस्टल, यूके
इस तरह एक रिस्टार्ट।बैट फाइल बनाएं
@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% हटाएं
एप्लिकेशन कोड को होस्ट करने के लिए एक अलग एपडोमेन बनाएं। जब पुनरारंभ की आवश्यकता होती है, तो हम प्रक्रिया (विंडोज़ सेवा) के बजाय एपडोमेन को अनलोड और लोड कर सकते हैं। यह है कि IIS ऐप पूल कैसे काम करता है, वे सीधे asp.net ऐप नहीं चलाते हैं, वे अलग-अलग ऐपमैन का उपयोग करते हैं।
सबसे आसान तरीका एक बैच फ़ाइल है:
नेट स्टॉप नेट स्टार्ट
और अपने इच्छित समय अंतराल के साथ अनुसूचक में फ़ाइल जोड़ें
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();
}
}