2009-03-04 7 views
8

मेरे पास डेल्फी में एक सेवा अनुप्रयोग है जो बहुत अच्छा काम करता है। यह वही करता है जो मैं चाहता हूं और सब खुश हैं। सब ठीक है जब तक कि मैं एक ही मशीन पर उस सेवा के दो (या अधिक) उदाहरण नहीं चलाता। चूंकि सेवा का नाम प्रोग्राम में (कोड की नाम संपत्ति के माध्यम से) कोड किया गया है, इसलिए मैं किसी भी दिए गए कंप्यूटर पर केवल एक बार सेवा स्थापित कर सकता हूं। यदि मैं रन-टाइम पर नाम संपत्ति को संशोधित करने का प्रयास करता हूं, तो सेवा तब तक प्रतिक्रिया नहीं देती जब तक कि नाम संपत्ति उसी समय पर सेट न हो जो डिज़ाइन समय के दौरान सेट की गई हो।क्या उसी डेल्फी सेवा एप्लिकेशन के कई उदाहरण स्थापित करना संभव है?

मैं इस जहाँ मैं कोड है कि सेवा नियंत्रण प्रबंधक के साथ सीधे बातचीत नहीं अलग इकाई (रों) में बाहर समझाया के सभी के लिए एक समाधान किया है। फिर मैं प्रत्येक उदाहरण के लिए एक अलग डेल्फी प्रोजेक्ट लिखता हूं जिसे मैं उस सेवा की चाहता हूं जिसमें स्वयं को लॉन्च करने के लिए पर्याप्त कोड है और मुख्य कोड चलाने शुरू करें।

इस विधि मेरी राय में, है, बदसूरत और निश्चित रूप से अक्षम है। यह दो उदाहरणों के लिए ठीक काम करता है, लेकिन फिर हमें तीसरे और चौथे की आवश्यकता होती है और ...

क्या कोई तरीका है कि मैं अपना कोड संशोधित कर सकता हूं ताकि मेरे पास केवल एक डेल्फी प्रोजेक्ट है जो कई को अपने आप इंस्टॉल और चला सकता है कुछ सरल रन-टाइम इनपुट (उदाहरण के लिए कमांड लाइन ध्वज) के साथ सेवा उदाहरण?

या शायद एक व्यापक प्रश्न: वहाँ एक "सही तरीके से" लक्ष्य को पूरा करने के लिए है?

उत्तर

13

आपने यह स्पष्ट नहीं किया है कि आपने TService उपclass में बदलने की कोशिश की है।

क्या आपने "पहले इंस्टॉल" हैंडलर जोड़ा है?

कुछ की तरह:

procedure TServiceMain.ServiceLoadInfo(Sender : TObject);// new method, not an override 
begin 
    Name := ParamStr(2); 
    DisplayName := ParamStr(3); 
end; 

procedure TServiceMain.ServiceBeforeInstall(Sender: TService); 
begin 
    ServiceLoadInfo(Self); 
end; 
procedure TServiceMain.ServiceCreate(Sender: TObject); 
begin 
    ServiceLoadInfo(Self); 
end; 

आप इस नियमित रूप से करते हैं, उपवर्ग TService thie निर्माता में बजाय क्या करना है।

साथ ही आप BeforeUninstall में भी ऐसा ही करना चाहिए - एक ही विधि में दोनों घटनाओं इशारा करते हैं।

C:\>servicename /install MyService "My Service Description" 
+0

यदि मैं ऐसा करता हूं, तो सेवा तब तक नहीं चलती जब तक कि ParamStr (2) आईडीई में ऑब्जेक्ट इंस्पेक्टर में नाम के लिए सेट किए गए मान के बराबर न हो। यदि ParamStr (2) अलग है, तो जब सेवा शुरू हो जाती है, तो यह एक सतत "प्रारंभ" स्थिति में जाती है और कभी निष्पादित नहीं होती है। –

+0

क्षमा करें, यह आवश्यक चीज़ों का केवल एक हिस्सा है। इसे कॉल करने के लिए आपको ऑनस्टार्ट ईवेंट की भी आवश्यकता है। (यहां मेमोरी से काम करना!) –

+0

मुझे यह सेवा लोडोडइन्फो विधि नहीं मिल रही है जिसका आप उपयोग कर रहे हैं। क्या यह एक मानक विधि है, या सिर्फ एक सुझाव लिखने का सुझाव है जो इस उदाहरण में कहलाता है कि इसका नाम क्या है? –

3

आप आंतरिक रूप से एक से अधिक थ्रेड के साथ अपनी सेवा, हर एक की तरह सेवा की उसके अपने संस्करण/कॉपी अभिनय बना सकते हैं। आप इसे सेवा नियंत्रक एपीआई, आईआईआरसी के साथ नियंत्रित करते हैं।

+0

मैंने इस बारे में सोचा, लेकिन ऐसा लगता है कि यह मूल रूप से डुप्लिकेट कोड बना रहा था। विंडोज़ की सेवाओं की सुविधाओं में पहले से ही थ्रेड कंट्रोलिंग कोड अंतर्निहित है। मेरा खुद को घुमाने के बजाय लीवरेज क्यों नहीं? –

+0

नहीं, यह वही नहीं है जो मैं कह रहा हूं। एकाधिक धागे को शुरू/बंद करने के लिए आपके पास Windows के लिए सेवा नियंत्रक कोड है। अपने सर्विस कोड को टीटीएचड में ले जाएं, और आपकी सेवा के प्रत्येक इंस्टेंस के लिए बस एक और थ्रेड शुरू करें। बेहतर स्पष्टीकरण, मुझे उम्मीद है कि मैं क्या चाहता हूं। –

