系统出现大量HTTP Auto Proxy Detection Worker Process

作者 | 2019年2月7日

如果不关心原理细节,可直接下载本人编译好的客户端修复版:Shadowsocks/SS修复版 ShadowsocksR/SSR修复版

今天打开任务管理器,发现有大量“HTTP Auto Proxy Detection Worker Process”进程,画风如下:

根据进程名称,应该和代理有关,因为电脑上开着Shadowsocks。但是这么多什么鬼?打群架吗?

退出SS程序,发现这些进程不会随之退出。意识到这超出了我的知识范围,于是马上打开Google学学。根据有限的搜索结果,基本上确认和SS有关,并且仅会出现在1809版的Windows 10上。于是打开电脑属性,确认了系统是1809版的bug10:

花了一个多小时理解WPADPACpacjsworker.exe关系,并加上自己反复测验,得到一些结论:

  1. HTTP Auto Proxy Detection Worker Process进程的程序文件是”C:\Windows\System32\pacjsworker.exe”,由WPAD服务启动;
  2. 这些进程不能手工杀死,重启系统才能解决,用户退出(logout)再登录也不行;
  3. WPAD服务(Win HTTP Web Proxy Auto Discovery Service)的属性不能修改,通过重启WPAD服务杀死进程的路也不通;
  4. 1809版本才会出现,在这之前版本的系统上运行正常;根据Twitter链接https://twitter.com/epakskape/status/1007316208087994368,应该是build 17692引入新功能导致;
  5. 情况复现:打开SS客户端,选择PAC模式,勾选启用系统代理;然后按电源键(或其他方式)让电脑进入休眠;接着唤醒电脑进入桌面,任务管理器中就多了一个HTTP Auto Proxy Detection Worker Process进程;如此反复进入休眠又启动,每次都会出现一个新进程;
  6. 后来发现不需要休眠也能复现情况:打开SS客户端,选择PAC模式,打开任务管理器;然后不断禁用/启用系统代理,在任务管理器窗口中可实时看到每次启用系统代理后都会多一个进程;
  7. 最新版的SS客户端依然有这个问题;
  8. 每次SS启动系统代理后的PAC地址均不同;
  9. PAC地址中的secret参数仅在勾选“保护本地PAC(secure local PAC)”选项时才会出现,但t参数一直都在。

根据网上知识,加上个人实验和思考,对问题原因的理解为:WPAD是系统关键服务,用户不能更改;以PAC模式启动SS时,SS会在LAN配置中设置一个新的PAC脚本地址;WPAD检测到有新的PAC脚本地址,唤醒一个新的pacjsworker.exe进程监听该地址;PAC地址失效后,监听进程不退出,于是进程堆积,慢慢出现几十上百个进程的壮观场景。

总结问题根源:1. Windows 10的进程不自动退出;2. 每次从休眠过来后,SS客户端生成不同的PAC地址并将其配置到LAN设置中。

把问题搞清楚了,解决方案基本上章口就莱:

  1. 使用全局模式;全局模式不会设置PAC配置脚本,WPAD服务也就不会拉起新的进程;
  2. 等待巨硬修复问题;去年下半年就爆出问题,到现在问题依旧,应该有得等(本人最近才更新1809版本,故而发现得迟);另外我不认为这是巨硬的锅,他们未必会修复;
  3. 重新编译SS客户端,生成相同的PAC(至少未重启SS客户端前PAC地址应一致)。

