2009-12-17 22 views
15

में प्रोग्रामेटिक रूप से एक निर्देशिका जोड़ना मैं एक फ़ंक्शन के साथ एक Win32 DLL लिख रहा हूं जो Windows PATH पर्यावरण चर (एक इंस्टॉलर में उपयोग करने के लिए) में एक निर्देशिका जोड़ता है।विंडोज पैथ पर्यावरण परिवर्तनीय

डीएलएल के चलने के बाद रेजीडिट या कंट्रोल पैनल में पर्यावरण चर को देखते हुए मुझे दिखाता है कि मेरा डीएलएल HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment और HKEY_CURRENT_USER\Environment पर पथ जोड़ने में सफल रहा है।

लेकिन जब मैं एक नया कमांड प्रॉम्प्ट (डीएलएल चलाने के बाद) शुरू करता हूं, तो मैंने जो निर्देशिका जोड़ा है वह echo %PATH% के आउटपुट में दिखाई नहीं देता है और मैं उस नाम में निष्पादन योग्य नहीं पहुंच सकता जो उसका नाम टाइप करके उस निर्देशिका में रहता है।

मुझे लगता है कि मेरा प्रोग्राम सिस्टम को सूचित करने का अच्छा काम नहीं कर रहा है कि पथ बदल गया है, या शायद यह परिवर्तन पूरी तरह से प्रभावी होने से पहले उन्हें सूचित कर रहा है। मैं एक article by Microsoft है कि एक वातावरण चर बदलने के बाद WM_SETTINGCHANGE संदेश प्रसारित करने का कहना है कि पढ़ा है, और मैं इस कोड के साथ कर रही हूँ:

DWORD result2 = 0; 
LRESULT result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 
    (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &result2); 
if (result == 0){ /* ... Display error message to user ... */ } 

मेरे कॉल के आदेश है: RegCreateKeyEx, RegSetValueEx, RegCloseKey, SendMessageTimeout

यदि मैं कंट्रोल पैनल "एनवायरनमेंट वैरिएबल" विंडो में "ओके" दबाता हूं, तो मेरे डीएलएल द्वारा किए गए परिवर्तन पीएटीएच में किए गए परिवर्तन नव निर्मित कमांड प्रॉम्प्ट में दिखाए जाते हैं, इसलिए कुछ ऐसा है जो नियंत्रण कक्ष पैथ परिवर्तनों को प्रसारित करने के लिए कर रहा है; मैं यह जानना चाहता हूं कि यह क्या है और वही काम करें।

क्या किसी को पता है कि मुझे क्या करना चाहिए?

मैं 64-बिट विंडोज विस्टा चला रहा हूं लेकिन मैं चाहता हूं कि यह सभी विंडोज एक्सपी, विस्टा और विंडोज 7 ऑपरेटिंग सिस्टम पर काम करे।

अद्यतन: मैंने ऊपर पोस्ट किए गए कोड के साथ समस्या यह है कि मैंने एल पर्यावरण को "पर्यावरण" स्ट्रिंग पर नहीं रखा है। यद्यपि यह माइक्रोसॉफ्ट प्रलेखन में स्पष्ट रूप से कहीं भी नहीं कहता है, जिसे मैं पा सकता हूं, LPARAM को एक CHAR स्ट्रिंग के विपरीत WCHAR स्ट्रिंग (2-बाइट वर्ण) में पॉइंटर होना आवश्यक है, जो विजुअल स्टूडियो का कंपाइलर डिफ़ॉल्ट रूप से उत्पन्न करता है जब मैं एक स्ट्रिंग अक्षर लिखता हूं। मेरी समस्या का समाधान "पर्यावरण" को एल "पर्यावरण" में बदलना था। (मैंने सोचा कि मैंने पहले से ही इस सवाल को पोस्ट करने से पहले कोशिश की है, लेकिन स्पष्ट रूप से मैंने इसे सही तरीके से आजमाया नहीं है!) लेकिन जो भी इस कार्य के लिए एक पूर्ण सी ++ समाधान चाहता है उसे डैन मोल्डिंग के जवाब को देखना चाहिए।

+0

आप कुछ ओपन-सोर्स इंस्टॉलर्स के स्रोत कोड को देखना चाहते हैं, उदा। एनएसआईएस या इनो सेटअप। वे इस अधिसूचना को सही करते हैं। – bialix

+6

एक छोटी सी त्वरित युक्ति, आप केवल "पथ" टाइप करके और एंटर दबाकर कमांड प्रॉम्प्ट पर पाथ सामग्री दिखा सकते हैं। प्रति परीक्षण 7 कीस्ट्रोक बचाता है (9 शिफ्ट कुंजी की गिनती)! – Todd

+0

