2010-07-21 9 views
54

इनो सेटअप आपको [रजिस्ट्री] अनुभागों के माध्यम से पर्यावरण चर सेट करने देता है (पर्यावरण चर के अनुरूप रजिस्ट्री कुंजी सेट करके)इनो सेटअप इंस्टॉलर चलाते समय मैं पैथ पर्यावरण चर को कैसे संशोधित करूं?

हालांकि, कभी-कभी आप केवल पर्यावरण चर सेट नहीं करना चाहते हैं। अक्सर, आप इसे संशोधित करना चाहते हैं। उदाहरण के लिए: स्थापना पर, कोई पाथ पर्यावरण परिवर्तक से/निर्देशिका में निर्देशिका को जोड़/निकालना चाहता है।

मैं इनोसेटअप के भीतर से पाथ पर्यावरण चर को कैसे संशोधित कर सकता हूं?

उत्तर

71

आपके द्वारा दी गई रजिस्ट्री कुंजी में पथ REG_EXPAND_SZ प्रकार का मान है। [रजिस्ट्री] अनुभाग राज्यों के लिए Inno सेटअप प्रलेखन के रूप में वहाँ उन लोगों के लिए तत्वों संलग्न करने के लिए एक तरीका है:

एक string, expandsz, या multisz प्रकार मान पर, आप एक विशेष निरंतर में {olddata} कहा जाता है का उपयोग कर सकते यह पैरामीटर {olddata} को रजिस्ट्री मान के पिछले डेटा के साथ बदल दिया गया है। {olddata} निरंतर उपयोगी हो सकता है यदि आपको मौजूदा मान में स्ट्रिंग जोड़ने की आवश्यकता है, उदाहरण के लिए, {olddata};{app}। यदि मान मौजूद नहीं है या मौजूदा मान स्ट्रिंग प्रकार नहीं है, तो {olddata} निरंतर चुपचाप हटा दिया जाता है।

तो पथ इस के समान एक रजिस्ट्री अनुभाग इस्तेमाल किया जा सकता करने के लिए संलग्न करने के लिए:

[Registry] 
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \ 
    ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo" 

जो "C: \ foo" संलग्न करेंगे पथ के लिए निर्देशिका।

दुर्भाग्यवश यह दोहराया जाएगा जब आप दूसरी बार स्थापित करते हैं, जिसे भी ठीक किया जाना चाहिए। कि क्या दिया निर्देशिका पहले यह में निहित है

[Registry] 
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \ 
    ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"; \ 
    Check: NeedsAddPath('C:\foo') 

इस समारोह मूल पथ मूल्य और चेक पर लिखा है: एक समारोह पास्कल लिपि में कोडित के साथ एक Check पैरामीटर कि उस पथ में वास्तव में विस्तार करने की आवश्यकता है की जाँच करने के लिए इस्तेमाल किया जा सकता है । ऐसा करने के लिए यह अर्धविराम वर्ण तैयार करता है और जोड़ता है जिसका उपयोग पथ में निर्देशिकाओं को अलग करने के लिए किया जाता है।

[Code] 

function NeedsAddPath(Param: string): boolean; 
var 
    OrigPath: string; 
begin 
    if not RegQueryStringValue(HKEY_LOCAL_MACHINE, 
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 
    'Path', OrigPath) 
    then begin 
    Result := True; 
    exit; 
    end; 
    { look for the path with leading and trailing semicolon } 
    { Pos() returns 0 if not found } 
    Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0; 
end; 

ध्यान दें कि आप स्थिरांक का विस्तार करने से पहले आप उन्हें पारित आवश्यकता हो सकती है: तथ्य यह है कि निर्देशिका के लिए खोजा गया पहला या अंतिम तत्व अर्धविराम वर्ण के साथ-साथ prepended और मूल मूल्य के साथ जोड़ दिया जाता है हो सकता है के लिए खाते में करने के लिए चेक फ़ंक्शन पर पैरामीटर, विवरण के लिए दस्तावेज़ देखें।

अनइंस्टॉलेशन के दौरान पथ से इस निर्देशिका को हटाकर एक ही फैशन में किया जा सकता है और पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।

+1

यदि आप बस {olddata 'पास कर सकते हैं तो यह अच्छा नहीं होगा } 'चेक फ़ंक्शन पर है ताकि आपको कोड में फिर से मूल्य को पढ़ने की आवश्यकता न हो? (शायद आप कर सकते हैं - मैंने कोशिश नहीं की है);) –

+3

