C# 实现向浏览器的兼容性视图列表中添加、删除网站和检查网站是否在兼容性网站列表中

2023-05-16

今天回答论坛上的一个问题,搜索了一下网上,并没有找到一个完整的例子,下面根据网上的一些资料,经过转换、完善成一个完整的例子。下面的例子可以实现添加、删除、检测网站是否在兼容性网站列表中的功能。

以下代码在IE8、Windows2003环境下测试通过。测试时要重新打开浏览器进行验证。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace WindowsFormsApplication4
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
    
    /*
     * 
     * 添加、删除兼容性网站列表的代码。
     * 
     * 孟宪会@2014-04-20
     * 
     */


    //兼容性列表在注册表中的位置,注意:不同位的操作系统可能不同,请注意测试。
    private const string CLEARABLE_LIST_DATA = @"Software\Microsoft\Internet Explorer\BrowserEmulation\ClearableListData";
    private const string USERFILTER = "UserFilter";
    private byte[] header = new byte[] { 0x41, 0x1F, 0x00, 0x00, 0x53, 0x08, 0xAD, 0xBA };
    private byte[] delim_a = new byte[] { 0x01, 0x00, 0x00, 0x00 };
    private byte[] delim_b = new byte[] { 0x0C, 0x00, 0x00, 0x00 };
    private byte[] checksum = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF };
    private byte[] filler = BitConverter.GetBytes(DateTime.Now.ToBinary());//new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
    private byte[] regbinary = new byte[] { };


    /// <summary>
    /// 得到已经存在的所有兼容网站列表,如果没有,则返回空数组。
    /// </summary>
    /// <returns></returns>
    private string[] GetDomains()
    {
      string[] domains = { };
      using (RegistryKey regkey = Registry.CurrentUser.OpenSubKey(CLEARABLE_LIST_DATA))
      {
        //可能不存在此key.
        Object filterData = regkey.GetValue(USERFILTER);
        if (filterData != null)
        {
          byte[] filter = filterData as byte[];
          domains = GetDomains(filter);
        }
      }
      return domains;
    }

    /// <summary>
    /// 从byte数组中分析所有网站名称
    /// </summary>
    /// <param name="filter"></param>
    /// <returns></returns>
    private string[] GetDomains(byte[] filter)
    {
      List<string> domains = new List<string>();
      int length;
      int offset_filter = 24;
      int totalSize = filter.Length;
      while (offset_filter < totalSize)
      {
        length = BitConverter.ToUInt16(filter, offset_filter + 16);
        domains.Add(System.Text.Encoding.Unicode.GetString(filter, 16 + 2 + offset_filter, length * 2));
        offset_filter += 16 + 2 + length * 2;
      }
      return domains.ToArray();
    }

    /// <summary>
    /// 从兼容性列表中删除一个网站。
    /// </summary>
    /// <param name="domain">要删除网站</param>
    private void RemoveUserFilter(string domain)
    {
      String[] domains = GetDomains();
      if (!domains.Contains(domain)) {
        return;
      }
      using (RegistryKey regkey = Registry.CurrentUser.OpenSubKey(CLEARABLE_LIST_DATA,true))
      {
        object oldData = regkey.GetValue(USERFILTER);
        if (oldData != null)
        {
          byte[] filter = oldData as byte[];
          byte[] newReg = GetRemovedValue(domain, filter);

          if (GetDomains(newReg).Length == 0)
            regkey.DeleteValue(USERFILTER);
          else
            regkey.SetValue(USERFILTER, newReg, RegistryValueKind.Binary);
        }
      }
    }

    /// <summary>
    /// 得到一个网站的存储的数据
    /// </summary>
    /// <param name="domain"></param>
    /// <param name="filter"></param>
    /// <returns></returns>
    private byte[] GetRemovedValue(string domain, byte[] filter)
    {
      byte[] newReg;
      int length;
      int offset_filter = 24;
      int offset_newReg = 0;
      int totalSize = filter.Length;

      newReg = new byte[totalSize];
      Array.Copy(filter, 0, newReg, 0, offset_filter);
      offset_newReg += offset_filter;

      while (offset_filter < totalSize)
      {
        length = BitConverter.ToUInt16(filter, offset_filter + 16);
        if (domain != System.Text.Encoding.Unicode.GetString(filter, offset_filter + 16 + 2, length * 2))
        {
          Array.Copy(filter, offset_filter, newReg, offset_newReg, 16 + 2 + length * 2);
          offset_newReg += 16 + 2 + length * 2;
        }
        offset_filter += 16 + 2 + length * 2;
      }
      Array.Resize(ref newReg, offset_newReg);
      byte[] newSize = BitConverter.GetBytes((UInt16)(offset_newReg - 12));
      newReg[12] = newSize[0];
      newReg[13] = newSize[1];

      return newReg;
    }

    /// <summary>
    /// 向兼容性列表中添加一个网站
    /// </summary>
    /// <param name="domain"></param>
    private void AddNewSiteToCompatibilityViewList(String domain)
    {
      String[] domains = GetDomains();
      if (domains.Length > 0)
      {
        if (domains.Contains(domain))
        {
          return;
        }
        else
        {
          domains = domains.Concat(new String[] { domain }).ToArray();
        }
      }
      else
      {
        domains = domains.Concat(new String[] { domain }).ToArray();
      }

      int count = domains.Length;
      byte[] entries = new byte[0];
      foreach (String d in domains)
      {
        entries = this.Combine(entries, this.GetDomainEntry(d));
      }
      regbinary = header;
      regbinary = this.Combine(regbinary, BitConverter.GetBytes(count));
      regbinary = this.Combine(regbinary, checksum);
      regbinary = this.Combine(regbinary, delim_a);
      regbinary = this.Combine(regbinary, BitConverter.GetBytes(count));
      regbinary = this.Combine(regbinary, entries);
      Registry.CurrentUser.OpenSubKey(CLEARABLE_LIST_DATA,true).SetValue(USERFILTER, regbinary, RegistryValueKind.Binary);
    }

    /// <summary>
    /// 得到一个网站在兼容性列表中的数据,跟GetRemovedValue类似
    /// </summary>
    /// <param name="domain"></param>
    /// <returns></returns>
    private byte[] GetDomainEntry(String domain)
    {
      byte[] tmpbinary = new byte[0];
      byte[] length = BitConverter.GetBytes((UInt16)domain.Length);
      byte[] data = System.Text.Encoding.Unicode.GetBytes(domain);
      tmpbinary = Combine(tmpbinary, delim_b);
      tmpbinary = Combine(tmpbinary, filler);
      tmpbinary = Combine(tmpbinary, delim_a);
      tmpbinary = Combine(tmpbinary, length);
      tmpbinary = Combine(tmpbinary, data);
      return tmpbinary;
    }

    //把两个byte[]数组合并在一起
    private byte[] Combine(byte[] a, byte[] b)
    {
      byte[] c = new byte[a.Length + b.Length];
      System.Buffer.BlockCopy(a, 0, c, 0, a.Length);
      System.Buffer.BlockCopy(b, 0, c, a.Length, b.Length);
      return c;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      //添加10个
      for (int i = 0; i < 10; i++)
      {
        AddNewSiteToCompatibilityViewList("meng" + i + ".com");
      }

      //删除2个
      for (int i = 3; i < 5; i++)
      {
        this.RemoveUserFilter("meng" + i + ".com");
      }
    }
  }
}