+0

मुझे खेद है, मुझे अभी भी नहीं लगता कि मैं समझता हूं। यह सेवा नियंत्रण कक्ष (एक प्रविष्टि/एकाधिक) में कैसे दिखाई देता है? क्या आप सुझाव दे रहे हैं कि मैं अपने कोड के भीतर सेवा नियंत्रण API का उपयोग करता हूं (उदा। कॉल कंट्रोल सेवा) या केवल ईवेंट को संभालें (जैसे सर्विस स्टार्ट, इत्यादि)? –

2

खैर हाँ यह एक ही सेवा के कई उदाहरण स्थापित करने के लिए संभव है, तो आप बस गतिशील समय स्थापित पर नाम (क्रम नहीं) लेकिन इस यह वांछनीय नहीं है को बदलने की जरूरत। (कोड प्रोजेक्ट http://www.codeproject.com/KB/dotnet/MultipleInstNetWinService.aspx पर कुछ नमूना कोड है)

हालांकि मैं आपके दृष्टिकोण पर पुनर्विचार करने के इच्छुक हूं, सेवा प्रक्रियाओं को वास्तव में सिंगलटन होने का मतलब है, यदि आपको किसी प्रक्रिया के चलने के कई उदाहरणों की आवश्यकता है, तो शायद आपकी सेवा बस प्रक्रिया के बजाय कई प्रक्रियाओं को नियंत्रित और प्रबंधित करें।

+0

धन्यवाद, लेकिन मुझे यकीन नहीं है कि यह डेल्फी पर लागू होता है। यही वह है जो मैंने करने की कोशिश की - इंस्टॉलेशन ईवेंट के दौरान प्रदर्शन नाम बदलें - लेकिन तब सेवा को दबाया गया जब उसने "गलत" नाम से शुरू करने का प्रयास किया। –

+0

इसके अलावा, कृपया केन के उत्तर पर मेरी टिप्पणी देखें ... बहु-थ्रेडेड नियंत्रक प्रकार की सेवा नहीं कर रही है जब मैं विंडोज़ पहले से ही नियंत्रक भाग कर सकता हूं तो अनावश्यक रूप से अपना खुद का रोलिंग कर रहा हूं? –

+0

केन की सलाह का पालन करें। आप जो करने का प्रयास कर रहे हैं वह खराब डिजाइन का एक उदाहरण है। क्या आप इसे काम पर ला सकते हैं? ज़रूर। अगर आप? नहीं, अगर आपको संसाधनों को सही तरीके से करने के लिए नहीं मिला है (और यह केवल कुछ बंद नहीं है)। – Mick

0

लपेटें एक वर्ग है कि TThread से विरासत में अपने कोड के सभी।

जब आपकी सेवा शुरू होती है तो यह सेटिंग फ़ाइल से या रजिस्ट्री से एक संख्या पढ़ेगी और आपकी कक्षा के कई उदाहरण बनाएगी।

प्रत्येक इंस्टेंस स्वतंत्र रूप से चलता है।

चल रहे उदाहरणों की संख्या बदलने के लिए आप सेवा बंद कर सकते हैं, सेटिंग संपादित कर सकते हैं (फ़ाइल या रजिस्ट्री में) और सेवा को पुनरारंभ करें।

+0

ऐसे सेटअप के साथ, मान लीजिए कि मैं तीन धागे के साथ सेवा शुरू करता हूं। क्या मैं थ्रेड 3 को रोक सकता हूं, थ्रेड 3 और 1 चल रहा हूं (सेवा नियंत्रक को प्रभावी रूप से फिर से बनाने के लिए कोड का एक समूह लिखने के बिना)? –

+0

सुझाव के साथ मैंने बनाया, हाँ। आपका मुख्य धागा बाल धागे को शुरू करने और रोकने के अनुरोधों को संभाल लेगा; वे बच्चे धागे वास्तविक काम कर रहे होंगे। आप सर्विस कंट्रोल एपीआई के साथ सेवा के मुख्य थ्रेड के साथ संवाद करेंगे। (जैसा कि मैंने आपके उत्तर के नीचे आपकी टिप्पणी में उल्लेख किया है।) –

0

ऊपर स्वीकृत उत्तर बहुत उपयोगी था।

कोड मैं प्रयोग किया है:

procedure TService1.ServiceAfterInstall(Sender: TService); 
begin 
//http://stackoverflow.com/questions/612587/is-it-possible-to-install-multiple-instances-of-the-same-delphi-service-applicati 
//http://www.c-sharpcorner.com/UploadFile/timosten/DynamicServiceInCSharp11262005062503AM/DynamicServiceInCSharp.aspx?ArticleID=4d5020e4-7317-425c-ab29-5bf37a1db421 
//http://support.microsoft.com/kb/137890 
    SaveRegSetting('\SYSTEM\CurrentControlSet\Services\' + Name, 'ImagePath', ParamStr(0) + ' --name=' + Name, HKEY_LOCAL_MACHINE) 
end; 

procedure TService1.ServiceCreate(Sender: TObject); 
begin 
    Name := Trim(FCommandLineOptions.Values['name']); 
    DisplayName := Name; 
end; 

SaveRegSetting अपने ही प्रक्रिया है और FCommandLineOptions एक वस्तु है कि आदेश पंक्ति पैरामीटर tokenises है।

संबंधित मुद्दे

 संबंधित मुद्दे