论坛风格切换切换到宽版
  • 10065阅读
  • 36回复

请教老虎版主通过附加任务屏蔽hosts问题 [复制链接]

上一主题 下一主题
离线546242502
 

发帖
332
金钱
-3060
威望
-306
只看楼主 倒序阅读 0 发表于: 2015-08-21
原帖地址:http://bbs.hanzify.org/read-htm-tid-97864.html
想请教老虎版主,为什么不能再卸载时删除写入 hosts 的内容?自己找不到问题出在哪儿?

  1. #ifdef Unicode
  2. #define A "W"
  3. #else
  4. #define A "A"
  5. #endif
  6. #define AppID "My Program"
  7. [Setup]
  8. AppName=My Program
  9. AppVersion=1.5
  10. DefaultDirName={pf}\My Program
  11. DefaultGroupName=My Program
  12. UninstallDisplayIcon={app}\MyProg.exe
  13. [Tasks]
  14. Name: "PATCHhosts"; Description: "屏蔽hosts"; GroupDescription:"其它任务"; Flags: checkedonce


  1. [code]
  2. var
  3. //当没有选择语言时,禁用下一步
  4. OldEvent_ComponentsListClickCheck: TNotifyEvent;
  5. //屏蔽 hosts 段开始
  6. const
  7. myMark = '546242502';    // 作为标识,用来标识你修改的内容
  8. function GetFileAttributes(lpFileName: String): Cardinal;
  9.    external 'GetFileAttributes{#A}@kernel32.dll stdcall';
  10. function SetFileAttributes(lpFileName: String; dwFileAttributes: Cardinal): Boolean;
  11.    external 'SetFileAttributes{#A}@kernel32.dll stdcall';
  12. function LineInFile(sItem, fPath: string): Boolean;
  13. var
  14.    aos: TArrayOfString;
  15.    i: Integer;
  16. begin
  17.    Result:= false;
  18.    if LoadStringsFromFile(fPath, aos) then
  19.       for i:= 0 to GetArrayLength(aos)-1 do
  20.          if Pos(sItem, TrimLeft(aos[i])) = 1 then
  21.             begin
  22.                Result := true;
  23.                Exit;
  24.             end;
  25. end;
  26. procedure AddHosts(newItem, comments: string);
  27. var
  28.    OldFileAttribute: Cardinal;
  29.    hfPath, newLine: string;
  30. begin
  31.    hfPath := ExpandConstant('{sys}\drivers\etc\hosts');
  32.    if not LineInFile(newItem, hfPath) then          // 仅添加 Hosts 中还没有的项目
  33.       begin
  34.          OldFileAttribute := GetFileAttributes(hfPath);
  35.          SetFileAttributes(hfPath, FILE_ATTRIBUTE_NORMAL);
  36.          newLine := newItem + ' # ' + myMark;
  37.          If comments > ' ' then
  38.             newLine := newLine + ' / ' + comments;
  39.          SaveStringToFile(hfPath, #13#10 + newLine, true);
  40.          SetFileAttributes(hfPath, OldFileAttribute);
  41.       end;
  42. end;
  43. procedure RemoveHosts(sItem: string);
  44. var
  45.    OldFileAttribute: Cardinal;
  46.    hfPath, newLine: string;
  47.    s: AnsiString;
  48.    stl: TStringList;
  49.    i: LongInt;
  50. begin
  51.    hfPath := ExpandConstant('{sys}\drivers\etc\hosts');
  52.    OldFileAttribute := GetFileAttributes(hfPath);
  53.    SetFileAttributes(hfPath, FILE_ATTRIBUTE_NORMAL);
  54.    newLine := sItem + ' # ' + myMark;
  55.    stl := TStringList.Create;
  56.    stl.LoadFromFile(hfPath);
  57.    for i:= stl.Count-1 downto 0 do
  58.       if Pos(newLine, TrimLeft(stl.Strings[i])) = 1 then
  59.          stl.Delete(i);
  60.    s := stl.Text;
  61.    SetLength(s, Length(s)-Length(#13#10));
  62.    SaveStringToFile(hfPath, s, false);
  63.    stl.Free;
  64.    SetFileAttributes(hfPath, OldFileAttribute);
  65. end;
  66. function WasTaskSelected(sTask, AppID: String): boolean;
  67. var
  68.    sSelectedTasks: String;
  69. begin
  70.    Result := false;
  71.    sSelectedTasks := '';
  72.    if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+AppID+'_is1',
  73.                                           'Inno Setup: Selected Tasks', sSelectedTasks) then
  74.       begin
  75.          if Pos(',', sSelectedTasks) = 0 then
  76.             Result := sSelectedTasks = sTask
  77.          else
  78.             begin
  79.                if Pos(sTask+',', sSelectedTasks) = 1 then
  80.                   Result := true;
  81.                if Pos(','+sTask+',', sSelectedTasks) > 0 then
  82.                   Result := true;
  83.                if Pos(','+sTask, sSelectedTasks) = Length(sSelectedTasks) - Length(sTask) then
  84.                   Result := true;
  85.             end;
  86.       end;
  87. end;
  88. //屏蔽 hosts 段结束
  89. procedure CurStepChanged(CurStep: TSetupStep );
  90. begin
  91. //屏蔽 hosts 代码
  92. if CurStep = ssPostInstall then             // 安装文件前检查
  93.       if IsTaskSelected('PATCHhosts') then            // 是否选择了相应的任务
  94.          begin
  95.             AddHosts('127.0.0.1 support.wondershare.net', '');          // 在 Hosts 中添加新项目,带注释
  96.             AddHosts('127.0.0.1 www.wondershare.net', '');                      // 在 Hosts 中添加新项目,不带注释
  97.             AddHosts('127.0.0.1 support.wondershare.com', '');
  98.             AddHosts('127.0.0.1 www.wondershare.com', '');
  99.             AddHosts('127.0.0.1 cbs.wondershare.com', '');
  100.          end;
  101. end;
  102. procedure CurUninstallStepChanged1(CurUninstallStep: TUninstallStep);
  103. begin
  104.   //屏蔽 hosts 代码
  105.   if (CurUninstallStep = usPostUninstall) and (WasTaskSelected('PATCHhosts', '{#AppID}')) then    // 卸载文件前检查
  106.             RemoveHosts('127.0.0.1 support.wondershare.net');            // 从 Hosts 中删除项目
  107.             RemoveHosts('127.0.0.1 www.wondershare.net');            // 从 Hosts 中删除项目
  108.             RemoveHosts('127.0.0.1 support.wondershare.com');            // 从 Hosts 中删除项目
  109.             RemoveHosts('127.0.0.1 www.wondershare.com');            // 从 Hosts 中删除项目
  110.             RemoveHosts('127.0.0.1 cbs.wondershare.com');            // 从 Hosts 中删除项目
  111. end;
  112. procedure CurUninstallStepChanged2(CurUninstallStep: TUninstallStep);
  113. begin
  114.   //卸载时提醒用户是否清理残留
  115.   if CurUninstallStep = usDone then
  116.   if MsgBox(CustomMessage('cmcleanhint'), mbConfirmation, MB_YESNO) = IDYES then
  117.   //删除文件夹及其中所有文件
  118.   DelTree(ExpandConstant('{app}'), True, True, True);
  119. end;



离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 1 发表于: 2015-08-22
问题应该是 WasTaskSelected 中,你搜索的注册表位置不对。64位系统下运行32位应用程序,注册表的位置是在 WOW6432NODE 下。具体参看帮助文件。
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 2 发表于: 2015-08-22
回 1楼(gnatix) 的帖子
老虎版主,好像不是注册表问题,
第一:
inno 在64 为系统好像会自动处理 WOW6432NODE ,比如说提取旧版代码,

  if RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XXXX_is1', 'UninstallString', uicmd) then
inno 在 SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ 下找不到会自动又到:
SOFTWARE\WOW6432NODE\Microsoft\Windows\CurrentVersion\Uninstall\ 下寻找,测试是这样;
第二:
我测试原来的脚本,可以实现写入和删除,好像就是这段代码的原因,但是又不知道是怎么回事?,procedure CurUninstallStepChanged 里面只有删除hosts 中网址的代码就能删除一些
  1. procedure CurUninstallStepChanged1(CurUninstallStep: TUninstallStep);
  2. begin
  3.   //屏蔽 hosts 代码
  4.   if (CurUninstallStep = usPostUninstall) and (WasTaskSelected('PATCHhosts', '{#AppID}')) then    // 卸载文件前检查
  5.             RemoveHosts('127.0.0.1 support.wondershare.net');            // 从 Hosts 中删除项目
  6.             RemoveHosts('127.0.0.1 www.wondershare.net');            // 从 Hosts 中删除项目
  7.             RemoveHosts('127.0.0.1 support.wondershare.com');            // 从 Hosts 中删除项目
  8.             RemoveHosts('127.0.0.1 www.wondershare.com');            // 从 Hosts 中删除项目
  9.             RemoveHosts('127.0.0.1 cbs.wondershare.com');            // 从 Hosts 中删除项目
  10. end;
  11. procedure CurUninstallStepChanged2(CurUninstallStep: TUninstallStep);
  12. begin
  13.   //卸载时提醒用户是否清理残留
  14.   if CurUninstallStep = usDone then
  15.   if MsgBox(CustomMessage('cmcleanhint'), mbConfirmation, MB_YESNO) = IDYES then
  16.   //删除文件夹及其中所有文件
  17.   DelTree(ExpandConstant('{app}'), True, True, True);
  18. end;





离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 3 发表于: 2015-08-22
帖子已被编译
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 4 发表于: 2015-08-22
回 3楼(gnatix) 的帖子
gnatix:检查后发现,INNO 本身有 Bug,在卸载部分, RegQueryStringValue 不能正确工作。 (2015-08-22 13:43) 

老虎版主,最新版修正了没?,我用的是 Restools 5.5.1 增强版
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 5 发表于: 2015-08-22
再仔细检查了你的代码。问题不是 INNO 的 Bug,而是你读取注册表是时候太晚了,你是在注册表中的内容已经删除后再去读取的(usPostUninstall),所以判断结果不对。建议
if (CurUninstallStep = usUninstall) and (WasTaskSelected('PATCHhosts', '{#AppID}')) then    // 卸载文件前检查
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 6 发表于: 2015-08-22
回 5楼(gnatix) 的帖子
gnatix:再仔细检查了你的代码。问题不是 INNO 的 Bug,而是你读取注册表是时候太晚了,你是在注册表中的内容已经删除后再去读取的(usPostUninstall),所以判断结果不对。建议 if (CurUninstallStep = usUninstall .. (2015-08-22 15:32) 

老虎版主,起初就是这种方式,我都试,没效果
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 7 发表于: 2015-08-22
回 5楼(gnatix) 的帖子
老虎版主,最开始就是这样:
  1. procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
  2. begin
  3.   //屏蔽 hosts 代码
  4.   if CurUninstallStep = usUninstall then    // 卸载文件前检查
  5.       if WasTaskSelected('NOOUT', '{#AppID}') then    // 安装时是否选择了相应的任务
  6.          begin
  7.             RemoveHosts('127.0.0.1 support.wondershare.net');            // 从 Hosts 中删除项目
  8.             RemoveHosts('127.0.0.1 www.wondershare.net');            // 从 Hosts 中删除项目
  9.             RemoveHosts('127.0.0.1 support.wondershare.com');            // 从 Hosts 中删除项目
  10.             RemoveHosts('127.0.0.1 www.wondershare.com');            // 从 Hosts 中删除项目
  11.             RemoveHosts('127.0.0.1 cbs.wondershare.com');            // 从 Hosts 中删除项目
  12.          end;
  13.   if CurUninstallStep = usDone then
  14.   begin
  15.   if MsgBox('是否清除项目文件及配置文件,请注意备份!', mbConfirmation, MB_YESNO) = IDYES then
  16.   //删除文件夹及其中所有文件
  17.   DelTree(ExpandConstant('{app}'), True, True, True);
  18.   end;
  19. end;


离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 8 发表于: 2015-08-22
肯定可以。我用你以前的代码测试过。
你把你现在的脚本文件作为附件发上来看看。
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 9 发表于: 2015-08-22
回 8楼(gnatix) 的帖子
脚本文件:
见上