2008-11-20 17 views
20

मैं सी # में एक विंडोज सेवा लिखने का प्रयास कर रहा हूं। मुझे एक निश्चित फ़ाइल के पथ को खोजने की ज़रूरत है, जो पर्यावरण चर में संग्रहीत है। एक नियमित रूप से सी # कंसोल आवेदन में, मैं निम्न पंक्ति के साथ कि प्राप्त कर सकते हैं:विंडोज सेवाओं से पर्यावरण चर का उपयोग

string t = System.Environment.GetEnvironmentVariable("TIP_HOME"); 

अगर मैं लिखना कि कंसोल के लिए मुझे लगता है कि यह सफल रहा था।

अब, यदि मैं एक ही कोड को विंडोज सेवा में कोशिश करता हूं, तो स्ट्रिंग t खाली है।

कोई विचार क्यों?

उत्तर

6

सेवा शायद एक अलग खाते के तहत चल रही है और एक ही पर्यावरण चर नहीं मिल रही है।

+0

मुझे लगता है कि मुझे यह स्पष्ट करना चाहिए था, लेकिन TIP_HOME एक सिस्टम चर है। मैंने सोचा कि सिस्टम चर उपयोगकर्ता-विशिष्ट नहीं थे? – Brian

+0

ठीक है, एक परीक्षण के रूप में आप अपनी सेवा में डीबगिंग कोड जोड़ सकते हैं ताकि इसे सभी पर्यावरण वार्स के माध्यम से स्टार्टअप पर देखा जा सके और उन्हें एक अस्थायी फ़ाइल में आउटपुट किया जा सके। – EBGreen

0

क्या आप सिस्टम और उपयोगकर्ता पर्यावरण चर के बारे में जानते हैं? एक विंडोज सेवा, डिफ़ॉल्ट रूप से, सिस्टम खाते के तहत चलाती है।

+0

हां, वेरिएबल जो मैं देख रहा हूं वह एक सिस्टम चर है। मैंने नीचे पोस्ट किया गया उत्तर देखें। – Brian

0

मैं इस के लिए कोड की है कि लाइन संशोधित:

स्ट्रिंग टी = System.Environment.GetEnvironmentVariable ("TIP_HOME", EnvironmentVariableTarget.Machine);

मैं अपनी रजिस्ट्री को देख सकता हूं और देख सकता हूं कि TIP_HOME सेट है।

यह एमएसडीएन से है: मशीन: पर्यावरण चर को विंडोज ऑपरेटिंग सिस्टम रजिस्ट्री में HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ सत्र प्रबंधक \ पर्यावरण कुंजी से संग्रहीत या पुनर्प्राप्त किया जाता है।

उपयोगकर्ता चर रजिस्ट्री में कहीं और जमा हो जाती है ..

स्ट्रिंग अभी भी खाली दिखा रहा है, हालांकि जब मैं इस परिवर्तन के साथ सेवा चलाते हैं।

+0

क्या आपने सुझाव दिया था कि env vars की गणना करने का प्रयास करें? – EBGreen

+0

मैं यह पता लगाने की कोशिश कर रहा हूं कि कैसे .. मैं सी # के लिए बहुत नया हूं, और इसे सिर्फ एक छोटी परियोजना के लिए इसकी आवश्यकता है। – Brian

18

आपकी समस्या ऐसा कुछ प्रतीत होता है जैसा हमने अनुभव किया है और यह पता लगाने में बहुत मुश्किल हो सकती है कि क्या हो रहा है।

क्या होता है जब पर्यावरण चर जोड़े/हटाए/बदले जाते हैं, सेवा वातावरण इसे "पुनरारंभ" तक नहीं पहचानता है। ऐसा इसलिए है क्योंकि इन पर्यावरण चर रजिस्ट्री में संग्रहीत हैं और यह रजिस्ट्री सेवा वातावरण द्वारा केवल पढ़ने के बाद ... सिस्टम स्टार्टअप पर पढ़ी गई है।

