65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 友好的 Shell_NotifyIcon 包装类 - 第四部分:广告拦截器后端

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2020 年 12 月 2 日

CPOL

9分钟阅读

viewsIcon

5587

downloadIcon

246

介绍一个方便的广告拦截应用程序的前端,该应用程序位于通知图标后面。

引言

本文将带您了解我在为 Windows 10 桌面构建广告拦截器后端时所探索的各种主题。我的主要目标是创建一个可以通过单击通知图标来启用或禁用广告拦截器。

本文(第 4 部分:广告拦截器后端)是 NotifyIconLibrary 的实际应用示例。在这里,我们将看到产品的“核心部分”、安装程序和数据库维护过程。

背景

广告拦截

我早就知道一种拦截互联网广告的最简单方法。与我曾经使用的第一个广告拦截器(它会分析和重写浏览器插件看到的网页内容)不同,这种方法不会过度扩展其能力,也不会弄乱页面内容。此外,现在有这么多非浏览器应用程序使用自己的 API,并且完全绕过浏览器,因此需要阻止绕过浏览器的互联网流量。

我所指的技术是替换 drivers.etc.hosts 文件。操作系统使用此文件来检测需要更改的路由,例如本地网络上的主机路由。这种重路由发生在域名和 IP 地址之间的转换过程中。为了达到特定的阻止目的,而不是重路由 DNS 翻译,要阻止的所有域名的主机文件条目都将被设置为 0.0.0.0 的 IP 地址(或等效的 IPv6 地址)。

Winhelp 2002 组织一直在收集有价值的要阻止的域名列表:据推测自 2002 年以来。当前列表可在 winhelp2002.mvps.org.txt 找到。该列表会定期更新。我已经获取了该列表的最新版本,并在文件开头添加了我自己的几项条目供本项目使用。我可以写另一整篇文章来介绍收集这些条目的技术,也许我也会这样做。

障眼法

替换 c:\windows\system32\drivers\etc\hosts 并不容易。要手动执行此操作,您可以先以本地管理员身份登录并打开一个提升的命令提示符。由于当前目录已设置为 c:\windows\system32,您可以 `cd` 到 drivers\etc。从那里,您就可以轻松地将新版本的 hosts 复制到现有文件上,或使用记事本在原地编辑 hosts。

自动化此过程则完全是另一回事。Windows 的设计使得在没有手动干预的情况下无法提升进程。我找到的最佳方法是使用任务计划程序提交一个运行预定义和预注册任务的请求。如果您运行的任务设置为在 SYSTEM 帐户下运行,则它将在非交互式窗口站中运行,因此无法实现用户界面。如果您将任务配置为在您的某个管理员帐户下运行,则您要么每次激活任务时都必须输入密码,要么将密码留在容易受到攻击的地方。如果您更改了密码,则需要在任务激活代码中更改它。由于我们尝试提升任务的运行权限,因此甚至可能有一个需要手动关闭的提升对话框。我尝试这个已经很久了,我记不起所有细节了。由于我的计划是让任务在我登录时自动激活,因此当时处理弹出窗口似乎不是一个好主意。

我尝试的另一种方法是使用客户端/服务器架构。这会导致客户端和服务器的独立安装。我必须在安装程序中将端口设为可配置,以便客户端和服务器可以通过未使用过的端口进行通信。总的来说,这效果不错,但服务器偶尔会出错并拒绝与客户端通信。为了使我的协议万无一失,需要比我想要的更多的工作,所以我放弃了这种方法。

我的下一步是接受安装、启动和卸载过程需要明确提升权限的现实。这使得这个问题一直延续到今天。

通知图标

我受到 Kevin Sacro 编写的一款名为“SystemTrayApp”的程序的启发,该程序是一款通知图标。您可以在 https://github.com/kesac/SystemTrayApp 上找到它。我整体采用了这段代码,然后根据需要开始删除和替换各种部分。

这项工作的结果之一是 NotifyIconLibrary,我们在本系列 第 1 部分 中已经看到了。我的工作还产生了 AdBlockerLibraryAdBlockerTest,我们在本系列 第 3 部分 中已经看到了。在本系列的这一部分,我们将看看 AdBlocker,即广告拦截器的后端,也是最后的谜题。

Using the Code

作为最终用户,使用代码非常简单:找到 AdBlockerAny.msi 并将其复制到更合适的位置进行安装。在文件资源管理器中双击此文件,或使用您喜欢的方法启动。我不会列出十二种不同的方法,也不会举办比赛看谁能找到最晦涩的启动方式。