网上的3篇资料与本文关系较大。

http://www3.xuebuyuan.com/1567759.html
http://jeffgraves.me/2014/02/19/modifying-ie-compatibility-view-settings-with-powershell/
http://stackoverflow.com/questions/16722454/editing-binary-registry-key


为了确保原文的丢失能找到内容,先把有用的PowerShell脚本粘贴过来。

$key = "HKCU:\Software\Microsoft\Internet Explorer\BrowserEmulation\ClearableListData"
$item = "UserFilter"

. .\Get-IPrange.ps1
$cidr = "^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)/(3[0-2]|[1-2]?[0-9])$"

[byte[]] $regbinary = @()

#This seems constant
[byte[]] $header = 0x41,0x1F,0x00,0x00,0x53,0x08,0xAD,0xBA

#This appears to be some internal value delimeter
[byte[]] $delim_a = 0x01,0x00,0x00,0x00

#This appears to separate entries
[byte[]] $delim_b = 0x0C,0x00,0x00,0x00

#This is some sort of checksum, but this value seems to work
[byte[]] $checksum = 0xFF,0xFF,0xFF,0xFF

#This could be some sort of timestamp for each entry ending with 0x01, but setting to this value seems to work
[byte[]] $filler = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01

#Examples: mydomain.com, 192.168.1.0/24
$domains = @("google.com","192.168.1.0/24")