एक और बात यह है कि पथ वहां हो सकता है लेकिन एक अलग वर्ण केस का उपयोग करें (आसानी से 'अपरकेस' या somesuch फ़ंक्शन का उपयोग करके तय किया गया) या इससे भी बदतर, 8.3 पथ नामों का उपयोग करें (उदाहरण के लिए "सी: \ प्रोग्रा ~ 1 \ मायप्रोग") या पर्यावरण चर (उदाहरण के लिए "% प्रोग्रामफाइल% \ MyProg")। यह उन लोगों का पता लगाने के लिए एक दुःस्वप्न होगा ... –

+1

आपके प्रोग्राम को अनइंस्टॉल करने के बारे में क्या होगा? आप पाथ पर्यावरण वैरिएबल से अपना रास्ता कैसे हटाएंगे? –

6

NeedsAddPaththe answer by @mghie\ और अक्षर केस की जांच नहीं करता है। इसे ठीक करो।

function NeedsAddPath(Param: string): boolean; 
var 
    OrigPath: string; 
begin 
    if not RegQueryStringValue(
    HKEY_LOCAL_MACHINE, 
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 
    'Path', OrigPath) 
    then begin 
    Result := True; 
    exit; 
    end; 
    { look for the path with leading and trailing semicolon } 
    { Pos() returns 0 if not found } 
    Result := 
    (Pos(';' + UpperCase(Param) + ';', ';' + UpperCase(OrigPath) + ';') = 0) and 
    (Pos(';' + UpperCase(Param) + '\;', ';' + UpperCase(OrigPath) + ';') = 0); 
end; 
+3

मैं 'सी: \ foo' के बजाय एक चर का उपयोग कैसे करूं? मैंने NeedsAddPath ('{app}') की कोशिश की लेकिन यह काम नहीं करता - बस पथ को जोड़ना हालांकि यह पहले से बाहर निकल चुका है। क्या आप सलाह दे सकते हैं? –

+1

उपर्युक्त टिप्पणी का उत्तर देने के लिए, दूसरों के लिए उपयोगी हो सकता है: आपको 'ExpandConstant()' फ़ंक्शन का उपयोग करने की आवश्यकता है। – Jack

+0

धन्यवाद जैक। हालांकि मुझे NeedsAddPath ('{app} \ MoreDirectoriesHere') का एक उदाहरण देखना अच्छा लगेगा। – vezenkov

14

आप लेगरूम का उपयोग कर सकते हैं।शुद्ध के अपने InnoSetup स्क्रिप्ट फ़ाइल में modpath.iss स्क्रिप्ट:

#define MyTitleName "MyApp" 

[Setup] 
ChangesEnvironment=yes 

[CustomMessages] 
AppAddPath=Add application directory to your environmental path (required) 

[Files] 
Source: "install\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; 

[Icons] 
Name: "{group}\{cm:UninstallProgram,{#MyTitleName}}"; Filename: "{uninstallexe}"; Comment: "Uninstalls {#MyTitleName}" 
Name: "{group}\{#MyTitleName}"; Filename: "{app}\{#MyTitleName}.EXE"; WorkingDir: "{app}"; AppUserModelID: "{#MyTitleName}"; Comment: "Runs {#MyTitleName}" 
Name: "{commondesktop}\{#MyTitleName}"; Filename: "{app}\{#MyTitleName}.EXE"; WorkingDir: "{app}"; AppUserModelID: "{#MyTitleName}"; Comment: "Runs {#MyTitleName}" 

[Registry] 
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}" 

[Tasks] 
Name: modifypath; Description:{cm:AppAddPath}; 

[Code] 

const 
    ModPathName = 'modifypath'; 
    ModPathType = 'system'; 

function ModPathDir(): TArrayOfString; 
begin 
    setArrayLength(Result, 1) 
    Result[0] := ExpandConstant('{app}'); 
end; 

#include "modpath.iss" 
1

यहाँ समस्या यह है कि पथ \ के साथ समाप्त होने के अस्तित्व के लिए आवरण, चेक पर ध्यान नहीं देता करने के लिए एक पूर्ण समाधान है और यह भी परम में स्थिरांक का विस्तार:

function NeedsAddPath(Param: string): boolean; 
var 
    OrigPath: string; 
    ParamExpanded: string; 
begin 
    //expand the setup constants like {app} from Param 
    ParamExpanded := ExpandConstant(Param); 
    if not RegQueryStringValue(HKEY_LOCAL_MACHINE, 
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 
    'Path', OrigPath) 
    then begin 
    Result := True; 
    exit; 
    end; 
    // look for the path with leading and trailing semicolon and with or without \ ending 
    // Pos() returns 0 if not found 
    Result := Pos(';' + UpperCase(ParamExpanded) + ';', ';' + UpperCase(OrigPath) + ';') = 0; 
    if Result = True then 
    Result := Pos(';' + UpperCase(ParamExpanded) + '\;', ';' + UpperCase(OrigPath) + ';') = 0; 