我的解决方案是重新编译SS客户端,根据 @Joelism 的提示及自己理解,做了两个方案的客户端:

  1. 方案一:总是生成相同的PAC地址,除非人工编辑”pac-secret.txt”文件。改动代码如下:

    // 文件: shadowsocks-csharp\Controller\Service\PACServer.cs
    public void UpdateConfiguration(Configuration config)
    {
        this._config = config;
    
        if (config.secureLocalPac) {
            // 注释掉部分
            // var rd = new byte[32];
            // RNG.GetBytes(rd);
            // PacSecret = $"&secret={Convert.ToBase64String(rd)}";
            if (!File.Exists(PAC_SECRET_FILE)) { 
                var rd = new byte[32]; 
                RNG.GetBytes(rd); 
                string secret = Convert.ToBase64String(rd); 
                PacSecret = $"secret={secret}"; 
                File.WriteAllText(PAC_SECRET_FILE, secret); 
            } else { 
                PacSecret = $"secret={File.ReadAllText(PAC_SECRET_FILE)}"; 
            } 
        } else { 
            PacSecret = ""; 
        } 
        // 注释掉部分 
        // PacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{PacSecret}"; 
        PacUrl = $"http://127.0.0.1:{config.localPort}/pac?{PacSecret}"; 
    }
    

    这个方案保证不管系统休眠重启,还是退出SS客户端再打开,都只会有一个HTTP Auto Proxy Detection Worker Process进程。

  2. 方案二: 仅当系统中无PAC进程运行时才生成新的PAC地址并设置到LAN中。代码如下:

    // 文件: shadowsocks-csharp\Controller\ShadowsocksController.cs
    protected void Reload()
    {
        Encryption.RNG.Reload();
        // some logic in configuration updated the config when saving, we need to read it again
        _config = Configuration.Load();
        StatisticsConfiguration = StatisticsStrategyConfiguration.Load();
    
        if (privoxyRunner == null) { 
            privoxyRunner = new PrivoxyRunner(); 
        } 
        if (_pacServer == null) { 
            _pacServer = new PACServer(); 
            _pacServer.PACFileChanged += pacServer_PACFileChanged; _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged; 
            // 这一行代码从外部移入 
            _pacServer.UpdateConfiguration(_config); 
        } 
        // 每次唤醒都更新的代码删除 
        // _pacServer.UpdateConfiguration(_config); 
        if (gfwListUpdater == null) { 
            gfwListUpdater = new GFWListUpdater(); 
            gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; 
        } 
        ... 
    }
    

    这个方案保证不退出SS客户端情况下只有一个pacjsworker.exe进程。缺点是如果频繁退出并重启SS客户端,同样会出现有大量进程的现象。

根据源代码思路,我认为第二种方案更合理,是原作者想要的。当然你应该想得到,我是先根据网上提示实现方案一,测试达到效果后继续思考才做出的方案二。从这个角度也是方案二更合理。

两个方案的exe文件我都编译好了,需要请自取:方案一 方案二

如果你用的SSR,请到这个页面下载:ShadowsocksR/SSR修复版

稍后我会发一个pull request到官方库,使用方案二修复该问题。

问题相关网页

打赏 赞(56)
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