इसका मतलब है कि एक सेवा के लिए पर्यावरण चर में बदलाव लेने के लिए, एक सिस्टम पुनरारंभ करने की आवश्यकता है।

इस पर Microsoft KB देखें।

+3

लेकिन ध्यान दें कि यह स्थानीय सिस्टम खाते के अंतर्गत चल रही सेवाओं के लिए केवल सत्य है। निर्दिष्ट उपयोगकर्ता खाते के अंतर्गत चलने वाली सेवाओं के लिए, वे * पुनरारंभ करने के बाद रजिस्ट्री से पर्यावरण परिवर्तन उठाएंगे। –

+1

@ मार्टिन - मुझे यह नहीं पता था। महान बिंदु! –

1

ठीक है, मैं काफी इस बात को समझ नहीं है, लेकिन यहाँ मैं क्या पाया है है ..

एक ही सेवा में, मैं पहली बार है कि मैं क्या पहले वर्णित कोशिश करते हैं और स्ट्रिंग खाली देता है।

फिर, यदि मैं प्रत्येक सिस्टम-स्तरीय पर्यावरण चर के माध्यम से गणना करता हूं, तो यह वैरिएबल पाता है जो मैं ठीक से ढूंढ रहा हूं।

foreach(DictionaryEntry de in Environment.GetEnvironmentVariables(tgt)) 
{ 
    key = (string)de.Key; 
    value = (string)de.Value; 

    if(key.Equals("TIP_HOME") && value != null) 
     log.WriteEntry("TIP_HOME="+value, EventLogEntryType.Information); 
} 
1

आप स्थानीय सिस्टम खाते के अंतर्गत सेवा चला रहे हैं:

कोड स्निपेट, थोड़ा MSDN पर पाया कुछ नमूना कोड से संशोधित किया गया है?

क्या आपने TIP_HOME चर जोड़ने के बाद मशीन को पुनरारंभ किया है?

सेवा स्थानीय सिस्टम के तहत चल रहा services.exe सेवा है, जो केवल अपने पर्यावरण पढ़ता है जब यह शुरू होता है से आरंभ करने के लिए: http://support.microsoft.com/kb/821761

+0

हां, सिस्टम चर सेट होने के बाद मशीन को पुनरारंभ किया गया है। मैं व्यवस्थापक खाते के तहत सेवा बना रहा हूं और लॉन्च कर रहा हूं। – Brian

1

इस कोड स्ट्रिंग getsyspath = System.Environment.GetEnvironmentVariable ("TIP_HOME" कोशिश, EnvironmentVariableTarget.Machine);

28

मुझे नहीं पता कि यह उपयोगी है, लेकिन मुझे पता चला है कि प्रत्येक सेवा के लिए, पर्यावरण चर को सीधे सेवा में जोड़ने का विकल्प होता है।

यह रजिस्ट्री के माध्यम से किया जाता है।

मान लें कि आपका सेवा के लिए महत्वपूर्ण है ...

HKLM \ SYSTEM \ CurrentControlSet \ Services \ YourService

एक REG_MULTI_SZ पर्यावरण बुलाया बनाएँ।

अब आप की तरह प्रविष्टियों में जोड़ सकते हैं ...

Var1=Value1 
Var2=Value2 

और इन सेवा कोड के लिए उपलब्ध हो जाएगा।

यदि आप एक सेवा (instsrv.exe और srvany.exe) के रूप में स्क्रिप्ट स्थापित करने के लिए Windows संसाधन टूलकिट का उपयोग कर रहे हैं, तो फिर, आपके पास सेवा के लिए पर्यावरण चर सेट करने का विकल्प है, लेकिन संभवतः यह है गलत है क्योंकि यह srvany.exe के लिए होगा।

इसके बजाय, आप कुंजी ...

HKLM \ SYSTEM \ CurrentControlSet \ Services \ YourService \ पैरामीटर