end; 
+0

निश्चित रूप से यहां कोई समस्या है: यह केवल ''; 'मामला जांचता है यदि मामला पाया गया था। – Stewart

2

मुझे एक ही समस्या थी लेकिन ऊपर दिए गए उत्तरों के बावजूद मैंने एक कस्टम समाधान के साथ समाप्त कर दिया है और मैं इसे आपके साथ साझा करना चाहता हूं।

सब मैं 2 तरीकों के साथ environment.iss फ़ाइल बना ली है सबसे पहले - पर्यावरण के पथ के लिए पथ को जोड़ने के लिए एक चर और दूसरा इसे हटाने के लिए:

[Code] 
const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; 

procedure EnvAddPath(Path: string); 
var 
    Paths: string; 
begin 
    { Retrieve current path (use empty string if entry not exists) } 
    if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) 
    then Paths := ''; 

    { Skip if string already found in path } 
    if Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit; 

    { App string to the end of the path variable } 
    Paths := Paths + ';'+ Path +';' 

    { Overwrite (or create if missing) path environment variable } 
    if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) 
    then Log(Format('The [%s] added to PATH: [%s]', [Path, Paths])) 
    else Log(Format('Error while adding the [%s] to PATH: [%s]', [Path, Paths])); 
end; 

procedure EnvRemovePath(Path: string); 
var 
    Paths: string; 
    P: Integer; 
begin 
    { Skip if registry entry not exists } 
    if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then 
     exit; 

    { Skip if string not found in path } 
    P := Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';'); 
    if P = 0 then exit; 

    { Update path variable } 
    Delete(Paths, P - 1, Length(Path) + 1); 

    { Overwrite path environment variable } 
    if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) 
    then Log(Format('The [%s] removed from PATH: [%s]', [Path, Paths])) 
    else Log(Format('Error while removing the [%s] from PATH: [%s]', [Path, Paths])); 
end; 

संदर्भ: RegQueryStringValue, RegWriteStringValue

अब मुख्य .iss फ़ाइल में मैं इस फ़ाइल को शामिल कर सकता हूं और 2 घटनाओं के बारे में सुन सकता हूं (प्रलेखन में Event Functions अनुभाग में उन घटनाओं के बारे में अधिक जानकारी), CurStepChanged स्थापना के बाद पथ जोड़ने के लिए और CurUninstallStepChanged उपयोगकर्ता को एप्लिकेशन को अनइंस्टॉल करते समय इसे निकालने के लिए।

#include "environment.iss" 

[Setup] 
ChangesEnvironment=true 

; More options in setup section as well as other sections like Files, Components, Tasks... 

[Code] 
procedure CurStepChanged(CurStep: TSetupStep); 
begin 
    if CurStep = ssPostInstall 
    then EnvAddPath(ExpandConstant('{app}') +'\bin'); 
end; 

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); 
begin 
    if CurUninstallStep = usPostUninstall 
    then EnvRemovePath(ExpandConstant('{app}') +'\bin'); 
end; 

संदर्भ:: ExpandConstant

नोट # 1: स्थापित करें कदम केवल एक बार पथ को जोड़ने (स्थापना के repeatability सुनिश्चित करता है में नीचे दिए गए उदाहरण स्क्रिप्ट जोड़ने/bin निर्देशिका (स्थापना निर्देशिका के सापेक्ष) को हटा दें)।

नोट # 2: अनइंस्टॉल चरण चर से पथ की केवल एक घटना को हटा दें।

बोनस: चेकबॉक्स साथ स्थापना कदम "पथ चर में जोड़ें"।

Inno Setup - Add to PATH variable

चेकबॉक्स साथ स्थापना कदम को जोड़ने के लिए "पथ चर में जोड़ें"[Tasks] खंड में नया कार्य को परिभाषित (डिफ़ॉल्ट रूप से चेक):

[Tasks] 
Name: envPath; Description: "Add to PATH variable" 

तो फिर तुम यह CurStepChanged घटना में जांच कर सकते हैं :

procedure CurStepChanged(CurStep: TSetupStep); 
begin 
    if (CurStep = ssPostInstall) and IsTaskSelected('envPath') 
    then EnvAddPath(ExpandConstant('{app}') +'\bin'); 
end;