正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- #ifdef Unicode
- #define A "W"
- #else
- #define A "A"
- #endif
- [Setup]
- AppName=My Program
- AppVerName=My Program version 1.5
- DefaultDirName={pf}\My Program
- DefaultGroupName=My Program
- [code]
- const
- myMark = '由 XYZ 添加'; // 作为标识
- function GetFileAttributes(lpFileName: String): Cardinal;
- external 'GetFileAttributes{#A}@kernel32.dll stdcall';
- function SetFileAttributes(lpFileName: String; dwFileAttributes: Cardinal): Boolean;
- external 'SetFileAttributes{#A}@kernel32.dll stdcall';
- function LineInFile(sLine, fPath: string): Boolean;
- var
- aos: TArrayOfString;
- n: Integer;
- begin
- Result:= false;
- if LoadStringsFromFile(fPath, aos) then
- for n:= 0 to GetArrayLength(aos)-1 do
- if aos[n] = sLine then
- begin
- Result := true;
- Exit;
- end;
- end;
- procedure AddHosts(newItem, comments: string);
- var
- OldFileAttribute: Cardinal;
- hfPath, newLine: string;
- begin
- hfPath := ExpandConstant('{sys}\drivers\etc\hosts');
- if not LineInFile(newItem, hfPath) then // 仅添加 Hosts 中还没有的项目
- begin
- OldFileAttribute:= GetFileAttributes(hfPath);
- SetFileAttributes(hfPath, FILE_ATTRIBUTE_NORMAL);
- newLine := newItem + ' # ' + myMark;
- If comments > ' ' then
- newLine := newLine + ' / ' + comments;
- SaveStringToFile(hfPath, #13#10 + newLine, True);
- SetFileAttributes(hfPath, OldFileAttribute);
- end;
- end;
- procedure RemoveHosts(sItem: string);
- var
- OldFileAttribute: Cardinal;
- hfPath, newLine: string;
- stl: TStringList;
- n: Integer;
- begin
- hfPath := ExpandConstant('{sys}\drivers\etc\hosts');
- newLine := sItem + ' # ' + myMark;
- stl:= TStringList.Create;
- stl.LoadFromFile(hfPath);
- for n:= stl.Count-1 downto 0 do
- if Pos(newLine, stl.Strings[n]) = 1 then
- stl.Delete(n);
- OldFileAttribute:= GetFileAttributes(hfPath);
- SetFileAttributes(hfPath, FILE_ATTRIBUTE_NORMAL);
- stl.SaveToFile(hfPath);
- stl.Free;
- SetFileAttributes(hfPath, OldFileAttribute);
- end;
- procedure Initializewizard;
- begin
- AddHosts('0.0.0.0 www.xxx.com', '这是注释'); // 在 Hosts 中添加新项目,带注释
- AddHosts('0.0.0.0 www.111.com', ''); // 在 Hosts 中添加新项目,不带注释
- end;
- procedure DeinitializeUninstall;
- begin
- RemoveHosts('0.0.0.0 www.xxx.com'); // 从 Hosts 中删除项目
- RemoveHosts('0.0.0.0 www.111.com'); // 从 Hosts 中删除项目
- end;
复制代码
优化后的代码:
- ANSI 和 Unicode 版本都适用。
- 增加了计数功能,保证卸载时只会删除自己添加的项目。
- 采用文件流,无论多大的 Hosts 文件都可以处理。
- 无论添加或删除多少个项目,只需要读取 Hosts 文件一次,从而加快运行速度,避免出现假死现象。
- #define AppID "FDBDCE28-5522-494B-B75A-E515082A312D"
- #ifdef UNICODE
- #define A "W"
- #else
- #define A "A"
- #endif
- [Setup]
- AppId={#AppID}
- AppName=My Program
- AppVerName=My Program version 1.5
- DefaultDirName={pf}\My Program
- DefaultGroupName=My Program
- [Tasks]
- Name: noad; Description: "通过 hosts 屏蔽广告(&D)"
- [code]
- const
- myMark = 'XYZ123'; // 你的标识,用于标识你修改的内容
- Var
- AddHostsItemList, AddHostsCommentList, RemoveHostsList: TStringList;
- function GetFileAttributes(lpFileName: String): Cardinal;
- external 'GetFileAttributes{#A}@kernel32.dll stdcall';
- function SetFileAttributes(lpFileName: String; dwFileAttributes: Cardinal): Boolean;
- external 'SetFileAttributes{#A}@kernel32.dll stdcall';
- function IsLineInFile(sItem: string; sl: TStringList; var LineNo, Cnt: LongInt): Boolean;
- var
- s: String;
- n: Integer;
- begin
- Result := false;
- LineNo := 0; // 行号
- Cnt := 0; // 计数器
- for n:= 0 to sl.Count-1 do
- if Pos(sItem, Trim(sl.Strings[n])) = 1 then
- begin
- Result := true;
- LineNo := n + 1;
- s := Trim(sl.Strings[n]);
- if Pos('##', s) > 0 then
- begin
- Delete(s, 1, Pos('##', s)+1);
- if Pos(' ', s) > 0 then
- s := Copy(s, 1, Pos(' ', s)-1);
- Cnt := StrToIntDef(s, 0);
- end;
- exit;
- end;
- end;
- procedure StartAddHosts();
- begin
- AddHostsItemList := TStringList.Create;
- AddHostsCommentList := TStringList.Create;
- end;
- procedure AddHosts(newItem, comments: string);
- begin
- AddHostsItemList.Add(newItem);
- AddHostsCommentList.Add(comments);
- end;
- procedure EndAddHosts();
- var
- stl: TStringList;
- fs: TFileStream;
- OldFileAttribute: Cardinal;
- hfPath, newItem, comments, s: string;
- LineNo, Cnt, n: LongInt;
- begin
- hfPath := ExpandConstant('{sys}\drivers\etc\hosts');
- OldFileAttribute := GetFileAttributes(hfPath);
- SetFileAttributes(hfPath, FILE_ATTRIBUTE_NORMAL);
- stl := TStringList.Create;
- stl.LoadFromFile(hfPath);
- try
- for n:= 0 to AddHostsItemList.Count-1 do
- begin
- newItem := AddHostsItemList.Strings[n];
- comments := AddHostsCommentList.Strings[n];
- if IsLineInFile(newItem, stl, LineNo, Cnt) then // 检查 Hosts 中是否有该项
- begin
- s := stl.Strings[LineNo-1];
- if Cnt = 0 then
- StringChangeEx(s, newItem, newItem + ' ##2', true) // 如果有项目,但是没有计数,说明是别人已经添加的项目,计数从 2 开始
- else
- StringChangeEx(s, newItem + ' ##' + IntToStr(Cnt), newItem + ' ##' + IntToStr(Cnt+1), true); // 计数加 1
- stl.Strings[LineNo-1] := s;
- end
- else
- begin // Hosts 中还没有该项
- s := newItem + ' ##1 ID' + myMark; // 计数从 1 开始,ID标识
- if Trim(comments) > '' then // 检查注释是否为空白
- s := s + ' / ' + Trim(comments);
- stl.Add(s);
- end;
- end;
- finally
- AddHostsItemList.Free;
- AddHostsCommentList.Free;
- end;
- fs := TFileStream.Create(hfPath, fmCreate);
- try
- stl.SaveToStream(fs);
- fs.Size := fs.Size - Length(#13#10); // 删除最后的换行符
- finally
- stl.Free;
- fs.Free;
- end;
- SetFileAttributes(hfPath, OldFileAttribute);
- end;
- procedure StartRemoveHosts();
- begin
- RemoveHostsList := TStringList.Create;
- end;
- procedure RemoveHosts(sItem: string);
- begin
- RemoveHostsList.Add(sItem);
- end;
- procedure EndRemoveHosts();
- var
- OldFileAttribute: Cardinal;
- hfPath, sItem, s: string;
- stl: TStringList;
- fs: TFileStream;
- LineNo, Cnt, n: LongInt;
- begin
- hfPath := ExpandConstant('{sys}\drivers\etc\hosts');
- OldFileAttribute := GetFileAttributes(hfPath);
- SetFileAttributes(hfPath, FILE_ATTRIBUTE_NORMAL);
- stl := TStringList.Create;
- stl.LoadFromFile(hfPath);
- try
- for n:= 0 to RemoveHostsList.Count-1 do
- begin
- sItem := RemoveHostsList.Strings[n];
- if IsLineInFile(sItem, stl, LineNo, Cnt) then // 检查 Hosts 中是否有该项
- if Cnt > 0 then
- begin
- if Cnt = 1 then
- stl.Delete(LineNo-1) // 计数是 1 的项将被删除
- else
- begin
- s := stl.Strings[LineNo-1];
- if (Cnt = 2) and (Pos('ID'+myMark, s) = 0) then // 如果计数是 2,但是没有标识,说明是别人添加的项,将恢复原状
- StringChangeEx(s, sItem + ' ##2', sItem, true)
- else
- StringChangeEx(s, sItem + ' ##' + IntToStr(Cnt), sItem + ' ##' + IntToStr(Cnt-1), true); // 计数减 1
- stl.Strings[LineNo-1] := s;
- end;
- end;
- end;
- finally
- RemoveHostsList.Free;
- end;
- fs := TFileStream.Create(hfPath, fmCreate);
- try
- stl.SaveToStream(fs);
- fs.Size := fs.Size - Length(#13#10); // 删除最后的换行符
- finally
- stl.Free;
- fs.Free;
- end;
- SetFileAttributes(hfPath, OldFileAttribute);
- end;
- function GetHKLM: Integer;
- begin
- if IsWin64 then
- Result := HKLM32
- else
- Result := HKLM;
- end;
- function WasTaskSelected(aTask, AppID: String): boolean;
- var
- sSelectedTasks, sTask: String;
- begin
- Result := false;
- sSelectedTasks := '';
- if RegQueryStringValue(getHKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+AppID+'_is1',
- 'Inno Setup: Selected Tasks', sSelectedTasks) then
- begin
- sSelectedTasks := Uppercase(sSelectedTasks);
- sTask := Uppercase(aTask);
- if Pos(',', sSelectedTasks) = 0 then
- Result := sSelectedTasks = sTask
- else
- begin
- if Pos(sTask+',', sSelectedTasks) = 1 then
- Result := true;
- if Pos(','+sTask+',', sSelectedTasks) > 0 then
- Result := true;
- if Pos(','+sTask, sSelectedTasks) = Length(sSelectedTasks) - Length(sTask) then
- Result := true;
- end;
- end;
- end;
- procedure CurStepChanged(CurStep: TSetupStep );
- begin
- if CurStep = ssPostInstall then // 安装文件前检查
- if IsTaskSelected('noad') then // 是否选择了相应的任务
- begin
- StartAddHosts; // 开始添加项目(必需)
- AddHosts('127.0.0.1 www.abcd.com', '你的注释'); // 添加要增加的项目,带注释
- AddHosts('127.0.0.1 www.abcd.net', ''); // 添加要增加的项目,不带注释
- EndAddHosts; // 结束添加项目(必需)
- end;
- end;
- procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep );
- begin
- if CurUninstallStep = usUninstall then // 卸载文件前检查
- if WasTaskSelected('noad', '{#AppID}') then // 安装时是否选择了相应的任务
- begin
- StartRemoveHosts; // 开始删除项目(必需)
- RemoveHosts('127.0.0.1 www.abcd.com'); // 添加要删除的项目
- RemoveHosts('127.0.0.1 www.abcd.net'); // 添加要删除的项目
- EndRemoveHosts; // 结束删除项目(必需)
- end;
- end;
复制代码
|