系统出现大量HTTP Auto Proxy Detection Worker Process” 有 25 条评论

  1. 头像Ao

    HTTP Auto Proxy Detection Worker Process 这个进程关不了 怎么办 楼上的方法都试过了 都不行

    回复
    1. tlanyantlanyan 作者

      开pac代理就会有一个,彻底关掉建议这么做:1. 禁止ss/ssr等代理软件的自动启动;2. 重启系统

      回复
  2. 头像outlook

    你好,非常感谢站长修复了这个问题,希望站长能更新SSR修复版到最新的版本v4.9.2,因为新版新增了切换服务器前断开所有连接的功能,非常实用方便的一个功能,希望在修复版上也能用到这个功能,谢谢。

    回复
  3. 头像alex romance

    今天升级到1903,特来跟楼主反馈一下,原版的4.9.0依旧会出现大量的HTTP Auto Proxy Detection Worker Process进程(我是升级上来的,不是全新安装,18362.175)。楼主你的则不会出现此问题。

    回复
  4. 头像function

    楼主救命!
    今天发现如楼主所说的20多个HTTP Auto… 进程在 任务管理器 里,WIN版本也是1809的(17763.437),之前用的是SS 416版。
    然后,按楼主所说,先关掉SS,然后关机(断电),开机,问题来了:还没等我启动楼主的SS414或者415版呢,先打开任务管理器一看,20多个HTTP Auto… 进程一个不少全在里边!
    这咋整?什么都没运行呢,SS也没运行,开机就出现全部的HTTP Auto…,这日子没法活了啊!😭

    回复
      1. 头像function

        谢谢!不过无论是旧版本,还是您这个415版,都没有安装过,是直接绿色运行使用的,当时也是直接关闭和删除了旧版的。
        现在已经正常使用您的415版。
        给后来者的经验:我找到的解决方法是,在 任务管理器 里,虽然无法直接关掉那堆HTTP Auto…,但是可以在 详细信息 里,把pacjsworker.exe进程关掉,这样所有的HTTP Auto…也就都没了。然后再重启,启动415,设为开机自启,就全好了。

        回复
  5. 头像安徒

    大佬,我现在一开机就占了7g内存,HTTP Auto Proxy Detection Worker Process进程管理器结束不了重启和切换pac都关不了,该怎么关啊

    回复
    1. tlanyantlanyan 作者

      你需要重启电脑(真正意义上的重启,不是休眠/睡眠再唤醒),然后用我给出的客户端就能避免这个问题

      回复
  6. 头像alex romance

    本机win10 1809,所以默认使用的应该是dotnet4.0的组件,而且运行官方版本的dotnet4.0的ssr没有出现需要下载dotnet3.5包括2.0的提示。我对比您打包的exe,dotnet4.0和dotnet2.0的两个exe文件大小一致,但是官方版本的两个exe大小是不同的。所以是不是您的打包选项还有点问题。最后两个问题哈,一个是现在的官方库地址麻烦告知一下好么,另一个是您pull 到官方库的进度怎么样了?

    回复
  7. 头像alex romance

    你好,下载您的ssr修复版后,使用dotnet4.0提示需要下载framework3.5包括2.0 ,但是dotnet2.0也是提示需要下载framework3.5包括2.0,那4.0那版是不是有什么问题

    回复
      1. 头像alex romance

        我试过你发的官方版那个dotnet4.0的,那个是不需要提示下载framework3.5包括2.0,本机是win10 1809的,所以应该默认使用的是dotnet4.0的组件的。而且我查看您的打包好的,3个exe文件大小是一样的。。。但是那个官方版本的dotnet2.0 和 dotnet4.0版本的两个exe是文件大小不一样的

        回复
      2. 头像alex romance

        本机是win10 1809的,所以默认应该是用的dotnet4.0的组件,使用那个官方版本的dotnet4.0就没提示需要下载组件,而且您打包的dotnet2.0和dotnet4.0的两个exe文件大小是一致的,但是官方版本的两个exe文件大小是不一致的

        回复
      3. 头像alex romance

        本机win10 1809,所以默认使用的应该是dotnet4.0的吧,麻烦大佬告知一下目前官方库的地址。

        回复
        1. tlanyantlanyan 作者

          Shadowsocks官方仓库:https://github.com/shadowsocks/shadowsocks-windows
          ShadowsocksR官方仓库:https://github.com/shadowsocksrr/shadowsocksr-csharp。提示:SSR官方已经停止开发。

          根据SS官方的issue,大量pacjsworker.exe的bug在即将发布的新版中会自动消失,似乎没有修复的必要,SS官方开发hold住了我的pull,等待新版发布并确认。

          你反馈的SSR编译文件问题,有空我会查看,谢谢。

          回复
          1. 头像alex romance

            不好意思啊。之前可能是网络有问题,以为没回复到,所以回复了很多遍,实在是不好意思啊,麻烦您把多余的删掉即可。谢谢

发表评论

电子邮件地址不会被公开。 必填项已用*标注