安装包卸载时如何删除安装时写在系统环境变量中的内容

本文介绍了使用InstallShield在卸载时清除注册表中追加的环境变量路径的方法,包括使用事件响应函数OnUninstall替代OnBegin,并确保删除唯一标识的字符串以避免误删。

在用InstallShield制作安装包时,有时我们会在脚本中通过操作注册表,配置系统环境变量,比如在Path中追加,但卸载时如何清除追加的路径变量,一直有些模糊。

 

今天受网友启发,在InstallShield的帮助文档中找到了解决办法,代码如下:

function   OnBegin ()  
    
STRING  svSearchPath;
begin
     //   Set  up the search path  to  pass  as  a parameter  to  PathSet. 
    svSearchPath 
=   " C:\\DOS;C:\\WINDOWS;C:\\TEMP; "   +  
                   
" D:\\Program Files\\Kevin Wan\\InstallShield; "   +  
                   
" C:\\EXAMPLE\\SOURCE;D:\\WORK\\TEMP "

     //  Initialize the path buffer. 
    
PathSet  (svSearchPath); 

     //  Display the initial search path. 
     //  Delete  D:\Program Files\Kevin Wan\InstallShield fro m the path buffer.                            

    if (PathDelete ("Kevin Wan"PARTIAL<0then    

        MessageBox ("First call to PathDelete failed.", SEVERE); 
    endif

    // Get the search path from the path buffer; this call also releases 
    
// the memory allocated for the path buffer. 

    PathGet (svSearchPath); 
    
MessageBox(svSearchPath, INFORMATION);
end;

这里我将Sample添加到了事件响应函数OnBegin中,大家实际操作时可以写到OnUninstall中。

Sample中我删除了和Kevin Wan相关的路径,但也要注意,这里最好选择唯一标示的字符串,否则可能会把其他程序写入的路径变量也同时删除了。

 以上转自:http://www.cnblogs.com/installshield/archive/2011/01/24/1943406.html

 

附:IS脚步增加环境变量实例

STRING  szKey , svValue;
NUMBER nvType , nvSize;

begin
    szKey = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
    RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
    if(RegDBGetKeyValueEx(szKey,"Path",nvType,svValue,nvSize)=0) then           //读取Path
        svValue = "C:\\ABC;" + svValue; //添加路径
        if(RegDBSetKeyValueEx(szKey, "Path", REGDB_STRING, svValue, -1)<0) then //更新Path
            MessageBox ("Path add failed!", SEVERE);
        endif;
    endif;
end;
这样添加的话卸载的时候会产生一个问题,那就是整个Path变量都被删掉了(不是清空,而是整个删除)。解决办法有二:

1.首先你在你写path的那句话前后加上Disable(LOGGING); Enable(LOGGING);,表示阻止掉IS的安装日志,这样就不会记录你的动作,卸载时候也不会卸载掉path了
2.在卸载那里自己写脚本,读到path后去掉你自己的路径C:\ABC,然后再设回去。

 

 

转载于:https://www.cnblogs.com/kivenhou/archive/2011/06/07/2074203.html

<think>我们正在使用InnoSetup来创建安装程序,并且需要在安装过程中添加系统环境变量。根据引用[1]和引用[3],我们知道InnoSetup使用脚本(.iss文件)来控制安装过程,包括设置环境变量。在InnoSetup中,我们可以使用[Registry]段来修改注册表,因为Windows的系统环境变量存储在注册表中(具体位置是HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment)。步骤:1.打开InnoSetup脚本(.iss文件)或创建一个新的。2.在[Registry]段中添加一个条目来设置环境变量。注意:环境变量分为用户变量和系统变量。系统变量需要入到HKEY_LOCAL_MACHINE下,并且需要管理员权限(所以安装程序通常需要以管理员身份运行)。示例:假设我们要将安装目录({app})添加到系统的PATH环境变量中。但是,直接修改PATH环境变量需要小心,因为不能重复添加,也不能破坏已有的路径。通常的做法是:-读取当前的PATH值-判断要添加的路径是否已经存在-如果不存在,则追加(或前置)到PATH中然而,InnoSetup的[Registry]段本身不支持条件判断,因此我们需要使用Pascal脚本来实现。我们可以使用[Code]段来编Pascal脚本,在安装过程中执行更复杂的操作。以下是一个示例,展示如何将安装目录添加到系统PATH环境变量中(仅当它不存在):在脚本的[Code]部分添加以下函数:```[Code]constEnvironmentKey='SYSTEM\CurrentControlSet\Control\SessionManager\Environment';procedureEnvAddPath(Path:string);varPaths:string;begin{检索当前的PATH(系统变量)}ifnotRegQueryStringValue(HKEY_LOCAL_MACHINE,EnvironmentKey,'Path',Paths)thenbegin{如果不存在PATH变量,则创建}Paths:='';end;{检查路径是否已经存在}ifPos(';'+Uppercase(Path)+';',';'+Uppercase(Paths)+';')>0thenexit;{追加路径}Paths:=Paths+';'+Path;{更新PATH}ifRegWriteStringValue(HKEY_LOCAL_MACHINE,EnvironmentKey,'Path',Paths)thenLog(Format('Added[%s]toPATH',[Path]))elseLog(Format('Errorwhileadding[%s]toPATH',[Path]));end;procedureEnvRemovePath(Path:string);varPaths:string;P:Integer;begin{检索当前的PATH}ifnotRegQueryStringValue(HKEY_LOCAL_MACHINE,EnvironmentKey,'Path',Paths)thenexit;{查找并删除路径(不区分大小)}P:=Pos(';'+Uppercase(Path)+';',';'+Uppercase(Paths)+';');ifP=0thenexit;{删除路径}Delete(Paths,P,Length(Path)+1);{更新PATH}RegWriteStringValue(HKEY_LOCAL_MACHINE,EnvironmentKey,'Path',Paths);end;```然后,在安装过程中调用这些函数。通常,我们在安装完成后添加,在卸载删除。在[Run]段之前(或确保在文件复制之后)执行添加PATH的操作。我们可以使用CurStepChanged事件,当安装步骤变为ssPostInstall(即安装文件完成后)执行。在[Code]部分继续添加:```procedureCurStepChanged(CurStep:TSetupStep);beginifCurStep=ssPostInstallthenbegin{将安装目录添加到PATH}EnvAddPath(ExpandConstant('{app}'));end;end;```在卸载,我们需要删除添加的路径。我们可以使用CurUninstallStepChanged事件:```procedureCurUninstallStepChanged(CurUninstallStep:TUninstallStep);beginifCurUninstallStep=usPostUninstallthenbegin{从PATH中移除安装目录}EnvRemovePath(ExpandConstant('{app}'));end;end;```注意:修改系统环境变量后,通常需要广播一条消息(WM_SETTINGCHANGE)来通知其他进程(如资源管理器)环境变量已经更改。但是,在安装程序中,由于安装后通常需要重启,所以可能不需要立即生效。如果希望立即生效,可以发送广播消息。在EnvAddPath和EnvRemovePath函数中,在修改注册表后添加广播:```//在修改注册表后,发送广播消息withTRegistry.CreatedotryRootKey:=HKEY_LOCAL_MACHINE;ifOpenKey('SYSTEM\CurrentControlSet\Control\SessionManager\Environment',False)thenbegin//发送消息SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,0,LParam('Environment'),SMTO_ABORTIFHUNG,5000,nil);end;finallyFree;end;```但是,InnoSetup的Pascal脚本中没有定义HWND_BROADCAST和WM_SETTINGCHANGE,我们需要先定义这些常量:```constHWND_BROADCAST=$FFFF;WM_SETTINGCHANGE=$001A;SMTO_ABORTIFHUNG=$0002;```然后,我们可以使用External函数来调用SendMessageTimeout(它在user32.dll中)。在函数外部声明:```functionSendMessageTimeout(hWnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LParam;fuFlags:UINT;uTimeout:UINT;varlpdwResult:DWORD):LRESULT;external'SendMessageTimeoutW@user32.dllstdcall';```因此,完整的EnvAddPath函数可以这样:```[Code]constEnvironmentKey='SYSTEM\CurrentControlSet\Control\SessionManager\Environment';HWND_BROADCAST=$FFFF;WM_SETTINGCHANGE=$001A;SMTO_ABORTIFHUNG=$0002;functionSendMessageTimeout(hWnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LParam;fuFlags:UINT;uTimeout:UINT;varlpdwResult:DWORD):LRESULT;external'SendMessageTimeoutW@user32.dllstdcall';procedureEnvAddPath(Path:string);varPaths:string;Dummy:DWORD;begin{检索当前的PATH(系统变量)}ifnotRegQueryStringValue(HKEY_LOCAL_MACHINE,EnvironmentKey,'Path',Paths)thenbegin{如果不存在PATH变量,则创建}Paths:='';end;{检查路径是否已经存在}ifPos(';'+Uppercase(Path)+';',';'+Uppercase(Paths)+';')>0thenexit;{追加路径}Paths:=Paths+';'+Path;{更新PATH}ifRegWriteStringValue(HKEY_LOCAL_MACHINE,EnvironmentKey,'Path',Paths)thenbeginLog(Format('Added[%s]toPATH',[Path]));//广播环境变量更改消息SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,0,LParam('Environment'),SMTO_ABORTIFHUNG,5000,Dummy);endelseLog(Format('Errorwhileadding[%s]toPATH',[Path]));end;```同样,在EnvRemovePath中也添加广播。注意事项:-修改系统环境变量需要管理员权限,因此安装程序应该包含`PrivilegesRequired=admin`。-由于修改的是系统环境变量,所以会影响到所有用户。另外,引用[2]中提供了一个批处理脚本,但这里我们使用InnoSetup的脚本实现。总结步骤:1.在[Setup]段设置管理员权限:`PrivilegesRequired=admin`2.在[Code]段中定义上述函数和常量3.在CurStepChanged和CurUninstallStepChanged事件中调用添加和移除路径的函数完整的示例脚本结构如下:```[Setup]AppName=MyProgramAppVersion=1.0PrivilegesRequired=adminDefaultDirName={pf}\MyProgram[Code]//此处放置上述定义的常量、函数和事件处理程序[Files]Source:"MyProgram.exe";DestDir:"{app}"//其他段...[Run]Filename:"{app}\MyProgram.exe";Description:"Runtheprogram";Flags:postinstallnowait```这样,在安装完成后,安装目录就会被添加到系统PATH环境变量中,并且在卸载自动移除。注意:如果安装目录中包含空格,通常需要用引号括起来,但PATH环境变量中一般不使用引号,除非必要(如果路径中有空格,系统会自动处理)。不过,为了避免问题,我们可以确保路径中不包含空格,或者如果包含空格,可以尝试用引号括起来。但是,在PATH中,每个路径之间用分号分隔,路径本身不需要引号。如果路径中有分号,才必须用引号括起来(这种情况很少)。所以一般情况下,我们直接添加路径即可。但是,如果路径中有空格,系统在解析可能会出现问题吗?实际上,Windows系统可以很好地处理带空格的路径,只要在PATH中正确用分号分隔,就不需要引号。例如:`C:\ProgramFiles\MyApp`是有效的。因此,我们不需要额外添加引号。最后,请在实际环境中测试安装程序,确保环境变量被正确添加和移除。</think>### 在 Inno Setup 中添加系统环境变量的教程 在 Inno Setup 中添加系统环境变量主要通过修改注册表实现,以下是详细步骤和示例脚本: #### 方法 1:使用 [Registry] 段(简单场景) ```innosetup [Setup] ; 必须要求管理员权限 PrivilegesRequired=admin [Registry] ; 添加新的系统环境变量 Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \ ValueType: string; ValueName: "MY_VARIABLE"; ValueData: "C:\MyApp\Bin"; \ Flags: preservestringtype ; 添加到 PATH 环境变量 Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \ ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}\Bin"; \ Flags: preservestringtype ``` **说明**: 1. `Root: HKLM`:修改系统级注册表 2. `ValueType: expandsz`:处理包含环境变量的路径 3. `{olddata}`:保留现有值 4. `{app}`:安装目录路径变量 5. `Flags: preservestringtype`:保持注册表数据类型不变 #### 方法 2:使用 [Code] 段(高级控制) ```innosetup [Code] const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; // 添加环境变量 procedure AddEnvVar(VarName, VarValue: string); begin if not RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, VarName, VarValue) then MsgBox('环境变量设置失败', mbError, MB_OK); end; // 添加到 PATH procedure AddToPath(Path: string); var OldPath: string; begin if RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', OldPath) then begin if Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(OldPath) + ';') = 0 then RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', OldPath + ';' + Path); end else RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Path); end; procedure CurStepChanged(CurStep: TSetupStep); begin if CurStep = ssPostInstall then begin AddEnvVar('MY_APP_HOME', ExpandConstant('{app}')); AddToPath(ExpandConstant('{app}\Bin')); // 通知系统更新环境变量 SendBroadcastMessage(WM_SETTINGCHANGE, 0, LParam('Environment')); end; end; ``` #### 关键注意事项: 1. **管理员权限**:必须设置 `PrivilegesRequired=admin` 2. **路径处理**: - 使用 `ExpandConstant('{app}')` 获取安装目录 - PATH 添加前检查是否已存在(避免重复) 3. **即生效**:通过 `SendBroadcastMessage` 通知系统更新环境变量 4. **卸载清理**:建议在卸载移除添加的环境变量 ```innosetup [UninstallDelete] ; 卸载移除 PATH 中的路径 Root: HKLM; Subkey: "Environment"; ValueType: string; ValueName: "Path"; \ ValueData: "{olddata}"; DeleteValue: no; \ Tasks: removepath; Check: IsPathEntryExists ``` #### 常见问题解决 1. **环境变量不生效**: - 确保使用 `admin` 权限 - 检查注册表路径是否正确 - 添加广播消息通知系统更新 2. **PATH 重复添加**: - 使用代码段检查路径是否已存在 - 卸载脚本中反向操作 3. **特殊字符处理**: - 包含空格的路径不需要额外引号 - 使用 `expandsz` 类型处理变量扩展 > 提示:修改系统环境变量可能影响其他程序,建议在安装前备份注册表项 `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment`[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值