का उपयोग करें और एक REG_MULTI_SZ उसी तरह से प्रविष्टियों सेट AppEnvironment

बुलाया पैदा करते हैं।

और अब आपकी स्क्रिप्ट सेवा के अपने पर्यावरण चर हैं।

मैं इन तकनीकों का उपयोग PHP + WinCache के साथ कर रहा हूं ताकि मुझे प्रत्येक सेवा के लिए एक APP_POOL_ID अद्वितीय सेट किया जा सके जो WinCache को सभी "थ्रेड" के लिए केंद्रीय कैश (APP_POOL_ID पर आधारित) साझा करने की अनुमति देता है (WShell का उपयोग गैर- बच्चे को "धागे" को अवरुद्ध करना और अभी भी वही WinCache लॉन्चर के रूप में साझा करना, सरल, अंतर-प्रक्रिया संचार की अनुमति देना)।

वैसे भी। मुझे उम्मीद है कि यह कुछ हद तक मदद करता है।

मुझे लगता है कि, मुख्य रूप से, आप वैश्विक वातावरण में अनावश्यक env_vars नहीं जोड़ रहे हैं। आप उन्हें लक्षित और अद्वितीय आप एक से अधिक 1.

सादर,

रिचर्ड जब रख सकते हैं।

+0

बढ़िया! वास्तव में उपयोगी नोट! मेरी परियोजना में इसका इस्तेमाल करेंगे। –

+0

अद्भुत, यह बस काम करता है! :-) – ASBai

1

आपको यह जांचने की आवश्यकता है कि चर कैसे संग्रहीत किया गया था। वहाँ सेट/GetEnvironmentVariable के लिए अधिभार विधि है:

Environment.GetEnvironmentVariable Method (String, EnvironmentVariableTarget)

बात है, वहाँ वातावरण चर (EnvironmentVariableTarget) भंडारण के तीन प्रकार हैं:

  • मशीन (सभी उपयोगकर्ताओं के लिए उपलब्ध है)
  • उपयोगकर्ता (वर्तमान उपयोगकर्ता के लिए उपलब्ध)
  • प्रक्रिया (केवल वर्तमान प्रक्रिया के लिए उपलब्ध [बीटीडब्ल्यू की सिफारिश नहीं की गई])

आप मशीन या उपयोगकर्ता के रूप में जानकारी स्टोर है, तो आप इसे चलाने के रूप में परीक्षण कर सकते हैं रन (विन + आर):% TIP_HOME%

आशा है कि यह मदद करता है :)

0

सेवाएं आम तौर तहत चलाए जा रहे तीन सेवा खातों में से एक, Local ServiceLocal System और Network Service। जिनके लिए आपके सामान्य पर्यावरणीय चर शून्य होंगे।



मैं सेवा होने से परीक्षण किया एक घटना लॉग प्रविष्टि लिखने की पड़ताल करें और प्रिंट क्या यह HOMEPATH चर में संग्रहीत करता है। यह सेवा खातों के लिए खाली लौटा। सी # में:

protected override void OnStart(string[] args) 
{ 
    EventLog.WriteEntry("The HomePath for this service is '" + Environment.GetEnvironmentVariable("HOMEPATH") + "'", EventLogEntryType.Information); 
} 

संभव समाधान


आप क्या खाते में एक सेवा का उपयोग करता है (उदाहरण के लिए आपके उपयोगकर्ता खाते), सेवाओं गुण विंडो में या सेवा में स्थापित सेट कर सकते हैं config। जब मैंने अपने उपयोगकर्ता खाते के साथ परीक्षण किया तो इवेंट लॉग एंट्री The HomePath for this service is '\Users\Admin-PC' प्रदर्शित हुई। यदि यह आपके उपयोगकर्ता खाते का उपयोग कर रहा था तो उसके पास उन सभी पर्यावरणीय चरों तक पहुंच होगी जिनकी आपके पास आम तौर पर पहुंच है।
enter image description hereenter image description here

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