提升权限后,接受所有默认选项,除非您知道有其他原因不这样做。安装应该很快。安装完成后,每次重新启动或登录后,您都应该考虑使用桌面图标或开始菜单图标(红绿交通信号灯)来启动应用程序。您每次这样做时都需要提升权限。或者,您也可以等到要更改广告拦截状态时再执行。

应用程序启动后,您会在任务栏上找到一个交通信号灯形式的通知图标。如果您是安装后第一次启动应用程序,交通信号灯将是绿色的。如果不是,交通信号灯将显示红色或绿色,具体取决于您上次的设置。几秒钟后,通知图标将迁移到通知区域。这是您单击任务栏上的“^”符号时显示的矩形弹出窗口。您可以双击通知图标来反转交通信号灯的设置。红色(停止)表示广告当前被阻止。绿色(前进)表示广告当前未被阻止。您还可以使用键盘通过按 Windows+B 然后按若干次向右箭头键来导航到通知图标或任务栏上的“^”符号。如果通知图标被隐藏,一旦您到达“^”符号,请按空格键打开通知区域。然后使用箭头键导航到通知图标。现在您可以使用上下文菜单键或 Enter 键打开应用程序的上下文菜单。您可以使用向上和向下箭头键在上下文菜单中导航,或使用 Escape 键关闭上下文菜单。您也可以通过右键单击通知图标来打开上下文菜单。您可以使用 Enter 键或单击所需的项目来从上下文菜单中选择一个项目。有四个项目

  1. 阻止项目会阻止广告
  2. 取消阻止选项会取消阻止广告
  3. 关于选项会打开关于对话框
  4. 退出选项会关闭上下文菜单,移除通知图标并退出应用程序。

您可以通过单击“X”或按 Escape 键关闭关于对话框。

为了继续阻止广告,不需要在登录或重启时启动应用程序。只有在您想验证或更改当前设置时才需要这样做。登出或重启时也不需要显式退出应用程序。即使是断电,只要不损坏文件系统,就不会影响应用程序的持续运行。

有时,您可能会发现阻止某个特定域名会产生一些不良副作用。您可以通过禁用广告拦截器并重试来解决此类情况,也许是通过刷新浏览器屏幕。如果这不是一个令人满意的解决方案,您可以注释掉 c:\windows\system32\drivers\etc\hosts.blocked 文件中的 offending 行,如果广告拦截器当前处于阻止状态,则取消阻止广告,然后使用 AdBlocker 阻止广告。如果这仍不能提供令人满意的结果,您可能需要阻止单个子域名,只留下不安全阻止的子域名。这需要一些侦探工作,这是一个另一篇文章的主题。

如果您对您的更改感到满意,请将您编辑的 hosts.blocked 文件复制到您的 Ad Blocker 构建项目中并重新构建,这样您在下次安装 Ad Blocker 时就会做好准备。

关注点

如果您从未为 .NET 程序创建过安装程序,您可能会从查看源代码中提供的两个示例中受益。AdBlockerSetupAny 可与 Any 配置的发布版本生成的​​文件一起使用。在设置项目上下文菜单中选择构建选项之前,选择构建和配置。生成的 .msi 文件可以在任何 Windows 10 系统上运行,以在 32 位或 64 位环境中安装 AdBlocker。同样,AdBlockerSetupX64 可与 X64 配置的发布版本生成的​​文件一起使用。生成的 .msi 文件仅适用于 Windows 10 的 X64 版本。

如果该主题有足够多的兴趣,我可以再写一篇关于使用安装程序与自定义任务(例如,在这种情况下,为了提升安装过程的一部分)的文章。

此应用程序提供了国际化所需的基本工具。只需在与提供的 en-US 版本相同的文件夹中创建具有正确名称的重复资源文件即可。这是一个有点争议的做法,但我已将所有 .resx 文件直接放在每个项目下的 Properties 文件夹中。有些人可能更喜欢在每个项目下直接使用 Resources 文件夹。如果 .resx 文件的名称形式为:LocalizedResources.resx,则其英文(英国)版本必须命名为:LocalizedResources.en-GB.resx。使用资源编辑器修改其中显示的第一个列以获得正确的翻译。构建项目将创建必需的子文件夹和附属程序集。这有点像命名噩梦,但当您将新功能强加于现有结构并要求向后兼容时,这就是您会得到的结果。不要忘记翻译您使用过的每个程序集中的资源文件。对于 AdBlocker,程序集是 AdBlockerAdBlockerLibraryAppWrapperNotifyIconLibrary

这是本系列的最后一篇文章。希望您和我一样喜欢阅读它。

历史

  • 2020 年 12 月 1 日:初始版本
© . All rights reserved.