आह, आपको यूनिकोड एप्लिकेशन बनाना होगा, इसलिए 'windows.h' एपीआई (' SendMessageTimeoutW') के यूनिकोड संस्करण में लाता है, जिसके लिए 'LPCSTR' के बजाय 'LPARAM' के लिए' LPCWSTR' की आवश्यकता होगी। मुझे लगता है कि यदि आप "एएनएसआई" और यूनिकोड दोनों का निर्माण करना चाहते हैं, तो सही काम करने के लिए 'LPCTSTR' (यानी '_T()' मैक्रो) का उपयोग करना है। मेरी लाइब्रेरी शायद इसे "यूनिकोड जागरूक" बनाने के लिए एक अद्यतन का उपयोग कर सकती है। यह वर्तमान में केवल "एएनएसआई" का उपयोग करके पर्यावरण चर सेट करने का समर्थन करता है, जो आपके पथ में, सिरीलिक वर्णों के साथ निर्देशिका की आवश्यकता होने पर समस्याग्रस्त हो सकता है। –

उत्तर

11

यह वास्तव में सूर्य के नीचे कुछ भी नया नहीं है। यह पहले से ही कम से कम एक बार किया जा चुका है। मेरे द्वारा। मैंने एक डीएलएल बनाया है जो आप बिल्कुल उसी उद्देश्य के लिए वर्णन करते हैं (एनएसआईएस इंस्टॉलर से पथ को संशोधित करने में उपयोग के लिए)। यह Visual Leak Detector इंस्टॉलर द्वारा उपयोग किया जाता है।

डीएलएल को editenv.dll कहा जाता है। The source गीथब में उपलब्ध है। मैंने अभी इंस्टॉलर का परीक्षण किया है और इसे सिस्टम पाथ पर्यावरण परिवर्तनीय, कोई समस्या नहीं अपडेट की गई है। जो आपने लिखा है उसके आधार पर, मुझे कुछ भी नहीं दिख रहा है जो गलत होने के रूप में सामने आता है। मुझे कुछ भी स्पष्ट नहीं दिख रहा है जो गायब है। लेकिन यह editenv.dll स्रोत पर एक नज़र डालने लायक हो सकता है (में EnvVar::set() में आपको और pathRemove() सी एपीआई editenv.cpp में अधिक रुचि होगी)।

+0

कोड दान के लिए धन्यवाद! यहां तक ​​कि सोचा था कि मुझे आपका कोड देखकर मेरा विशिष्ट समाधान नहीं मिला, आपका उत्तर इस प्रश्न के भविष्य के पाठकों के लिए बेहद सहायक होगा। –

0

मेरे पास एक प्रोग्राम है जो पर्यावरण को अद्यतन करने के लिए आपके लिए एक ही Win32 API कॉल करता है, और यह ठीक काम करता है।

से सावधान रहना एक बात है आप कमांड प्रॉम्प्ट खोल रहे हैं।

यदि आप ऐसा करने से कमांड प्रॉम्प्ट को खोलने:

Start -> Run -> cmd.exe 

तो शीघ्र में वातावरण है कि नया वेरिएबल सेट किया गया है पता चलता है।

हालांकि, मेरे पास मेरे कीबोर्ड पर एक प्रोग्राम करने योग्य फ़ंक्शन कुंजी भी है जिसे मैंने cmd.exe प्रक्रिया चलाने के लिए सेट किया है। अगर मैं उस फंक्शन कुंजी के माध्यम से कमांड प्रॉम्प्ट खोलता हूं और फिर env टाइप करता हूं, तो यह चर को सेट के रूप में नहीं दिखाता है।

मुझे यकीन नहीं है कि यह अलग-अलग क्यों काम करता है, लेकिन cmd.exe प्रक्रिया शुरू होने के तरीके से कुछ करना चाहिए (हालांकि दोनों मेरे उपयोगकर्ता नाम के तहत चल रहे हैं, SYSTEM नहीं)।

आप कमांड प्रॉम्प्ट कैसे खोल रहे हैं?

+4

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

+0

दिलचस्प। मैं अपने स्टार्ट मेनू में "कमांड प्रॉम्प्ट" पर क्लिक करके अपना कमांड प्रॉम्प्ट शुरू कर रहा था। यह एक शॉर्टकट है जो विंडोज के साथ सहायक उपकरण मेनू में आया था, जिसे मैंने स्टार्ट मेनू में "पिन किया" था। लक्ष्य% SystemRoot% \ system32 \ cmd.exe –

+0

@Todd - हाँ जो सही लगता है। अच्छा विश्लेषण! @ डेविड - अगर आप cmd.exe को स्टार्ट-> रन से चलाते हैं तो कोई अंतर? – LeopardSkinPillBoxHat