function Get-DomainEntry($domain) {
[byte[]] $tmpbinary = @()

[byte[]] $length = [BitConverter]::GetBytes([int16]$domain.Length)
[byte[]] $data = [System.Text.Encoding]::Unicode.GetBytes($domain)

$tmpbinary += $delim_b
$tmpbinary += $filler
$tmpbinary += $delim_a
$tmpbinary += $length
$tmpbinary += $data

return $tmpbinary
}

if($domains.Length -gt 0) {
[int32] $count = $domains.Length

[byte[]] $entries = @()

foreach($domain in $domains) {
if($domain -match $cidr) {
$network = $domain.Split("/")[0]
$subnet = $domain.Split("/")[1]
$ips = Get-IPrange -ip $network -cidr $subnet
$ips | %{$entries += Get-DomainEntry $_}
$count = $count - 1 + $ips.Length
}
else {
$entries += Get-DomainEntry $domain
}
}

$regbinary = $header
$regbinary += [byte[]] [BitConverter]::GetBytes($count)
$regbinary += $checksum
$regbinary += $delim_a
$regbinary += [byte[]] [BitConverter]::GetBytes($count)
$regbinary += $entries
}

Set-ItemProperty -Path $key -Name $item -Value $regbinary

IE11下的PowerShell

$key = "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft"

if(-Not (Test-Path "$key\Internet Explorer")) {
New-Item -Path $key -Name "Internet Explorer" | Out-Null
}

if(-Not (Test-Path "$key\Internet Explorer\BrowserEmulation")) {
New-Item -Path "$key\Internet Explorer" -Name "BrowserEmulation" | Out-Null
}

if(-Not (Test-Path "$key\Internet Explorer\BrowserEmulation\PolicyList")) {
New-Item -Path "$key\Internet Explorer\BrowserEmulation" -Name "PolicyList" | Out-Null
}

. .\Get-IPrange.ps1
$cidr = "^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)/(3[0-2]|[1-2]?[0-9])$"

#Examples: mydomain.com, 192.168.1.0/24
$domains = @("google.com","192.168.1.0/24")

$regkey = "$key\Internet Explorer\BrowserEmulation\PolicyList"

foreach($domain in $domains) {
if($domain -match $cidr) {
$network = $domain.Split("/")[0]
$subnet = $domain.Split("/")[1]
$ips = Get-IPrange -ip $network -cidr $subnet
$ips | %{$val = New-ItemProperty -Path $regkey -Name $_ -Value $_ -PropertyType String | Out-Null}
$count = $count - 1 + $ips.Length
}
else {
New-ItemProperty -Path $regkey -Name $domain -Value $domain -PropertyType String | Out-Null
}
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 实现向浏览器的兼容性视图列表中添加、删除网站和检查网站是否在兼容性网站列表中 的相关文章

  • 生信学习——GEO数据挖掘

    步骤 STEP1 xff1a 表达矩阵ID转换STEP2 xff1a 差异分析STEP3 xff1a KEGG数据库注释完整代码 写在前面 按照生信技能树的学习路线 xff0c 学完R语言就该学习GEO数据挖掘了 有人说GEO数据挖掘可以快
  • 机器学习——基于python的鸢尾花SVM练习(包含超参数批量筛选、交叉验证)

    目录 1 最普通的SVM2 交叉验证 筛选超参数法一 xff1a cross val score法二 xff1a GridSearchCV xff08 推荐 xff09 3 完整代码 写在前面 虽然本人一直对机器学习感兴趣 xff0c 但是
  • python学习——tsv文件批量转为csv文件、csv文件列合并

    写在前面 近日在处理数据的时候发现有的文件为csv文件 xff0c 有的为tsv文件 xff0c 大概搜了一下了解到 xff1a TSV是用制表符 xff08 t xff09 作为字段值的分隔符 xff1b CSV是用半角逗号 xff08
  • PPI网络的构建与美化(String+Cytoscape)

    目录 写在前面一 使用string分析数据二 使用Cytoscape构建网络1 导入TSV文件2 Analyze Network3 Generate Style4 CytoNCA计算Betweenness 三 美化网络1 根据Between
  • 生信刷题之ROSALIND——Part 2

    目录 1 Counting Point MutationsProblemSample DatasetSample OutputCodeOutput 2 Mendel 39 s First LawProblemSample DatasetSa
  • 生信刷题之ROSALIND——Part 3

    目录 1 Mortal Fibonacci RabbitsProblemSample DatasetSample OutputCodeOutput 2 Overlap GraphsProblemSample DatasetSample Ou
  • 生信刷题之ROSALIND——Part 4 (MPRT, MRNA, ORF)

    目录 写在前面1 Finding a Protein MotifProblemSample DatasetSample OutputCodeOutput 2 Inferring mRNA from ProteinProblemSample
  • Pandas第三次作业20200907

    练习1 读取北向 csv 指定trade date为行索引 查看数据的基本信息 有无缺失值 对其缺失值进行处理 删除缺失值所在行 查看数据的基本信息 查看数据是否清洗完毕 index列没啥用 将index列删除 观察数据是否有重复行 将重复
  • Linux设置开机默认进入命令行或者图形界面

    开机默认进入命令行模式 xff1a sudo systemctl set default multi user target 开机默认进入图形用户界面 xff1a sudo systemctl set default graphical t
  • 美团后端笔试

    文章目录 整场笔试下来 xff0c 整体难度一般 xff0c 只不过在第三题扑克牌游戏的时候进行的不是很顺利 xff0c 附加题难度一般 xff0c 不知道有没有小伙伴和我一样时间耗费在第三题上面的 1 魔法外卖 题目描述 xff1a 炸鸡
  • 【JokerのZYNQ7020】QSPI启动。

    软件环境 xff1a vivado 2017 4 硬件平台 xff1a XC7Z020 通常来说 xff0c 系统做好以后是放SD卡里 xff0c 上电以后 xff0c 根据boot引脚的配置 xff0c 从SD卡引导系统启动 如果你像我一
  • 【JokerのZYNQ7020】SDK程序从QSPI启动。

    软件环境 xff1a vivado 2017 4 硬件平台 xff1a XC7Z020 之前写的QSPI启动是对ZYNQ的PS装Linux系统的 xff0c 如果不想搞那么麻烦或者功能要求单一 xff0c 调试又想方便一些 xff0c 直接
  • 【JokerのZYNQ7020】Vxworks 6.9。

    软件环境 xff1a vivado 2017 4 硬件平台 xff1a XC7Z020 基本全程参考的官方xapp1158 zynq 7000 vxworks bsp pdf xff0c 但我感觉主要难度不在移植上 xff0c 因为pdf里
  • 【JokerのZYNQ7020】ubuntu启动后跳过验证登录。

    之前分享过一篇debian系统启动后如何自动加载用户应用的例程 xff0c 今天在这里继续分享一个非常实用的小技巧 xff0c 如何让嵌入式板卡的ubuntu系统启动后 xff0c 跳过用户名密码验证 xff0c 直接以root身份进入系统
  • 2013年终总结

    2013年即将过去 xff0c 回顾这一年 xff0c 有得有失 xff0c 有喜有悲 xff0c 些许记忆碎片留在脑海中 简单做个总结 xff0c 也算划上一个完美的句号 xff0c 再迎接充满挑战的2014 xff01 项目 一年过来
  • 用FSL进行VBM统计分析

    用FSL进行VBM统计分析 总体步骤概览1 准备数据1 1 T1数据格式1 2 Template list查看数据 2 剥头皮 xff1a fslvbm 1 bet3 数据分割 43 生成模板 xff1a fslvbm 2 template
  • 程序员的生活,其实苦不堪言

    前一天 A 下班前把这个代码发给我 B 好的 xff01 第二天 A 都他妈中午了 xff0c 代码怎么还没发过来 xff1f B 我他妈还没下班呢 xff01 程序猿的真实写照 曾经刚参加工作 xff0c 接手一个项目的维护 xff0c
  • 文件后缀大全

    file extensions with related program associations a unix library unix ada program a01 arj multi volume compressed archiv
  • Android Studio 安装Kotlin插件

    1 打开Android Studio 的File gt Settings xff0c 选择左侧Plugins显示已安装插件列表 搜索框输入kotlin xff0c 若无搜索结果 xff0c 可以点击 Search in repositori
  • Python读取文件的多种方式

    在Python编程中 xff0c 读取文件是非常常见的操作 Python提供了多种读取文件的方式 xff0c 本文将介绍其中的几种方式 1 使用open函数读取文件 使用Python内置函数open 可以打开一个文件 xff0c 并返回一个

随机推荐