├── .gitignore ├── 001 Hello World.md ├── 001 Hello World ├── 001 Hello World.csproj ├── Main.cs └── Properties │ └── AssemblyInfo.cs ├── 002 Global Style.md ├── 002 Global Style ├── 002 Global Style.csproj ├── Container.xaml ├── Container.xaml.cs ├── GlobalStyle.xaml ├── Main.cs └── Properties │ └── AssemblyInfo.cs ├── 003 Static Page.md ├── 003 Static Page ├── 003 Static Page.csproj ├── Container.xaml ├── Container.xaml.cs ├── GlobalStyle.xaml ├── Main.cs └── Properties │ └── AssemblyInfo.cs ├── 004 Data Model.md ├── 004 Data Model ├── 004 Data Model.csproj ├── Container.xaml ├── Container.xaml.cs ├── GlobalStyle.xaml ├── HostModel.cs ├── Main.cs ├── Properties │ └── AssemblyInfo.cs ├── Tools │ └── DataTool.cs ├── app.config └── packages.config ├── 005 Global Event.md ├── 005 Global Event ├── 005 Global Event.csproj ├── AlertUI │ ├── ExplainAlertUI.xaml │ ├── ExplainAlertUI.xaml.cs │ ├── HostAlertUI.xaml │ └── HostAlertUI.xaml.cs ├── Container.xaml ├── Container.xaml.cs ├── GlobalStyle.xaml ├── HostModel.cs ├── Main.cs ├── Properties │ └── AssemblyInfo.cs ├── Tools │ ├── AlertTool.cs │ └── DataTool.cs ├── app.config └── packages.config ├── 006 Host Event.md ├── 006 Host Event ├── 006 Host Event.csproj ├── AlertUI │ ├── ExplainAlertUI.xaml │ ├── ExplainAlertUI.xaml.cs │ ├── HostAlertUI.xaml │ └── HostAlertUI.xaml.cs ├── Container.xaml ├── Container.xaml.cs ├── GlobalEvent.cs ├── GlobalStyle.xaml ├── HostModel.cs ├── Main.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── delete.png │ ├── down.png │ ├── modify.png │ └── up.png ├── Tools │ ├── AlertTool.cs │ └── DataTool.cs ├── app.config └── packages.config ├── 007 Host Mapping.md ├── 007 Host Mapping ├── 007 Host Mapping.csproj ├── AlertUI │ ├── ExplainAlertUI.xaml │ ├── ExplainAlertUI.xaml.cs │ ├── HostAlertUI.xaml │ └── HostAlertUI.xaml.cs ├── Container.xaml ├── Container.xaml.cs ├── GlobalEvent.cs ├── GlobalStyle.xaml ├── HostModel.cs ├── Main.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── delete.png │ ├── down.png │ ├── modify.png │ └── up.png ├── Tools │ ├── AlertTool.cs │ ├── DataTool.cs │ └── FiddlerTool.cs ├── app.config └── packages.config ├── 008 Other.md ├── 008 Other ├── 008 Other.csproj ├── AlertUI │ ├── ExplainAlertUI.xaml │ ├── ExplainAlertUI.xaml.cs │ ├── HostAlertUI.xaml │ └── HostAlertUI.xaml.cs ├── Container.xaml ├── Container.xaml.cs ├── GlobalEvent.cs ├── GlobalStyle.xaml ├── HostModel.cs ├── Main.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── ExplainImages │ │ ├── 001.png │ │ └── 002.png │ ├── delete.png │ ├── down.png │ ├── icon.png │ ├── modify.png │ └── up.png ├── Tools │ ├── AlertTool.cs │ ├── DataTool.cs │ └── FiddlerTool.cs ├── app.config └── packages.config ├── 009 Executable File.md ├── 009 Executable File ├── FiddlerExample.dll ├── FiddlerExample.exe ├── FiddlerExample.nsi ├── Newtonsoft.Json.dll └── icon.ico ├── Fiddler-Plug-Example.sln ├── README.md ├── images ├── 001 Hello World │ ├── 001.png │ ├── 002.png │ ├── 003.png │ ├── 004.png │ ├── 005.png │ └── 006.png ├── 002 Global Style │ ├── 001.png │ ├── 002.png │ └── 003.png ├── 003 Static Page │ ├── 001.png │ ├── 002.png │ └── 003.png ├── 004 Data Model │ ├── 001.png │ └── 002.png ├── 005 Global Event │ ├── 001.png │ ├── 002.png │ ├── 003.png │ └── 004.png ├── 006 Host Event │ ├── 001.png │ ├── 002.png │ ├── 003.png │ ├── 004.png │ ├── 005.png │ └── 006.png ├── 007 Host Mapping │ ├── 001.png │ ├── 002.png │ ├── 003.png │ └── 004.png ├── 008 Other │ ├── 001.png │ ├── 002.png │ └── 003.png ├── 009 Executable File │ ├── 001.png │ ├── 002.png │ ├── 003.png │ └── 004.png └── preview.gif └── notes ├── 001 Hello World.docx ├── 002 全局样式.docx ├── 003 静态页面.docx ├── 004 数据层.docx ├── 005 全局事件.docx ├── 006 HOST事件.docx ├── 007 HOST映射.docx ├── 008 其他.docx └── 009 可执行文件.docx /001 Hello World.md: -------------------------------------------------------------------------------- 1 | # Hello World 2 | ## 一、环境准备 3 | Visual Studio 2015、Fiddler 5.0 4 | ## 二、新建工程 5 | ### 1、创建项目 6 | 选择新建工程,选择类库,因为Fiddler5.0使用的是.Net4.6.1,因此选择.Net4.6.1 7 | ![创建项目](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/001%20Hello%20World/001.png "创建项目") 8 | ### 2、添加Fiddler的类库 9 | 项目右键选择添加引用,点击浏览,然后找到Fiddler的安装地址选择Fiddler.exe添加即可 10 | ![添加引用](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/001%20Hello%20World/002.png "添加引用") 11 | ![浏览](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/001%20Hello%20World/003.png "浏览") 12 | ### 3、添加Fiddler版本要求 13 | 打开AssemblyInfo.cs,增加要求的Fiddler版本信息,因为使用的是Fiddler5.0,因此填写版本号支持Fiddler5.0以上(这里理论上填写4.0也可以,因为Fiddler从4.0开始就使用.Net4.0的架构了) 14 | ``` 15 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 16 | ``` 17 | ![版本要求](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/001%20Hello%20World/004.png "版本要求") 18 | ## 三、Hello Word 19 | 1、新建Main.cs文件,并添加public前缀 20 | 2、继承IFiddlerExtension类,并且实现OnLoad和OnBeforeUnload函数 21 | ``` 22 | public class Main : IFiddlerExtension 23 | { 24 | public void OnBeforeUnload() 25 | {} 26 | 27 | public void OnLoad() 28 | {} 29 | } 30 | ``` 31 | 3、项目中添加System.Windows.Forms引用,接着在Main加入using System.Windows.Forms,然后Main继承UserControl类 32 | 4、在OnLoad中加入以下代码 33 | ``` 34 | //新建一个Fiddler插件的page 35 | TabPage page = new TabPage("Hello World"); 36 | //将page加入Fiddler的tab选项卡中 37 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 38 | //输出Hello World 39 | FiddlerApplication.DoNotifyUser("Hello", "Hello World"); 40 | ``` 41 | ## 四、打包测试 42 | 1、使用快捷键Ctrl+Shift+B来快速生成dll文件 43 | 2、将项目目录下的bin\Debug文件夹里面的.dll文件拷贝到Fiddler安装目录里的Scripts文件夹下 44 | 3、重启Fiddler,如下图所示,则代表插件安装成功 45 | ![弹框](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/001%20Hello%20World/005.png "弹框") 46 | ![插件](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/001%20Hello%20World/006.png "插件") 47 | -------------------------------------------------------------------------------- /001 Hello World/001 Hello World.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C3B04B3F-2112-4EC7-81CF-5215DE04CA67} 8 | Library 9 | Properties 10 | _001_Hello_World 11 | 001 Hello World 12 | v4.6.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\..\Users\柯俊盛\AppData\Local\Programs\Fiddler\Fiddler.exe 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | UserControl 49 | 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /001 Hello World/Main.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using System.Windows.Forms; 3 | 4 | namespace _001_Hello_World 5 | { 6 | public class Main: UserControl, IFiddlerExtension 7 | { 8 | public void OnBeforeUnload() 9 | { } 10 | 11 | public void OnLoad() 12 | { 13 | //新建一个Fiddler插件的page 14 | TabPage page = new TabPage("Heelo World"); 15 | //将page加入Fiddler的tab选项卡中 16 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 17 | //输出Hello World 18 | FiddlerApplication.DoNotifyUser("Hello", "Hello World"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /001 Hello World/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("001 Hello World")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("001 Hello World")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("c3b04b3f-2112-4ec7-81cf-5215de04ca67")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] -------------------------------------------------------------------------------- /002 Global Style.md: -------------------------------------------------------------------------------- 1 | # 全局样式 2 | ## 一、资源字典 3 | 一般项目肯定存在需要复用的样式和模板,在WPF中可以使用资源字典来实现公共样式的编写,然后在页面中引入资源字典即可实现样式继承 4 | ### 1、新建字典 5 | 首先添加System.Xaml引用,接着新建一个WPF,命名为GlobalStyle.xaml,然后手动删除掉GlobalStyle.xaml.cs,将GlobalStyle.xaml重新编写为资源字典文件格式,接着实现一个确定按钮样式 6 | ![新建字典](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/002%20Global%20Style/001.png "新建字典") 7 | ``` 8 | 15 | 16 | 28 | 29 | ``` 30 | ### 2、插件承载页面 31 | 新建一个WPF控件,命名为Container.xaml,作为插件内容的承载页面,然后引入全局资源字典,接着创建一个Label标签,指定Style为全局样式中的alert_style_sure_btn 32 | ``` 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ``` 43 | ### 3、预览结果 44 | ![预览](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/002%20Global%20Style/002.png "预览") 45 | ## 二、关联WPF 46 | 1、在Main.cs文件中,申明静态UI对象属性,同时在OnLoad中初始化 47 | ``` 48 | public static Container container; 49 | //新建UI对象 50 | container = new Container(); 51 | ``` 52 | 2、添加WindowsFormsIntegration引用,同时代码引入System.Windows.Forms.Integration库 53 | 3、使用ElementHost实现在WinForm中调用WPF 54 | ``` 55 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 56 | ElementHost element = new ElementHost(); 57 | element.Child = container; 58 | element.Dock = DockStyle.Fill; 59 | ``` 60 | 4、将UI对象添加进Fiddler插件的Page中 61 | ``` 62 | //将WPF挂载对象添加到page中 63 | page.Controls.Add(element); 64 | ``` 65 | ## 三、打包调试结果 66 | ![结果](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/002%20Global%20Style/003.png "结果") 67 | -------------------------------------------------------------------------------- /002 Global Style/002 Global Style.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A7909D00-35BE-4D15-AE05-36E6F9A21902} 8 | Library 9 | Properties 10 | _002_Global_Style 11 | 002 Global Style 12 | v4.6.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\..\Users\柯俊盛\AppData\Local\Programs\Fiddler\Fiddler.exe 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Container.xaml 54 | 55 | 56 | UserControl 57 | 58 | 59 | 60 | 61 | 62 | Designer 63 | MSBuild:Compile 64 | 65 | 66 | Designer 67 | MSBuild:Compile 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /002 Global Style/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /002 Global Style/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace _002_Global_Style 17 | { 18 | /// 19 | /// Container.xaml 的交互逻辑 20 | /// 21 | public partial class Container : UserControl 22 | { 23 | public Container() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /002 Global Style/GlobalStyle.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 21 | 22 | -------------------------------------------------------------------------------- /002 Global Style/Main.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using System.Windows.Forms; 3 | using System.Windows.Forms.Integration; 4 | 5 | namespace _002_Global_Style 6 | { 7 | public class Main : UserControl, IFiddlerExtension 8 | { 9 | public static Container container; 10 | 11 | public void OnBeforeUnload() 12 | { } 13 | 14 | public void OnLoad() 15 | { 16 | //新建UI对象 17 | container = new Container(); 18 | 19 | //新建一个Fiddler插件的page 20 | TabPage page = new TabPage("PlugExample"); 21 | //将page加入Fiddler的tab选项卡中 22 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 23 | 24 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 25 | ElementHost element = new ElementHost(); 26 | element.Child = container; 27 | element.Dock = DockStyle.Fill; 28 | 29 | //将WPF挂载对象添加到page中 30 | page.Controls.Add(element); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /002 Global Style/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("002 Global Style")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("002 Global Style")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("a7909d00-35be-4d15-ae05-36e6f9a21902")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] -------------------------------------------------------------------------------- /003 Static Page.md: -------------------------------------------------------------------------------- 1 | # 静态页面 2 | 样式设计思路:容器均使用内联样式,元素均使用静态样式,对于重复或者复杂的元素使用ControlTemplate来实现复用和简化代码 3 | ## 一、Icon 4 | 在前端样式实现方案中经常使用到图标字体,在WPF中也可以使用,不过在WPF中图标字体的承载对象是Canvas控件,下面主要介绍如何快捷的生成WPF中可以使用的图标字体 5 | 6 | 1、访问图标字体网站:https://icomoon.io/app/#/select 7 | 2、选择需要的图标,然后选择Generate SVG & More按钮 8 | 3、点击Preferences按钮,然后选择性修改图标尺寸,同时选择生成XAML格式,最后点击Download进行下载 9 | ![配置面板](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/003%20Static%20Page/001.png "配置面板") 10 | 4、将zip压缩包进行解压,打开XAML文件夹,编辑对应icon的wxml文件,拷贝其中的整个Canvas对象代码,其中修改Path的Fill可以修改图标颜色 11 | ## 二、布局 12 | 最外层使用Grid面板,来实现Top - Content布局;其中Content层再内嵌ScrollViewer控件来实现滚动界面 13 | ### 1、Grid面板 14 | 指定全局唯一标识Name为main,指定背景颜色为FFF0F3F6,最后再声明Top区域的高度为auto,Content区域的高度为100* 15 | ``` 16 | 17 | 18 | 19 | 20 | 21 | 22 | ``` 23 | ### 2、Top区域 24 | 使用DockPanel面板作为容器,并设置Margin为30,0;其中左侧为标题和Icon,右侧为操作按钮;操作按钮使用WrapPanel来作为容器,然后右对齐 25 | ``` 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | ``` 35 | ### 3、Content区域 36 | 使用ScrollViewer控件作为容器,设置Margin为30,0、VerticalScrollBarVisibility为Auto(当内容超过最大高度才显示滚动条),内部再内嵌StackPanel,并指定Name为host 37 | ``` 38 | 39 | 40 | 41 | ``` 42 | ### 4、结果预览 43 | ![Content区域](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/003%20Static%20Page/002.png "Content区域") 44 | ## 三、列表区域 45 | ### 1、容器布局 46 | 列表内容主要包含IP、Url和选中框,因此分为3列,其中选中框宽度固定为40,IP和Url列分别占剩余的30%和70%宽度 47 | ``` 48 | 49 | 50 | 51 | 52 | 53 | ``` 54 | ### 2、文本和选中框 55 | 文本内容使用Label嵌套TextBlock来实现超出自动显示省略号的功能,选中框则使用Rectangle和Canvas来实现,然后使用Visibility来控制选中态和未选中态的展示 56 | ``` 57 | 60 | 61 | 62 | 63 | 64 | 65 | ``` 66 | ### 3、结果预览 67 | ![列表区域](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/003%20Static%20Page/003.png "列表区域") 68 | -------------------------------------------------------------------------------- /003 Static Page/003 Static Page.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EEB827FA-464B-4151-80CD-CC8574F7FD1F} 8 | Library 9 | Properties 10 | _003_Static_Page 11 | 003 Static Page 12 | v4.6.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\..\Users\柯俊盛\AppData\Local\Programs\Fiddler\Fiddler.exe 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Container.xaml 54 | 55 | 56 | UserControl 57 | 58 | 59 | 60 | 61 | 62 | Designer 63 | MSBuild:Compile 64 | 65 | 66 | Designer 67 | MSBuild:Compile 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /003 Static Page/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /003 Static Page/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace _003_Static_Page 17 | { 18 | /// 19 | /// Container.xaml 的交互逻辑 20 | /// 21 | public partial class Container : UserControl 22 | { 23 | public Container() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /003 Static Page/Main.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using System.Windows.Forms; 3 | using System.Windows.Forms.Integration; 4 | 5 | namespace _003_Static_Page 6 | { 7 | public class Main : UserControl, IFiddlerExtension 8 | { 9 | public static Container container; 10 | 11 | public void OnBeforeUnload() 12 | { } 13 | 14 | public void OnLoad() 15 | { 16 | //新建UI对象 17 | container = new Container(); 18 | 19 | //新建一个Fiddler插件的page 20 | TabPage page = new TabPage("PlugExample"); 21 | //将page加入Fiddler的tab选项卡中 22 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 23 | 24 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 25 | ElementHost element = new ElementHost(); 26 | element.Child = container; 27 | element.Dock = DockStyle.Fill; 28 | 29 | //将WPF挂载对象添加到page中 30 | page.Controls.Add(element); 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /003 Static Page/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("003 Static Page")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("003 Static Page")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("eeb827fa-464b-4151-80cd-cc8574f7fd1f")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 38 | -------------------------------------------------------------------------------- /004 Data Model.md: -------------------------------------------------------------------------------- 1 | # 数据层 2 | 在WPF中可以使用数据绑定来实现数据驱动UI的能力,因此我们使用HostModel类来实现数据到UI的映射,同时继承INotifyPropertyChanged来实现当数据变化UI自动更新的功能,最后将数据JSON化以后进行本地存储 3 | ## 一、Model层 4 | 1、新建HostModel类,修改为public类,同时继承INotifyPropertyChanged,并且引用System.ComponentModel,然后定义PropertyChanged,并实现NotifyPropertyChanged函数 5 | ``` 6 | public event PropertyChangedEventHandler PropertyChanged; 7 | #region 通知UI更新数据 8 | protected void NotifyPropertyChanged(string propertyName) 9 | { 10 | PropertyChangedEventHandler handler = PropertyChanged; 11 | if (handler != null) 12 | { 13 | handler(this, new PropertyChangedEventArgs(propertyName)); 14 | } 15 | } 16 | #endregion 17 | ``` 18 | 2、添加Index、Enable、CheckShow、CheckHide、IP、Port、IpAndPort、Url属性,同时实现get/set方法,以Index为例 19 | ``` 20 | private int _index; 21 | public int Index 22 | { 23 | get { return _index; } 24 | set 25 | { 26 | if (_index != value) 27 | { 28 | _index = value; 29 | NotifyPropertyChanged("Index"); 30 | } 31 | } 32 | } 33 | ``` 34 | 3、实现构造函数 35 | ``` 36 | public HostModel(int index, bool enable, string ip, string port, string url) 37 | { 38 | _index = index; 39 | _enable = enable; 40 | _ip = ip; 41 | _port = port; 42 | _url = url; 43 | } 44 | ``` 45 | ## 二、数据绑定 46 | 找到GlobalStyle.xaml中的content_host模板,给其中的IP和URL的Tag、Content属性设置数据绑定,同样也给选中框的Tag、Visibility属性设置数据绑定 47 | ``` 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ``` 56 | ## 三、初始化 57 | 1、在Main类中新增静态属性mainData,并在OnLoad方法的第一行添加初始化代码 58 | ``` 59 | //配置数据 60 | public static ArrayList mainData; 61 | //初始化配置数据 62 | mainData = new ArrayList(); 63 | ``` 64 | 2、新建Tools文件夹,在Tools文件夹中新建DataTool类,并实现静态方法addHostRule 65 | ``` 66 | public static void addHostRule(string ip, string port, string url) 67 | { 68 | //新建数据 69 | HostModel rule = new HostModel(mainData.Count, true, ip, port, url); 70 | //添加数据 71 | mainData.Add(rule); 72 | } 73 | ``` 74 | 3、在Container类中实现addHostRule方法 75 | ``` 76 | public void addHostRule(HostModel rule) 77 | { 78 | //创建UI对象 79 | Label label = new Label(); 80 | //设置UI对象属性 81 | label.Template = Resources["content_host"] as ControlTemplate; 82 | label.DataContext = rule; 83 | //添加Rule 84 | this.host.Children.Add(label); 85 | } 86 | ``` 87 | 4、在Main类中的Onload添加以下测试代码 88 | ``` 89 | //测试代码 90 | addHostRule("127.0.0.1", "8080", "www.example.com"); 91 | addHostRule("127.0.0.1", "", "www.example.com"); 92 | addHostRule("127.0.0.1", "3366", "www.example.com"); 93 | ``` 94 | 5、结果预览 95 | ![数据绑定](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/004%20Data%20Model/001.png "数据绑定") 96 | ## 四、本地存储 97 | 1、新建Tools文件夹,然后在Tools文件夹中新建DataTool类 98 | 2、本地存储需要写权限,因此我们选择文档文件夹,在DataTool类中定义静态属性path,并使用Environment获取文档文件夹的路径 99 | ``` 100 | //对应文件夹路径 101 | private static string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Fiddler2\\FiddlerExample"; 102 | ``` 103 | 3、定义配置文件路径 104 | ``` 105 | //配置文件路径 106 | private static string configPath = path + "\\config.json"; 107 | ``` 108 | 4、使用NuGet给项目添加Newtonsoft.Json库,选择最新稳定版即可 109 | 5、引入Newtonsoft.Json.Linq,然后定义私有静态方法formatConfigData 110 | ``` 111 | using Newtonsoft.Json.Linq; 112 | #region 内部工具--配置转JSON 113 | //格式化配置数据成JSON格式 114 | private static JObject formatConfigData() 115 | { 116 | //最终结果 117 | JObject result = new JObject(); 118 | //规则数据 119 | JArray rules = new JArray(); 120 | //获取所有配置数据 121 | ArrayList items = Main.mainData; 122 | 123 | //遍历添加配置数据到rules 124 | for (int i = 0, len = items.Count; i < len; i++) 125 | { 126 | //获取对应的Item 127 | HostModel item = items[i] as HostModel; 128 | //生成Json数据 129 | JObject rule = new JObject(); 130 | rule.Add("enable", item.Enable); 131 | rule.Add("ip", item.IP); 132 | rule.Add("port", item.Port); 133 | rule.Add("url", item.Url); 134 | //填充进数据中 135 | rules.Add(rule); 136 | } 137 | 138 | //添加骨架 139 | result.Add("host", rules); 140 | 141 | return result; 142 | } 143 | #endregion 144 | ``` 145 | 6、定义公有静态方法initFolder和writeConfigToFile 146 | ``` 147 | #region 暴露出去的方法 148 | //初始化文件夹 149 | public static void initFolder() 150 | { 151 | //备份文件夹不存在直接创建 152 | if (!Directory.Exists(path)) 153 | { 154 | Directory.CreateDirectory(path); 155 | } 156 | } 157 | //将配置数据写到本地 158 | public static void writeConfigToFile() 159 | { 160 | try 161 | { 162 | FileStream fs = new FileStream(configPath, FileMode.Create); 163 | StreamWriter sw = new StreamWriter(fs); 164 | //开始写入 165 | sw.Write(formatConfigData().ToString()); 166 | //清空缓冲区 167 | sw.Flush(); 168 | //关闭流 169 | sw.Close(); 170 | fs.Close(); 171 | } 172 | catch (Exception e) 173 | { 174 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(writeConfigToFile函数):" + e.ToString()); 175 | } 176 | } 177 | #endregion 178 | ``` 179 | 7、在Main类的OnLoad方法中添加测试代码 180 | ``` 181 | //本地存储测试代码 182 | DataTool.initFolder(); 183 | DataTool.writeConfigToFile(); 184 | ``` 185 | 8、进行编译打包后,将新添加的依赖库Newtonsoft.Json.dll也复制到Fiddler的Scripts文件夹中 186 | ![本地存储](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/004%20Data%20Model/002.png "本地存储") 187 | -------------------------------------------------------------------------------- /004 Data Model/004 Data Model.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8058CCB5-E232-4E01-95B5-947BB714A9A9} 8 | Library 9 | Properties 10 | _004_Data_Model 11 | 004 Data Model 12 | v4.6.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\..\Users\柯俊盛\AppData\Local\Programs\Fiddler\Fiddler.exe 35 | 36 | 37 | ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll 38 | True 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Container.xaml 58 | 59 | 60 | 61 | UserControl 62 | 63 | 64 | 65 | 66 | 67 | 68 | Designer 69 | MSBuild:Compile 70 | 71 | 72 | Designer 73 | MSBuild:Compile 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | -------------------------------------------------------------------------------- /004 Data Model/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /004 Data Model/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace _004_Data_Model 17 | { 18 | /// 19 | /// Container.xaml 的交互逻辑 20 | /// 21 | public partial class Container : UserControl 22 | { 23 | public Container() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | #region 暴露出去的方法 29 | public void addHostRule(HostModel rule) 30 | { 31 | //创建UI对象 32 | Label label = new Label(); 33 | //设置UI对象属性 34 | label.Template = Resources["content_host"] as ControlTemplate; 35 | label.DataContext = rule; 36 | //添加Rule 37 | this.host.Children.Add(label); 38 | } 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /004 Data Model/HostModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | 4 | namespace _004_Data_Model 5 | { 6 | public class HostModel: INotifyPropertyChanged 7 | { 8 | public event PropertyChangedEventHandler PropertyChanged; 9 | 10 | #region index 11 | private int _index; 12 | public int Index 13 | { 14 | get { return _index; } 15 | set 16 | { 17 | if (_index != value) 18 | { 19 | _index = value; 20 | NotifyPropertyChanged("Index"); 21 | } 22 | } 23 | } 24 | #endregion 25 | 26 | #region enable 27 | private bool _enable; 28 | public bool Enable 29 | { 30 | get { return _enable; } 31 | set 32 | { 33 | if (_enable != value) 34 | { 35 | _enable = value; 36 | NotifyPropertyChanged("CheckShow"); 37 | NotifyPropertyChanged("CheckHide"); 38 | } 39 | } 40 | } 41 | public Visibility CheckShow 42 | { 43 | get 44 | { 45 | return _enable ? Visibility.Visible : Visibility.Collapsed; 46 | } 47 | } 48 | public Visibility CheckHide 49 | { 50 | get 51 | { 52 | return _enable ? Visibility.Collapsed : Visibility.Visible; 53 | } 54 | } 55 | #endregion 56 | 57 | #region ip and port 58 | private string _ip; 59 | public string IP 60 | { 61 | get { return _ip; } 62 | set 63 | { 64 | if (_ip != value) 65 | { 66 | _ip = value; 67 | NotifyPropertyChanged("IpAndPort"); 68 | } 69 | } 70 | } 71 | 72 | private string _port; 73 | public string Port 74 | { 75 | get { return _port; } 76 | set 77 | { 78 | if (_port != value) 79 | { 80 | _port = value; 81 | NotifyPropertyChanged("IpAndPort"); 82 | } 83 | } 84 | } 85 | 86 | public string IpAndPort 87 | { 88 | get 89 | { 90 | if (_port.Length <= 0) 91 | { 92 | return "IP / " + _ip; 93 | } 94 | else 95 | { 96 | return "IP / " + _ip + ":" + _port; 97 | } 98 | } 99 | } 100 | #endregion 101 | 102 | #region url 103 | private string _url; 104 | public string Url 105 | { 106 | get { return _url; } 107 | set 108 | { 109 | if (_url != value) 110 | { 111 | _url = value; 112 | NotifyPropertyChanged("TipsAndUrl"); 113 | } 114 | } 115 | } 116 | public string TipsAndUrl { 117 | get { return "URL / " + _url; } 118 | } 119 | #endregion 120 | 121 | public HostModel(int index, bool enable, string ip, string port, string url) 122 | { 123 | _index = index; 124 | _enable = enable; 125 | _ip = ip; 126 | _port = port; 127 | _url = url; 128 | } 129 | 130 | #region 通知UI更新数据 131 | protected void NotifyPropertyChanged(string propertyName) 132 | { 133 | PropertyChangedEventHandler handler = PropertyChanged; 134 | if (handler != null) 135 | { 136 | handler(this, new PropertyChangedEventArgs(propertyName)); 137 | } 138 | } 139 | #endregion 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /004 Data Model/Main.cs: -------------------------------------------------------------------------------- 1 | using _004_Data_Model.Tools; 2 | using Fiddler; 3 | using System.Collections; 4 | using System.Windows.Forms; 5 | using System.Windows.Forms.Integration; 6 | 7 | namespace _004_Data_Model 8 | { 9 | public class Main : UserControl, IFiddlerExtension 10 | { 11 | //UI 12 | public static Container container; 13 | //配置数据 14 | public static ArrayList mainData; 15 | 16 | public void OnBeforeUnload() 17 | { } 18 | 19 | public void OnLoad() 20 | { 21 | //初始化配置数据 22 | mainData = new ArrayList(); 23 | //新建UI对象 24 | container = new Container(); 25 | 26 | //新建一个Fiddler插件的page 27 | TabPage page = new TabPage("PlugExample"); 28 | //将page加入Fiddler的tab选项卡中 29 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 30 | 31 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 32 | ElementHost element = new ElementHost(); 33 | element.Child = container; 34 | element.Dock = DockStyle.Fill; 35 | 36 | //将WPF挂载对象添加到page中 37 | page.Controls.Add(element); 38 | 39 | //测试代码 40 | addHostRule("127.0.0.1", "8080", "www.example.com"); 41 | addHostRule("127.0.0.1", "", "www.example.com"); 42 | addHostRule("127.0.0.1", "3366", "www.example.com"); 43 | //本地存储测试代码 44 | DataTool.initFolder(); 45 | DataTool.writeConfigToFile(); 46 | } 47 | 48 | #region 暴露出去的方法 49 | //新增Host规则 50 | public static void addHostRule(string ip, string port, string url) 51 | { 52 | //新建数据 53 | HostModel rule = new HostModel(mainData.Count, true, ip, port, url); 54 | //添加数据 55 | mainData.Add(rule); 56 | //添加UI 57 | container.addHostRule(rule); 58 | } 59 | #endregion 60 | } 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /004 Data Model/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("004 Data Model")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("004 Data Model")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("8058ccb5-e232-4e01-95b5-947bb714a9a9")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 38 | -------------------------------------------------------------------------------- /004 Data Model/Tools/DataTool.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections; 5 | using System.IO; 6 | 7 | namespace _004_Data_Model.Tools 8 | { 9 | class DataTool 10 | { 11 | //对应文件夹路径 12 | private static string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Fiddler2\\FiddlerExample"; 13 | //配置文件路径 14 | private static string configPath = path + "\\config.json"; 15 | 16 | #region 内部工具--配置转JSON 17 | //格式化配置数据成JSON格式 18 | private static JObject formatConfigData() 19 | { 20 | //最终结果 21 | JObject result = new JObject(); 22 | //规则数据 23 | JArray rules = new JArray(); 24 | //获取所有配置数据 25 | ArrayList items = Main.mainData; 26 | 27 | //遍历添加配置数据到rules 28 | for (int i = 0, len = items.Count; i < len; i++) 29 | { 30 | //获取对应的Item 31 | HostModel item = items[i] as HostModel; 32 | //生成Json数据 33 | JObject rule = new JObject(); 34 | rule.Add("enable", item.Enable); 35 | rule.Add("ip", item.IP); 36 | rule.Add("port", item.Port); 37 | rule.Add("url", item.Url); 38 | //填充进数据中 39 | rules.Add(rule); 40 | } 41 | 42 | //添加骨架 43 | result.Add("host", rules); 44 | 45 | return result; 46 | } 47 | #endregion 48 | 49 | #region 暴露出去的方法 50 | //初始化文件夹 51 | public static void initFolder() 52 | { 53 | //备份文件夹不存在直接创建 54 | if (!Directory.Exists(path)) 55 | { 56 | Directory.CreateDirectory(path); 57 | } 58 | } 59 | //将配置数据写到本地 60 | public static void writeConfigToFile() 61 | { 62 | try 63 | { 64 | FileStream fs = new FileStream(configPath, FileMode.Create); 65 | StreamWriter sw = new StreamWriter(fs); 66 | //开始写入 67 | sw.Write(formatConfigData().ToString()); 68 | //清空缓冲区 69 | sw.Flush(); 70 | //关闭流 71 | sw.Close(); 72 | fs.Close(); 73 | } 74 | catch (Exception e) 75 | { 76 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(writeConfigToFile函数):" + e.ToString()); 77 | } 78 | } 79 | #endregion 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /004 Data Model/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /004 Data Model/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /005 Global Event/005 Global Event.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AA5D6C35-5EE4-413E-926C-163E87375B7C} 8 | Library 9 | Properties 10 | _005_Global_Event 11 | 005 Global Event 12 | v4.6.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\..\Users\柯俊盛\AppData\Local\Programs\Fiddler\Fiddler.exe 35 | 36 | 37 | ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll 38 | True 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ExplainAlertUI.xaml 58 | 59 | 60 | HostAlertUI.xaml 61 | 62 | 63 | Container.xaml 64 | 65 | 66 | 67 | UserControl 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Designer 80 | MSBuild:Compile 81 | 82 | 83 | Designer 84 | MSBuild:Compile 85 | 86 | 87 | Designer 88 | MSBuild:Compile 89 | 90 | 91 | Designer 92 | MSBuild:Compile 93 | 94 | 95 | 96 | 103 | -------------------------------------------------------------------------------- /005 Global Event/AlertUI/ExplainAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 1、IP字段:填写映射机器的IP地址即可 21 | 2、端口字段:非必填,填写则替换为指定端口号,为空则使用请求本身的端口号 22 | 23 | 3、URL字段: 24 | 25 | 26 | 27 | 28 | 29 | 4、配置示例: 30 | 5、映射结果示例: 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /005 Global Event/AlertUI/ExplainAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace _005_Global_Event.AlertUI 17 | { 18 | /// 19 | /// ExplainAlertUI.xaml 的交互逻辑 20 | /// 21 | public partial class ExplainAlertUI : UserControl 22 | { 23 | public ExplainAlertUI() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /005 Global Event/AlertUI/HostAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /005 Global Event/AlertUI/HostAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace _005_Global_Event.AlertUI 6 | { 7 | /// 8 | /// HostAlertUI.xaml 的交互逻辑 9 | /// 10 | public partial class HostAlertUI : UserControl 11 | { 12 | public HostAlertUI() 13 | { 14 | InitializeComponent(); 15 | } 16 | 17 | #region 鼠标点击事件 18 | private void addHostRule(object sender, MouseButtonEventArgs e) 19 | { 20 | string ip = this.ip.Text; 21 | string port = this.port.Text; 22 | string url = this.url.Text; 23 | 24 | if (ip.Length == 0) 25 | { 26 | Fiddler.FiddlerApplication.DoNotifyUser("请填写IP", "输入提示"); 27 | return; 28 | } 29 | 30 | if (url.Length == 0) 31 | { 32 | Fiddler.FiddlerApplication.DoNotifyUser("请填写URL", "输入提示"); 33 | return; 34 | } 35 | 36 | //添加UI 37 | Main.addHostRule(ip, port, url); 38 | 39 | //关闭弹框 40 | (this.Parent as Window).Close(); 41 | } 42 | #endregion 43 | 44 | #region 输入框按键监听事件 45 | private void inputKeyDown(object sender, KeyEventArgs e) 46 | { 47 | if (e.Key == Key.Enter) 48 | { 49 | addHostRule(null, null); 50 | } 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /005 Global Event/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /005 Global Event/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using _005_Global_Event.Tools; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace _005_Global_Event 6 | { 7 | /// 8 | /// Container.xaml 的交互逻辑 9 | /// 10 | public partial class Container : UserControl 11 | { 12 | public Container() 13 | { 14 | InitializeComponent(); 15 | } 16 | 17 | #region Alert--事件 18 | //显示说明弹框 19 | private void showExplainAlertUI(object sender, MouseButtonEventArgs e) 20 | { 21 | AlertTool.showExplainAlertUI(); 22 | } 23 | //增加Host 24 | private void addHost(object sender, MouseButtonEventArgs e) 25 | { 26 | AlertTool.showHostAlertUI(); 27 | } 28 | #endregion 29 | 30 | #region 暴露出去的方法 31 | public void addHostRule(HostModel rule) 32 | { 33 | //创建UI对象 34 | Label label = new Label(); 35 | //设置UI对象属性 36 | label.Template = Resources["content_host"] as ControlTemplate; 37 | label.DataContext = rule; 38 | //添加Rule 39 | this.host.Children.Add(label); 40 | } 41 | //禁止所有Item 42 | private void disabledAllItem(object sender, MouseButtonEventArgs e) 43 | { 44 | Main.disabledAllHostFromData(); 45 | } 46 | #endregion 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /005 Global Event/HostModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | 4 | namespace _005_Global_Event 5 | { 6 | public class HostModel : INotifyPropertyChanged 7 | { 8 | public event PropertyChangedEventHandler PropertyChanged; 9 | 10 | #region index 11 | private int _index; 12 | public int Index 13 | { 14 | get { return _index; } 15 | set 16 | { 17 | if (_index != value) 18 | { 19 | _index = value; 20 | NotifyPropertyChanged("Index"); 21 | } 22 | } 23 | } 24 | #endregion 25 | 26 | #region enable 27 | private bool _enable; 28 | public bool Enable 29 | { 30 | get { return _enable; } 31 | set 32 | { 33 | if (_enable != value) 34 | { 35 | _enable = value; 36 | NotifyPropertyChanged("CheckShow"); 37 | NotifyPropertyChanged("CheckHide"); 38 | } 39 | } 40 | } 41 | public Visibility CheckShow 42 | { 43 | get 44 | { 45 | return _enable ? Visibility.Visible : Visibility.Collapsed; 46 | } 47 | } 48 | public Visibility CheckHide 49 | { 50 | get 51 | { 52 | return _enable ? Visibility.Collapsed : Visibility.Visible; 53 | } 54 | } 55 | #endregion 56 | 57 | #region ip and port 58 | private string _ip; 59 | public string IP 60 | { 61 | get { return _ip; } 62 | set 63 | { 64 | if (_ip != value) 65 | { 66 | _ip = value; 67 | NotifyPropertyChanged("IpAndPort"); 68 | } 69 | } 70 | } 71 | 72 | private string _port; 73 | public string Port 74 | { 75 | get { return _port; } 76 | set 77 | { 78 | if (_port != value) 79 | { 80 | _port = value; 81 | NotifyPropertyChanged("IpAndPort"); 82 | } 83 | } 84 | } 85 | 86 | public string IpAndPort 87 | { 88 | get 89 | { 90 | if (_port.Length <= 0) 91 | { 92 | return "IP / " + _ip; 93 | } 94 | else 95 | { 96 | return "IP / " + _ip + ":" + _port; 97 | } 98 | } 99 | } 100 | #endregion 101 | 102 | #region url 103 | private string _url; 104 | public string Url 105 | { 106 | get { return _url; } 107 | set 108 | { 109 | if (_url != value) 110 | { 111 | _url = value; 112 | NotifyPropertyChanged("TipsAndUrl"); 113 | } 114 | } 115 | } 116 | public string TipsAndUrl 117 | { 118 | get { return "URL / " + _url; } 119 | } 120 | #endregion 121 | 122 | public HostModel(int index, bool enable, string ip, string port, string url) 123 | { 124 | _index = index; 125 | _enable = enable; 126 | _ip = ip; 127 | _port = port; 128 | _url = url; 129 | } 130 | 131 | #region 通知UI更新数据 132 | protected void NotifyPropertyChanged(string propertyName) 133 | { 134 | PropertyChangedEventHandler handler = PropertyChanged; 135 | if (handler != null) 136 | { 137 | handler(this, new PropertyChangedEventArgs(propertyName)); 138 | } 139 | } 140 | #endregion 141 | } 142 | } 143 | 144 | -------------------------------------------------------------------------------- /005 Global Event/Main.cs: -------------------------------------------------------------------------------- 1 | using _005_Global_Event.Tools; 2 | using Fiddler; 3 | using System.Collections; 4 | using System.Windows.Forms; 5 | using System.Windows.Forms.Integration; 6 | 7 | namespace _005_Global_Event 8 | { 9 | public class Main : UserControl, IFiddlerExtension 10 | { 11 | //UI 12 | public static Container container; 13 | //配置数据 14 | public static ArrayList mainData; 15 | 16 | public void OnBeforeUnload() 17 | { } 18 | 19 | public void OnLoad() 20 | { 21 | //初始化配置数据 22 | mainData = new ArrayList(); 23 | //新建UI对象 24 | container = new Container(); 25 | 26 | //新建一个Fiddler插件的page 27 | TabPage page = new TabPage("PlugExample"); 28 | //将page加入Fiddler的tab选项卡中 29 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 30 | 31 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 32 | ElementHost element = new ElementHost(); 33 | element.Child = container; 34 | element.Dock = DockStyle.Fill; 35 | 36 | //将WPF挂载对象添加到page中 37 | page.Controls.Add(element); 38 | 39 | //测试代码 40 | addHostRule("127.0.0.1", "8080", "www.example.com"); 41 | addHostRule("127.0.0.1", "", "www.example.com"); 42 | addHostRule("127.0.0.1", "3366", "www.example.com"); 43 | //本地存储测试代码 44 | DataTool.initFolder(); 45 | DataTool.writeConfigToFile(); 46 | } 47 | 48 | #region 暴露出去的方法 49 | //新增Host规则 50 | public static void addHostRule(string ip, string port, string url) 51 | { 52 | //新建数据 53 | HostModel rule = new HostModel(mainData.Count, true, ip, port, url); 54 | //添加数据 55 | mainData.Add(rule); 56 | //添加UI 57 | container.addHostRule(rule); 58 | } 59 | //禁止所有Host规则 60 | public static void disabledAllHostFromData() 61 | { 62 | //遍历更新数据 63 | for (int i = 0, len = mainData.Count; i < len; i++) 64 | { 65 | HostModel item = mainData[i] as HostModel; 66 | //更新数据 67 | item.Enable = false; 68 | } 69 | //重新写入文件 70 | DataTool.writeConfigToFile(); 71 | } 72 | #endregion 73 | } 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /005 Global Event/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("005 Global Event")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("005 Global Event")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("aa5d6c35-5ee4-413e-926c-163e87375b7c")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 38 | -------------------------------------------------------------------------------- /005 Global Event/Tools/AlertTool.cs: -------------------------------------------------------------------------------- 1 | using _005_Global_Event.AlertUI; 2 | using System; 3 | using System.Windows; 4 | 5 | namespace _005_Global_Event.Tools 6 | { 7 | class AlertTool 8 | { 9 | #region 暴露出去的方法 10 | //显示说明弹框 11 | public static void showExplainAlertUI() 12 | { 13 | ExplainAlertUI explainAlertUI = new ExplainAlertUI(); 14 | //初始化窗体 15 | Window window = initWindow("explain", 450, 700); 16 | //设置window窗体内容 17 | window.Content = explainAlertUI; 18 | //显示窗体 19 | window.ShowDialog(); 20 | } 21 | //显示Host弹框 22 | public static void showHostAlertUI() 23 | { 24 | HostAlertUI hostAlertUI = new HostAlertUI(); 25 | //初始化窗体 26 | Window window = initWindow("host", 310); 27 | //设置window窗体内容 28 | window.Content = hostAlertUI; 29 | //自动聚焦 30 | hostAlertUI.ip.Focus(); 31 | //显示窗体 32 | window.ShowDialog(); 33 | } 34 | #endregion 35 | 36 | #region 内部方法 37 | //初始化窗体 38 | private static Window initWindow(string type, int height, int width = 500) 39 | { 40 | Window window = new Window(); 41 | //设置宽和高 42 | window.Width = width; 43 | window.Height = height + 30;//状态栏的高度是30 44 | //去掉最小化、最大化按钮 45 | window.ResizeMode = 0; 46 | window.Title = type == "explain" ? "配置说明" : "Host配置"; 47 | //设置显示在中间 48 | window.WindowStartupLocation = WindowStartupLocation.CenterScreen; 49 | //返回对应的窗体 50 | return window; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /005 Global Event/Tools/DataTool.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections; 5 | using System.IO; 6 | 7 | namespace _005_Global_Event.Tools 8 | { 9 | class DataTool 10 | { 11 | //对应文件夹路径 12 | private static string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Fiddler2\\FiddlerExample"; 13 | //配置文件路径 14 | private static string configPath = path + "\\config.json"; 15 | 16 | #region 内部工具--配置转JSON 17 | //格式化配置数据成JSON格式 18 | private static JObject formatConfigData() 19 | { 20 | //最终结果 21 | JObject result = new JObject(); 22 | //规则数据 23 | JArray rules = new JArray(); 24 | //获取所有配置数据 25 | ArrayList items = Main.mainData; 26 | 27 | //遍历添加配置数据到rules 28 | for (int i = 0, len = items.Count; i < len; i++) 29 | { 30 | //获取对应的Item 31 | HostModel item = items[i] as HostModel; 32 | //生成Json数据 33 | JObject rule = new JObject(); 34 | rule.Add("enable", item.Enable); 35 | rule.Add("ip", item.IP); 36 | rule.Add("port", item.Port); 37 | rule.Add("url", item.Url); 38 | //填充进数据中 39 | rules.Add(rule); 40 | } 41 | 42 | //添加骨架 43 | result.Add("host", rules); 44 | 45 | return result; 46 | } 47 | #endregion 48 | 49 | #region 暴露出去的方法 50 | //初始化文件夹 51 | public static void initFolder() 52 | { 53 | //备份文件夹不存在直接创建 54 | if (!Directory.Exists(path)) 55 | { 56 | Directory.CreateDirectory(path); 57 | } 58 | } 59 | //将配置数据写到本地 60 | public static void writeConfigToFile() 61 | { 62 | try 63 | { 64 | FileStream fs = new FileStream(configPath, FileMode.Create); 65 | StreamWriter sw = new StreamWriter(fs); 66 | //开始写入 67 | sw.Write(formatConfigData().ToString()); 68 | //清空缓冲区 69 | sw.Flush(); 70 | //关闭流 71 | sw.Close(); 72 | fs.Close(); 73 | } 74 | catch (Exception e) 75 | { 76 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(writeConfigToFile函数):" + e.ToString()); 77 | } 78 | } 79 | #endregion 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /005 Global Event/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /005 Global Event/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /006 Host Event/AlertUI/ExplainAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 1、IP字段:填写映射机器的IP地址即可 21 | 2、端口字段:非必填,填写则替换为指定端口号,为空则使用请求本身的端口号 22 | 23 | 3、URL字段: 24 | 25 | 26 | 27 | 28 | 29 | 4、配置示例: 30 | 5、映射结果示例: 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /006 Host Event/AlertUI/ExplainAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace _006_Host_Event.AlertUI 4 | { 5 | /// 6 | /// ExplainAlertUI.xaml 的交互逻辑 7 | /// 8 | public partial class ExplainAlertUI : UserControl 9 | { 10 | public ExplainAlertUI() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /006 Host Event/AlertUI/HostAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /006 Host Event/AlertUI/HostAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace _006_Host_Event.AlertUI 6 | { 7 | /// 8 | /// HostAlertUI.xaml 的交互逻辑 9 | /// 10 | public partial class HostAlertUI : UserControl 11 | { 12 | private int _index; 13 | 14 | public HostAlertUI(int index = -1) 15 | { 16 | _index = index; 17 | 18 | InitializeComponent(); 19 | 20 | //初始化输入框内容 21 | initInputText(); 22 | } 23 | 24 | #region 初始化输入框内容 25 | private void initInputText() 26 | { 27 | //小于0代表是新增,直接返回 28 | if (_index < 0) 29 | { 30 | return; 31 | } 32 | 33 | //获取数据 34 | HostModel rule = Main.mainData[_index] as HostModel; 35 | 36 | //设置数据 37 | this.ip.Text = rule.IP; 38 | this.port.Text = rule.Port; 39 | this.url.Text = rule.Url; 40 | } 41 | #endregion 42 | 43 | #region 鼠标点击事件 44 | private void addHostRule(object sender, MouseButtonEventArgs e) 45 | { 46 | string ip = this.ip.Text; 47 | string port = this.port.Text; 48 | string url = this.url.Text; 49 | 50 | if (ip.Length == 0) 51 | { 52 | Fiddler.FiddlerApplication.DoNotifyUser("请填写IP", "输入提示"); 53 | return; 54 | } 55 | 56 | if (url.Length == 0) 57 | { 58 | Fiddler.FiddlerApplication.DoNotifyUser("请填写URL", "输入提示"); 59 | return; 60 | } 61 | 62 | if (_index >= 0) 63 | { 64 | //修改数据 65 | Main.modifyRuleByIndex(_index, ip, port, url); 66 | } 67 | else 68 | { 69 | //添加UI 70 | Main.addHostRule(ip, port, url); 71 | } 72 | 73 | //关闭弹框 74 | (this.Parent as Window).Close(); 75 | } 76 | #endregion 77 | 78 | #region 输入框按键监听事件 79 | private void inputKeyDown(object sender, KeyEventArgs e) 80 | { 81 | if (e.Key == Key.Enter) 82 | { 83 | addHostRule(null, null); 84 | } 85 | } 86 | #endregion 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /006 Host Event/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /006 Host Event/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using _006_Host_Event.Tools; 2 | using System; 3 | using System.Collections; 4 | using System.Windows.Controls; 5 | using System.Windows.Input; 6 | using System.Windows.Shapes; 7 | 8 | namespace _006_Host_Event 9 | { 10 | /// 11 | /// Container.xaml 的交互逻辑 12 | /// 13 | public partial class Container : UserControl 14 | { 15 | public Container() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | #region Alert--事件 21 | //显示说明弹框 22 | private void showExplainAlertUI(object sender, MouseButtonEventArgs e) 23 | { 24 | AlertTool.showExplainAlertUI(); 25 | } 26 | //增加Host 27 | private void addHost(object sender, MouseButtonEventArgs e) 28 | { 29 | AlertTool.showHostAlertUI(); 30 | } 31 | #endregion 32 | 33 | #region 全局事件 34 | //禁止所有Item 35 | private void disabledAllItem(object sender, MouseButtonEventArgs e) 36 | { 37 | Main.disabledAllHostFromData(); 38 | } 39 | #endregion 40 | 41 | #region 私有方法(内部工具方法) 42 | //初始化Rule面板 43 | private void initRuleToUI() 44 | { 45 | ArrayList items = Main.mainData; 46 | 47 | //遍历添加Rule到UI 48 | for (int i = 0, len = items.Count; i < len; i++) 49 | { 50 | addHostRule(items[i] as HostModel); 51 | } 52 | } 53 | #endregion 54 | 55 | #region 暴露出去的方法 56 | public void addHostRule(HostModel rule) 57 | { 58 | //创建UI对象 59 | Label label = new Label(); 60 | //设置UI对象属性 61 | label.Template = Resources["content_host"] as ControlTemplate; 62 | label.DataContext = rule; 63 | //添加Rule 64 | this.host.Children.Add(label); 65 | } 66 | //删除Rule控件 67 | public void deleteRuleFromUI(int index) 68 | { 69 | this.host.Children.RemoveAt(index); 70 | } 71 | //移动Rule控件 72 | public void moveRuleFromUI(int index, string moveType) 73 | { 74 | if (index <= 0 && moveType == "up") 75 | { 76 | Fiddler.FiddlerApplication.DoNotifyUser("已在最顶部", "无法上移"); 77 | return; 78 | } 79 | 80 | StackPanel panel = this.host; 81 | 82 | if (index == panel.Children.Count - 1 && moveType == "down") 83 | { 84 | Fiddler.FiddlerApplication.DoNotifyUser("已在最底部", "无法下移"); 85 | return; 86 | } 87 | 88 | //移除所有的Item 89 | panel.Children.Clear(); 90 | //重新渲染所有的Item 91 | initRuleToUI(); 92 | } 93 | #endregion 94 | } 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /006 Host Event/GlobalEvent.cs: -------------------------------------------------------------------------------- 1 | using _006_Host_Event.Tools; 2 | using System; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Input; 6 | using System.Windows.Shapes; 7 | 8 | namespace _006_Host_Event 9 | { 10 | partial class GlobalEvent 11 | { 12 | #region HOST事件 13 | //是否生效事件 14 | private void changeRuleEnable(object sender, MouseButtonEventArgs e) 15 | { 16 | int index = Convert.ToInt32((sender as Rectangle).Tag.ToString()); 17 | //变更状态 18 | Main.changeRuleEnableByIndex(index); 19 | } 20 | //修改规则 21 | private void modifyRule(object sender, MouseButtonEventArgs e) 22 | { 23 | int index = Convert.ToInt32((sender as Label).Tag.ToString()); 24 | //显示弹框 25 | AlertTool.showHostAlertUI(index); 26 | } 27 | #endregion 28 | 29 | #region 菜单点击事件 30 | private void handleRuleMenuClick(object sender, RoutedEventArgs e) 31 | { 32 | string type = (sender as MenuItem).Tag.ToString(); 33 | object target = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as object;//获取点击源控件 34 | int index = (int)(target as Label).Tag; 35 | 36 | if (type == "modify") 37 | { 38 | modifyRule(target, null); 39 | } 40 | else if (type == "delete") 41 | { 42 | //删除数据 43 | Main.deleteRuleByIndex(index); 44 | //删除对应UI 45 | Main.container.deleteRuleFromUI(index); 46 | } 47 | else if (type == "up" || type == "down") 48 | { 49 | //移动对应的数据 50 | Main.moveRuleByType(index, type); 51 | //移动对应的UI 52 | Main.container.moveRuleFromUI(index, type); 53 | } 54 | } 55 | #endregion 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /006 Host Event/HostModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | 4 | namespace _006_Host_Event 5 | { 6 | public class HostModel : INotifyPropertyChanged 7 | { 8 | public event PropertyChangedEventHandler PropertyChanged; 9 | 10 | #region index 11 | private int _index; 12 | public int Index 13 | { 14 | get { return _index; } 15 | set 16 | { 17 | if (_index != value) 18 | { 19 | _index = value; 20 | NotifyPropertyChanged("Index"); 21 | } 22 | } 23 | } 24 | #endregion 25 | 26 | #region enable 27 | private bool _enable; 28 | public bool Enable 29 | { 30 | get { return _enable; } 31 | set 32 | { 33 | if (_enable != value) 34 | { 35 | _enable = value; 36 | NotifyPropertyChanged("CheckShow"); 37 | NotifyPropertyChanged("CheckHide"); 38 | } 39 | } 40 | } 41 | public Visibility CheckShow 42 | { 43 | get 44 | { 45 | return _enable ? Visibility.Visible : Visibility.Collapsed; 46 | } 47 | } 48 | public Visibility CheckHide 49 | { 50 | get 51 | { 52 | return _enable ? Visibility.Collapsed : Visibility.Visible; 53 | } 54 | } 55 | #endregion 56 | 57 | #region ip and port 58 | private string _ip; 59 | public string IP 60 | { 61 | get { return _ip; } 62 | set 63 | { 64 | if (_ip != value) 65 | { 66 | _ip = value; 67 | NotifyPropertyChanged("IpAndPort"); 68 | } 69 | } 70 | } 71 | 72 | private string _port; 73 | public string Port 74 | { 75 | get { return _port; } 76 | set 77 | { 78 | if (_port != value) 79 | { 80 | _port = value; 81 | NotifyPropertyChanged("IpAndPort"); 82 | } 83 | } 84 | } 85 | 86 | public string IpAndPort 87 | { 88 | get 89 | { 90 | if (_port.Length <= 0) 91 | { 92 | return "IP / " + _ip; 93 | } 94 | else 95 | { 96 | return "IP / " + _ip + ":" + _port; 97 | } 98 | } 99 | } 100 | #endregion 101 | 102 | #region url 103 | private string _url; 104 | public string Url 105 | { 106 | get { return _url; } 107 | set 108 | { 109 | if (_url != value) 110 | { 111 | _url = value; 112 | NotifyPropertyChanged("TipsAndUrl"); 113 | } 114 | } 115 | } 116 | public string TipsAndUrl 117 | { 118 | get { return "URL / " + _url; } 119 | } 120 | #endregion 121 | 122 | public HostModel(int index, bool enable, string ip, string port, string url) 123 | { 124 | _index = index; 125 | _enable = enable; 126 | _ip = ip; 127 | _port = port; 128 | _url = url; 129 | } 130 | 131 | #region 通知UI更新数据 132 | protected void NotifyPropertyChanged(string propertyName) 133 | { 134 | PropertyChangedEventHandler handler = PropertyChanged; 135 | if (handler != null) 136 | { 137 | handler(this, new PropertyChangedEventArgs(propertyName)); 138 | } 139 | } 140 | #endregion 141 | } 142 | } 143 | 144 | -------------------------------------------------------------------------------- /006 Host Event/Main.cs: -------------------------------------------------------------------------------- 1 | using _006_Host_Event.Tools; 2 | using Fiddler; 3 | using System.Collections; 4 | using System.Windows.Forms; 5 | using System.Windows.Forms.Integration; 6 | 7 | namespace _006_Host_Event 8 | { 9 | public class Main : UserControl, IFiddlerExtension 10 | { 11 | //UI 12 | public static Container container; 13 | //配置数据 14 | public static ArrayList mainData; 15 | 16 | public void OnBeforeUnload() 17 | { } 18 | 19 | public void OnLoad() 20 | { 21 | //初始化配置数据 22 | mainData = new ArrayList(); 23 | //新建UI对象 24 | container = new Container(); 25 | 26 | //新建一个Fiddler插件的page 27 | TabPage page = new TabPage("PlugExample"); 28 | //将page加入Fiddler的tab选项卡中 29 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 30 | 31 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 32 | ElementHost element = new ElementHost(); 33 | element.Child = container; 34 | element.Dock = DockStyle.Fill; 35 | 36 | //将WPF挂载对象添加到page中 37 | page.Controls.Add(element); 38 | 39 | //测试代码 40 | addHostRule("127.0.0.1", "8080", "www.example.com"); 41 | addHostRule("127.0.0.1", "", "www.example.com"); 42 | addHostRule("127.0.0.1", "3366", "www.example.com"); 43 | //本地存储测试代码 44 | DataTool.initFolder(); 45 | DataTool.writeConfigToFile(); 46 | } 47 | 48 | #region 暴露出去的方法 49 | //新增Host规则 50 | public static void addHostRule(string ip, string port, string url) 51 | { 52 | //新建数据 53 | HostModel rule = new HostModel(mainData.Count, true, ip, port, url); 54 | //添加数据 55 | mainData.Add(rule); 56 | //添加UI 57 | container.addHostRule(rule); 58 | } 59 | //禁止所有Host规则 60 | public static void disabledAllHostFromData() 61 | { 62 | //遍历更新数据 63 | for (int i = 0, len = mainData.Count; i < len; i++) 64 | { 65 | HostModel item = mainData[i] as HostModel; 66 | //更新数据 67 | item.Enable = false; 68 | } 69 | //重新写入文件 70 | DataTool.writeConfigToFile(); 71 | } 72 | //变更Rule的Enable数据 73 | public static void changeRuleEnableByIndex(int index) 74 | { 75 | //获取数据 76 | HostModel rule = mainData[index] as HostModel; 77 | //变更状态 78 | rule.Enable = !rule.Enable; 79 | //重新写入文件 80 | DataTool.writeConfigToFile(); 81 | } 82 | //修改Rule数据 83 | public static void modifyRuleByIndex(int index, string ip, string port, string url) 84 | { 85 | //获取规则 86 | HostModel rule = mainData[index] as HostModel; 87 | //更新数据 88 | rule.IP = ip; 89 | rule.Port = port; 90 | rule.Url = url; 91 | //重新写入文件 92 | DataTool.writeConfigToFile(); 93 | } 94 | //删除Rule 95 | public static void deleteRuleByIndex(int index) 96 | { 97 | //删除对应的数据 98 | mainData.RemoveAt(index); 99 | 100 | //遍历修改下标值 101 | for (int i = 0, len = mainData.Count; i < len; i++) 102 | { 103 | HostModel item = mainData[i] as HostModel; 104 | item.Index = i; 105 | } 106 | 107 | //重新写入文件 108 | DataTool.writeConfigToFile(); 109 | } 110 | //移动Rule 111 | public static void moveRuleByType(int index, string moveType) 112 | { 113 | //第一个数据 114 | if (index == 0 && moveType == "up") 115 | { 116 | return; 117 | } 118 | 119 | //最后一个数据 120 | if (index == mainData.Count - 1 && moveType == "down") 121 | { 122 | return; 123 | } 124 | 125 | //移动数据 126 | if (moveType == "up") 127 | { 128 | mainData.Insert(index - 1, mainData[index]); 129 | mainData.RemoveAt(index + 1); 130 | } 131 | else 132 | { 133 | mainData.Insert(index, mainData[index + 1]); 134 | mainData.RemoveAt(index + 2); 135 | } 136 | 137 | //遍历修改下标值 138 | for (int i = 0, len = mainData.Count; i < len; i++) 139 | { 140 | HostModel item = mainData[i] as HostModel; 141 | item.Index = i; 142 | } 143 | 144 | //重新写入文件 145 | DataTool.writeConfigToFile(); 146 | } 147 | #endregion 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /006 Host Event/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("006 Host Event")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("006 Host Event")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("0d16bbd1-d098-4cdd-b49c-6b1e639f9b0c")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 38 | -------------------------------------------------------------------------------- /006 Host Event/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace _006_Host_Event.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("_006_Host_Event.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 使用此强类型资源类,为所有资源查找 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap delete { 67 | get { 68 | object obj = ResourceManager.GetObject("delete", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 75 | /// 76 | internal static System.Drawing.Bitmap down { 77 | get { 78 | object obj = ResourceManager.GetObject("down", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 85 | /// 86 | internal static System.Drawing.Bitmap modify { 87 | get { 88 | object obj = ResourceManager.GetObject("modify", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 95 | /// 96 | internal static System.Drawing.Bitmap up { 97 | get { 98 | object obj = ResourceManager.GetObject("up", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /006 Host Event/Resources/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/006 Host Event/Resources/delete.png -------------------------------------------------------------------------------- /006 Host Event/Resources/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/006 Host Event/Resources/down.png -------------------------------------------------------------------------------- /006 Host Event/Resources/modify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/006 Host Event/Resources/modify.png -------------------------------------------------------------------------------- /006 Host Event/Resources/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/006 Host Event/Resources/up.png -------------------------------------------------------------------------------- /006 Host Event/Tools/AlertTool.cs: -------------------------------------------------------------------------------- 1 | using _006_Host_Event.AlertUI; 2 | using System; 3 | using System.Windows; 4 | 5 | namespace _006_Host_Event.Tools 6 | { 7 | class AlertTool 8 | { 9 | #region 暴露出去的方法 10 | //显示说明弹框 11 | public static void showExplainAlertUI() 12 | { 13 | ExplainAlertUI explainAlertUI = new ExplainAlertUI(); 14 | //初始化窗体 15 | Window window = initWindow("explain", 450, 700); 16 | //设置window窗体内容 17 | window.Content = explainAlertUI; 18 | //显示窗体 19 | window.ShowDialog(); 20 | } 21 | //显示Host弹框 22 | public static void showHostAlertUI(int index = -1) 23 | { 24 | HostAlertUI hostAlertUI = new HostAlertUI(index); 25 | //初始化窗体 26 | Window window = initWindow("host", 310); 27 | //设置window窗体内容 28 | window.Content = hostAlertUI; 29 | //自动聚焦 30 | hostAlertUI.ip.Focus(); 31 | //显示窗体 32 | window.ShowDialog(); 33 | } 34 | #endregion 35 | 36 | #region 内部方法 37 | //初始化窗体 38 | private static Window initWindow(string type, int height, int width = 500) 39 | { 40 | Window window = new Window(); 41 | //设置宽和高 42 | window.Width = width; 43 | window.Height = height + 30;//状态栏的高度是30 44 | //去掉最小化、最大化按钮 45 | window.ResizeMode = 0; 46 | window.Title = type == "explain" ? "配置说明" : "Host配置"; 47 | //设置显示在中间 48 | window.WindowStartupLocation = WindowStartupLocation.CenterScreen; 49 | //返回对应的窗体 50 | return window; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /006 Host Event/Tools/DataTool.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections; 5 | using System.IO; 6 | 7 | namespace _006_Host_Event.Tools 8 | { 9 | class DataTool 10 | { 11 | //对应文件夹路径 12 | private static string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Fiddler2\\FiddlerExample"; 13 | //配置文件路径 14 | private static string configPath = path + "\\config.json"; 15 | 16 | #region 内部工具--配置转JSON 17 | //格式化配置数据成JSON格式 18 | private static JObject formatConfigData() 19 | { 20 | //最终结果 21 | JObject result = new JObject(); 22 | //规则数据 23 | JArray rules = new JArray(); 24 | //获取所有配置数据 25 | ArrayList items = Main.mainData; 26 | 27 | //遍历添加配置数据到rules 28 | for (int i = 0, len = items.Count; i < len; i++) 29 | { 30 | //获取对应的Item 31 | HostModel item = items[i] as HostModel; 32 | //生成Json数据 33 | JObject rule = new JObject(); 34 | rule.Add("enable", item.Enable); 35 | rule.Add("ip", item.IP); 36 | rule.Add("port", item.Port); 37 | rule.Add("url", item.Url); 38 | //填充进数据中 39 | rules.Add(rule); 40 | } 41 | 42 | //添加骨架 43 | result.Add("host", rules); 44 | 45 | return result; 46 | } 47 | #endregion 48 | 49 | #region 暴露出去的方法 50 | //初始化文件夹 51 | public static void initFolder() 52 | { 53 | //备份文件夹不存在直接创建 54 | if (!Directory.Exists(path)) 55 | { 56 | Directory.CreateDirectory(path); 57 | } 58 | } 59 | //将配置数据写到本地 60 | public static void writeConfigToFile() 61 | { 62 | try 63 | { 64 | FileStream fs = new FileStream(configPath, FileMode.Create); 65 | StreamWriter sw = new StreamWriter(fs); 66 | //开始写入 67 | sw.Write(formatConfigData().ToString()); 68 | //清空缓冲区 69 | sw.Flush(); 70 | //关闭流 71 | sw.Close(); 72 | fs.Close(); 73 | } 74 | catch (Exception e) 75 | { 76 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(writeConfigToFile函数):" + e.ToString()); 77 | } 78 | } 79 | #endregion 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /006 Host Event/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /006 Host Event/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /007 Host Mapping.md: -------------------------------------------------------------------------------- 1 | # HOST映射 2 | ## 一、初始化 3 | 1、删除之前Main类中的测试代码 4 | 2、DataTool类增加私有静态方法readConfigFromFile 5 | ``` 6 | //读取配置文件的数据 7 | private static JObject readConfigFromFile() 8 | { 9 | if (!File.Exists(configPath)) 10 | { 11 | //文件不存在,则返回null 12 | return null; 13 | } 14 | try 15 | { 16 | //读取对应文件的数据 17 | StreamReader file = new StreamReader(configPath); 18 | String content = file.ReadToEnd(); 19 | file.Close(); 20 | //解析数据 21 | JObject data = JObject.Parse(content); 22 | //返回数据 23 | return data; 24 | } 25 | catch (Exception e) 26 | { 27 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(readConfigFromFile函数):" + e.ToString()); 28 | return null; 29 | } 30 | } 31 | ``` 32 | 3、DataTool增加公有静态方法initConfigData 33 | ``` 34 | //初始化配置数据 35 | public static ArrayList initConfigData() 36 | { 37 | ArrayList result = new ArrayList(); 38 | //获取配置数据 39 | JObject config = readConfigFromFile(); 40 | 41 | if (config != null) 42 | { 43 | JArray rules = config["host"] as JArray; 44 | 45 | for (int i = 0, len = rules.Count; i < len; i++) 46 | { 47 | //获取规则 48 | JObject rule = rules[i] as JObject; 49 | //生成对应数据对象 50 | HostModel item = new HostModel(i, (bool)rule["enable"], rule["ip"].ToString(), rule["port"].ToString(), rule["url"].ToString()); 51 | //添加到结果中 52 | result.Add(item); 53 | } 54 | } 55 | 56 | //返回数据 57 | return result; 58 | } 59 | ``` 60 | 4、修改Main类OnLoad函数初始化mainData逻辑 61 | ``` 62 | //初始化配置数据 63 | mainData = DataTool.initConfigData(); 64 | ``` 65 | 5、Container类构造函数增加初始化逻辑 66 | ``` 67 | //初始化Rule面板 68 | initRuleToUI(); 69 | ``` 70 | 6、修改新增规则的Bug 71 | Main类的addHostRule方法增加写入文件逻辑 72 | ``` 73 | //重新写入文件 74 | DataTool.writeConfigToFile(); 75 | ``` 76 | 7、打包预览 77 | ![初始化](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/007%20Host%20Mapping/001.png "初始化") 78 | ## 二、Host映射 79 | 1、在Tools文件夹中新增FiddlerTool类,同时新增私有静态方法getValidRulesByType、getPathFromSession 80 | ``` 81 | //根据类型获取有效的规则 82 | private static ArrayList getValidRulesByType() 83 | { 84 | ArrayList rules = new ArrayList(); 85 | 86 | //遍历获取有效的数据 87 | for (int i = 0, len = Main.mainData.Count; i < len; i++) 88 | { 89 | HostModel item = Main.mainData[i] as HostModel; 90 | 91 | //为false则直接跳过 92 | if (!item.Enable) 93 | { 94 | continue; 95 | } 96 | 97 | rules.Add(item); 98 | } 99 | 100 | return rules; 101 | } 102 | //从Session中获取path 103 | private static string getPathFromSession(string fullUrl) 104 | { 105 | string path = fullUrl; 106 | 107 | if (path.IndexOf("?") > 0) 108 | { 109 | path = path.Substring(0, path.IndexOf("?")); 110 | } 111 | 112 | return path; 113 | } 114 | ``` 115 | 2、FiddlerTool类中增加私有静态方法handleHostMapping 116 | ``` 117 | //HOST映射 118 | private static void handleHostMapping(Session session) 119 | { 120 | ArrayList rules = getValidRulesByType(); 121 | 122 | //如果没有有效的host配置,直接返回 123 | if (rules.Count == 0) 124 | { 125 | return; 126 | } 127 | 128 | //获取Url的Path 129 | string path = getPathFromSession(session.fullUrl); 130 | 131 | //遍历配置去修改映射值 132 | for (int i = 0; i < rules.Count; i++) 133 | { 134 | //获取对应的各种参数 135 | string url = (rules[i] as HostModel).Url.ToString(); 136 | string ip = (rules[i] as HostModel).IP.ToString(); 137 | string port = (rules[i] as HostModel).Port.ToString(); 138 | //新建正则表达式来检测 139 | Regex urlRegex = new Regex(url); 140 | //判断当前session的path是否在配置中 141 | if (path.IndexOf(url) >= 0 || urlRegex.IsMatch(path)) 142 | { 143 | //修改背景颜色、字体颜色 144 | session["ui-color"] = "#FFFFFF"; 145 | session["ui-backcolor"] = "#9966CC"; 146 | 147 | if (port.Length > 0) 148 | { 149 | session["x-overrideHost"] = ip + ":" + port; 150 | } 151 | else 152 | { 153 | //映射到对应的ip和端口(这里必须写上端口号,不然https下会有问题) 154 | session["x-overrideHost"] = ip + ":" + session.port; 155 | } 156 | session.bypassGateway = true; 157 | break; 158 | } 159 | } 160 | } 161 | ``` 162 | 3、FiddlerTool类中增加公有静态方法handleRequest 163 | ``` 164 | //监听请求前的事件 165 | public static void handleRequest(Session session) 166 | { 167 | //HOST映射 168 | handleHostMapping(session); 169 | } 170 | ``` 171 | 4、在Main类的OnLoad方法的末尾增加监听相关代码 172 | ``` 173 | //监听请求响应之前 174 | FiddlerApplication.BeforeRequest += delegate (Session session) 175 | { 176 | FiddlerTool.handleRequest(session); 177 | }; 178 | ``` 179 | 5、打包插件,然后起一个简单的Node服务,端口设置为3333,并重新设置插件规则 180 | ![重置规则](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/007%20Host%20Mapping/002.png "重置规则") 181 | 6、浏览器访问www.example.com 182 | ![浏览器访问](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/007%20Host%20Mapping/003.png "浏览器访问") 183 | ![映射结果](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/007%20Host%20Mapping/004.png "映射结果") 184 | -------------------------------------------------------------------------------- /007 Host Mapping/AlertUI/ExplainAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 1、IP字段:填写映射机器的IP地址即可 21 | 2、端口字段:非必填,填写则替换为指定端口号,为空则使用请求本身的端口号 22 | 23 | 3、URL字段: 24 | 25 | 26 | 27 | 28 | 29 | 4、配置示例: 30 | 5、映射结果示例: 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /007 Host Mapping/AlertUI/ExplainAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace _007_Host_Mapping.AlertUI 4 | { 5 | /// 6 | /// ExplainAlertUI.xaml 的交互逻辑 7 | /// 8 | public partial class ExplainAlertUI : UserControl 9 | { 10 | public ExplainAlertUI() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /007 Host Mapping/AlertUI/HostAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /007 Host Mapping/AlertUI/HostAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace _007_Host_Mapping.AlertUI 6 | { 7 | /// 8 | /// HostAlertUI.xaml 的交互逻辑 9 | /// 10 | public partial class HostAlertUI : UserControl 11 | { 12 | private int _index; 13 | 14 | public HostAlertUI(int index = -1) 15 | { 16 | _index = index; 17 | 18 | InitializeComponent(); 19 | 20 | //初始化输入框内容 21 | initInputText(); 22 | } 23 | 24 | #region 初始化输入框内容 25 | private void initInputText() 26 | { 27 | //小于0代表是新增,直接返回 28 | if (_index < 0) 29 | { 30 | return; 31 | } 32 | 33 | //获取数据 34 | HostModel rule = Main.mainData[_index] as HostModel; 35 | 36 | //设置数据 37 | this.ip.Text = rule.IP; 38 | this.port.Text = rule.Port; 39 | this.url.Text = rule.Url; 40 | } 41 | #endregion 42 | 43 | #region 鼠标点击事件 44 | private void addHostRule(object sender, MouseButtonEventArgs e) 45 | { 46 | string ip = this.ip.Text; 47 | string port = this.port.Text; 48 | string url = this.url.Text; 49 | 50 | if (ip.Length == 0) 51 | { 52 | Fiddler.FiddlerApplication.DoNotifyUser("请填写IP", "输入提示"); 53 | return; 54 | } 55 | 56 | if (url.Length == 0) 57 | { 58 | Fiddler.FiddlerApplication.DoNotifyUser("请填写URL", "输入提示"); 59 | return; 60 | } 61 | 62 | if (_index >= 0) 63 | { 64 | //修改数据 65 | Main.modifyRuleByIndex(_index, ip, port, url); 66 | } 67 | else 68 | { 69 | //添加UI 70 | Main.addHostRule(ip, port, url); 71 | } 72 | 73 | //关闭弹框 74 | (this.Parent as Window).Close(); 75 | } 76 | #endregion 77 | 78 | #region 输入框按键监听事件 79 | private void inputKeyDown(object sender, KeyEventArgs e) 80 | { 81 | if (e.Key == Key.Enter) 82 | { 83 | addHostRule(null, null); 84 | } 85 | } 86 | #endregion 87 | } 88 | } -------------------------------------------------------------------------------- /007 Host Mapping/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /007 Host Mapping/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using _007_Host_Mapping.Tools; 2 | using System; 3 | using System.Collections; 4 | using System.Windows.Controls; 5 | using System.Windows.Input; 6 | using System.Windows.Shapes; 7 | 8 | namespace _007_Host_Mapping 9 | { 10 | /// 11 | /// Container.xaml 的交互逻辑 12 | /// 13 | public partial class Container : UserControl 14 | { 15 | public Container() 16 | { 17 | InitializeComponent(); 18 | //初始化Rule面板 19 | initRuleToUI(); 20 | } 21 | 22 | #region Alert--事件 23 | //显示说明弹框 24 | private void showExplainAlertUI(object sender, MouseButtonEventArgs e) 25 | { 26 | AlertTool.showExplainAlertUI(); 27 | } 28 | //增加Host 29 | private void addHost(object sender, MouseButtonEventArgs e) 30 | { 31 | AlertTool.showHostAlertUI(); 32 | } 33 | #endregion 34 | 35 | #region 全局事件 36 | //禁止所有Item 37 | private void disabledAllItem(object sender, MouseButtonEventArgs e) 38 | { 39 | Main.disabledAllHostFromData(); 40 | } 41 | #endregion 42 | 43 | #region 私有方法(内部工具方法) 44 | //初始化Rule面板 45 | private void initRuleToUI() 46 | { 47 | ArrayList items = Main.mainData; 48 | 49 | //遍历添加Rule到UI 50 | for (int i = 0, len = items.Count; i < len; i++) 51 | { 52 | addHostRule(items[i] as HostModel); 53 | } 54 | } 55 | #endregion 56 | 57 | #region 暴露出去的方法 58 | public void addHostRule(HostModel rule) 59 | { 60 | //创建UI对象 61 | Label label = new Label(); 62 | //设置UI对象属性 63 | label.Template = Resources["content_host"] as ControlTemplate; 64 | label.DataContext = rule; 65 | //添加Rule 66 | this.host.Children.Add(label); 67 | } 68 | //删除Rule控件 69 | public void deleteRuleFromUI(int index) 70 | { 71 | this.host.Children.RemoveAt(index); 72 | } 73 | //移动Rule控件 74 | public void moveRuleFromUI(int index, string moveType) 75 | { 76 | if (index <= 0 && moveType == "up") 77 | { 78 | Fiddler.FiddlerApplication.DoNotifyUser("已在最顶部", "无法上移"); 79 | return; 80 | } 81 | 82 | StackPanel panel = this.host; 83 | 84 | if (index == panel.Children.Count - 1 && moveType == "down") 85 | { 86 | Fiddler.FiddlerApplication.DoNotifyUser("已在最底部", "无法下移"); 87 | return; 88 | } 89 | 90 | //移除所有的Item 91 | panel.Children.Clear(); 92 | //重新渲染所有的Item 93 | initRuleToUI(); 94 | } 95 | #endregion 96 | } 97 | } -------------------------------------------------------------------------------- /007 Host Mapping/GlobalEvent.cs: -------------------------------------------------------------------------------- 1 | using _007_Host_Mapping.Tools; 2 | using System; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Input; 6 | using System.Windows.Shapes; 7 | 8 | namespace _007_Host_Mapping 9 | { 10 | partial class GlobalEvent 11 | { 12 | #region HOST事件 13 | //是否生效事件 14 | private void changeRuleEnable(object sender, MouseButtonEventArgs e) 15 | { 16 | int index = Convert.ToInt32((sender as Rectangle).Tag.ToString()); 17 | //变更状态 18 | Main.changeRuleEnableByIndex(index); 19 | } 20 | //修改规则 21 | private void modifyRule(object sender, MouseButtonEventArgs e) 22 | { 23 | int index = Convert.ToInt32((sender as Label).Tag.ToString()); 24 | //显示弹框 25 | AlertTool.showHostAlertUI(index); 26 | } 27 | #endregion 28 | 29 | #region 菜单点击事件 30 | private void handleRuleMenuClick(object sender, RoutedEventArgs e) 31 | { 32 | string type = (sender as MenuItem).Tag.ToString(); 33 | object target = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as object;//获取点击源控件 34 | int index = (int)(target as Label).Tag; 35 | 36 | if (type == "modify") 37 | { 38 | modifyRule(target, null); 39 | } 40 | else if (type == "delete") 41 | { 42 | //删除数据 43 | Main.deleteRuleByIndex(index); 44 | //删除对应UI 45 | Main.container.deleteRuleFromUI(index); 46 | } 47 | else if (type == "up" || type == "down") 48 | { 49 | //移动对应的数据 50 | Main.moveRuleByType(index, type); 51 | //移动对应的UI 52 | Main.container.moveRuleFromUI(index, type); 53 | } 54 | } 55 | #endregion 56 | } 57 | } -------------------------------------------------------------------------------- /007 Host Mapping/HostModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | 4 | namespace _007_Host_Mapping 5 | { 6 | public class HostModel : INotifyPropertyChanged 7 | { 8 | public event PropertyChangedEventHandler PropertyChanged; 9 | 10 | #region index 11 | private int _index; 12 | public int Index 13 | { 14 | get { return _index; } 15 | set 16 | { 17 | if (_index != value) 18 | { 19 | _index = value; 20 | NotifyPropertyChanged("Index"); 21 | } 22 | } 23 | } 24 | #endregion 25 | 26 | #region enable 27 | private bool _enable; 28 | public bool Enable 29 | { 30 | get { return _enable; } 31 | set 32 | { 33 | if (_enable != value) 34 | { 35 | _enable = value; 36 | NotifyPropertyChanged("CheckShow"); 37 | NotifyPropertyChanged("CheckHide"); 38 | } 39 | } 40 | } 41 | public Visibility CheckShow 42 | { 43 | get 44 | { 45 | return _enable ? Visibility.Visible : Visibility.Collapsed; 46 | } 47 | } 48 | public Visibility CheckHide 49 | { 50 | get 51 | { 52 | return _enable ? Visibility.Collapsed : Visibility.Visible; 53 | } 54 | } 55 | #endregion 56 | 57 | #region ip and port 58 | private string _ip; 59 | public string IP 60 | { 61 | get { return _ip; } 62 | set 63 | { 64 | if (_ip != value) 65 | { 66 | _ip = value; 67 | NotifyPropertyChanged("IpAndPort"); 68 | } 69 | } 70 | } 71 | 72 | private string _port; 73 | public string Port 74 | { 75 | get { return _port; } 76 | set 77 | { 78 | if (_port != value) 79 | { 80 | _port = value; 81 | NotifyPropertyChanged("IpAndPort"); 82 | } 83 | } 84 | } 85 | 86 | public string IpAndPort 87 | { 88 | get 89 | { 90 | if (_port.Length <= 0) 91 | { 92 | return "IP / " + _ip; 93 | } 94 | else 95 | { 96 | return "IP / " + _ip + ":" + _port; 97 | } 98 | } 99 | } 100 | #endregion 101 | 102 | #region url 103 | private string _url; 104 | public string Url 105 | { 106 | get { return _url; } 107 | set 108 | { 109 | if (_url != value) 110 | { 111 | _url = value; 112 | NotifyPropertyChanged("TipsAndUrl"); 113 | } 114 | } 115 | } 116 | public string TipsAndUrl 117 | { 118 | get { return "URL / " + _url; } 119 | } 120 | #endregion 121 | 122 | public HostModel(int index, bool enable, string ip, string port, string url) 123 | { 124 | _index = index; 125 | _enable = enable; 126 | _ip = ip; 127 | _port = port; 128 | _url = url; 129 | } 130 | 131 | #region 通知UI更新数据 132 | protected void NotifyPropertyChanged(string propertyName) 133 | { 134 | PropertyChangedEventHandler handler = PropertyChanged; 135 | if (handler != null) 136 | { 137 | handler(this, new PropertyChangedEventArgs(propertyName)); 138 | } 139 | } 140 | #endregion 141 | } 142 | } 143 | 144 | 145 | -------------------------------------------------------------------------------- /007 Host Mapping/Main.cs: -------------------------------------------------------------------------------- 1 | using _007_Host_Mapping.Tools; 2 | using Fiddler; 3 | using System.Collections; 4 | using System.Windows.Forms; 5 | using System.Windows.Forms.Integration; 6 | 7 | namespace _007_Host_Mapping 8 | { 9 | public class Main : UserControl, IFiddlerExtension 10 | { 11 | //UI 12 | public static Container container; 13 | //配置数据 14 | public static ArrayList mainData; 15 | 16 | public void OnBeforeUnload() 17 | { } 18 | 19 | public void OnLoad() 20 | { 21 | //初始化文件夹 22 | DataTool.initFolder(); 23 | //初始化配置数据 24 | mainData = DataTool.initConfigData(); 25 | //新建UI对象 26 | container = new Container(); 27 | 28 | //新建一个Fiddler插件的page 29 | TabPage page = new TabPage("PlugExample"); 30 | //将page加入Fiddler的tab选项卡中 31 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 32 | 33 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 34 | ElementHost element = new ElementHost(); 35 | element.Child = container; 36 | element.Dock = DockStyle.Fill; 37 | 38 | //将WPF挂载对象添加到page中 39 | page.Controls.Add(element); 40 | 41 | //监听请求响应之前 42 | FiddlerApplication.BeforeRequest += delegate (Session session) 43 | { 44 | FiddlerTool.handleRequest(session); 45 | }; 46 | } 47 | 48 | #region 暴露出去的方法 49 | //新增Host规则 50 | public static void addHostRule(string ip, string port, string url) 51 | { 52 | //新建数据 53 | HostModel rule = new HostModel(mainData.Count, true, ip, port, url); 54 | //添加数据 55 | mainData.Add(rule); 56 | //添加UI 57 | container.addHostRule(rule); 58 | //重新写入文件 59 | DataTool.writeConfigToFile(); 60 | } 61 | //禁止所有Host规则 62 | public static void disabledAllHostFromData() 63 | { 64 | //遍历更新数据 65 | for (int i = 0, len = mainData.Count; i < len; i++) 66 | { 67 | HostModel item = mainData[i] as HostModel; 68 | //更新数据 69 | item.Enable = false; 70 | } 71 | //重新写入文件 72 | DataTool.writeConfigToFile(); 73 | } 74 | //变更Rule的Enable数据 75 | public static void changeRuleEnableByIndex(int index) 76 | { 77 | //获取数据 78 | HostModel rule = mainData[index] as HostModel; 79 | //变更状态 80 | rule.Enable = !rule.Enable; 81 | //重新写入文件 82 | DataTool.writeConfigToFile(); 83 | } 84 | //修改Rule数据 85 | public static void modifyRuleByIndex(int index, string ip, string port, string url) 86 | { 87 | //获取规则 88 | HostModel rule = mainData[index] as HostModel; 89 | //更新数据 90 | rule.IP = ip; 91 | rule.Port = port; 92 | rule.Url = url; 93 | //重新写入文件 94 | DataTool.writeConfigToFile(); 95 | } 96 | //删除Rule 97 | public static void deleteRuleByIndex(int index) 98 | { 99 | //删除对应的数据 100 | mainData.RemoveAt(index); 101 | 102 | //遍历修改下标值 103 | for (int i = 0, len = mainData.Count; i < len; i++) 104 | { 105 | HostModel item = mainData[i] as HostModel; 106 | item.Index = i; 107 | } 108 | 109 | //重新写入文件 110 | DataTool.writeConfigToFile(); 111 | } 112 | //移动Rule 113 | public static void moveRuleByType(int index, string moveType) 114 | { 115 | //第一个数据 116 | if (index == 0 && moveType == "up") 117 | { 118 | return; 119 | } 120 | 121 | //最后一个数据 122 | if (index == mainData.Count - 1 && moveType == "down") 123 | { 124 | return; 125 | } 126 | 127 | //移动数据 128 | if (moveType == "up") 129 | { 130 | mainData.Insert(index - 1, mainData[index]); 131 | mainData.RemoveAt(index + 1); 132 | } 133 | else 134 | { 135 | mainData.Insert(index, mainData[index + 1]); 136 | mainData.RemoveAt(index + 2); 137 | } 138 | 139 | //遍历修改下标值 140 | for (int i = 0, len = mainData.Count; i < len; i++) 141 | { 142 | HostModel item = mainData[i] as HostModel; 143 | item.Index = i; 144 | } 145 | 146 | //重新写入文件 147 | DataTool.writeConfigToFile(); 148 | } 149 | #endregion 150 | } 151 | } -------------------------------------------------------------------------------- /007 Host Mapping/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("007 Host Mapping")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("007 Host Mapping")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("18eec4fc-55b2-48ed-97ee-3397bb3a6e10")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 38 | -------------------------------------------------------------------------------- /007 Host Mapping/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace _007_Host_Mapping.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("_007_Host_Mapping.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 使用此强类型资源类,为所有资源查找 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap delete { 67 | get { 68 | object obj = ResourceManager.GetObject("delete", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 75 | /// 76 | internal static System.Drawing.Bitmap down { 77 | get { 78 | object obj = ResourceManager.GetObject("down", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 85 | /// 86 | internal static System.Drawing.Bitmap modify { 87 | get { 88 | object obj = ResourceManager.GetObject("modify", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 95 | /// 96 | internal static System.Drawing.Bitmap up { 97 | get { 98 | object obj = ResourceManager.GetObject("up", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /007 Host Mapping/Resources/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/007 Host Mapping/Resources/delete.png -------------------------------------------------------------------------------- /007 Host Mapping/Resources/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/007 Host Mapping/Resources/down.png -------------------------------------------------------------------------------- /007 Host Mapping/Resources/modify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/007 Host Mapping/Resources/modify.png -------------------------------------------------------------------------------- /007 Host Mapping/Resources/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/007 Host Mapping/Resources/up.png -------------------------------------------------------------------------------- /007 Host Mapping/Tools/AlertTool.cs: -------------------------------------------------------------------------------- 1 | using _007_Host_Mapping.AlertUI; 2 | using System; 3 | using System.Windows; 4 | 5 | namespace _007_Host_Mapping.Tools 6 | { 7 | class AlertTool 8 | { 9 | #region 暴露出去的方法 10 | //显示说明弹框 11 | public static void showExplainAlertUI() 12 | { 13 | ExplainAlertUI explainAlertUI = new ExplainAlertUI(); 14 | //初始化窗体 15 | Window window = initWindow("explain", 450, 700); 16 | //设置window窗体内容 17 | window.Content = explainAlertUI; 18 | //显示窗体 19 | window.ShowDialog(); 20 | } 21 | //显示Host弹框 22 | public static void showHostAlertUI(int index = -1) 23 | { 24 | HostAlertUI hostAlertUI = new HostAlertUI(index); 25 | //初始化窗体 26 | Window window = initWindow("host", 310); 27 | //设置window窗体内容 28 | window.Content = hostAlertUI; 29 | //自动聚焦 30 | hostAlertUI.ip.Focus(); 31 | //显示窗体 32 | window.ShowDialog(); 33 | } 34 | #endregion 35 | 36 | #region 内部方法 37 | //初始化窗体 38 | private static Window initWindow(string type, int height, int width = 500) 39 | { 40 | Window window = new Window(); 41 | //设置宽和高 42 | window.Width = width; 43 | window.Height = height + 30;//状态栏的高度是30 44 | //去掉最小化、最大化按钮 45 | window.ResizeMode = 0; 46 | window.Title = type == "explain" ? "配置说明" : "Host配置"; 47 | //设置显示在中间 48 | window.WindowStartupLocation = WindowStartupLocation.CenterScreen; 49 | //返回对应的窗体 50 | return window; 51 | } 52 | #endregion 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /007 Host Mapping/Tools/DataTool.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections; 5 | using System.IO; 6 | 7 | namespace _007_Host_Mapping.Tools 8 | { 9 | class DataTool 10 | { 11 | //对应文件夹路径 12 | private static string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Fiddler2\\FiddlerExample"; 13 | //配置文件路径 14 | private static string configPath = path + "\\config.json"; 15 | 16 | #region 内部工具--配置转JSON 17 | //格式化配置数据成JSON格式 18 | private static JObject formatConfigData() 19 | { 20 | //最终结果 21 | JObject result = new JObject(); 22 | //规则数据 23 | JArray rules = new JArray(); 24 | //获取所有配置数据 25 | ArrayList items = Main.mainData; 26 | 27 | //遍历添加配置数据到rules 28 | for (int i = 0, len = items.Count; i < len; i++) 29 | { 30 | //获取对应的Item 31 | HostModel item = items[i] as HostModel; 32 | //生成Json数据 33 | JObject rule = new JObject(); 34 | rule.Add("enable", item.Enable); 35 | rule.Add("ip", item.IP); 36 | rule.Add("port", item.Port); 37 | rule.Add("url", item.Url); 38 | //填充进数据中 39 | rules.Add(rule); 40 | } 41 | 42 | //添加骨架 43 | result.Add("host", rules); 44 | 45 | return result; 46 | } 47 | //读取配置文件的数据 48 | private static JObject readConfigFromFile() 49 | { 50 | if (!File.Exists(configPath)) 51 | { 52 | //文件不存在,则返回null 53 | return null; 54 | } 55 | try 56 | { 57 | //读取对应文件的数据 58 | StreamReader file = new StreamReader(configPath); 59 | String content = file.ReadToEnd(); 60 | file.Close(); 61 | //解析数据 62 | JObject data = JObject.Parse(content); 63 | //返回数据 64 | return data; 65 | } 66 | catch (Exception e) 67 | { 68 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(readConfigFromFile函数):" + e.ToString()); 69 | return null; 70 | } 71 | } 72 | #endregion 73 | 74 | #region 暴露出去的方法 75 | //初始化文件夹 76 | public static void initFolder() 77 | { 78 | //备份文件夹不存在直接创建 79 | if (!Directory.Exists(path)) 80 | { 81 | Directory.CreateDirectory(path); 82 | } 83 | } 84 | //将配置数据写到本地 85 | public static void writeConfigToFile() 86 | { 87 | try 88 | { 89 | FileStream fs = new FileStream(configPath, FileMode.Create); 90 | StreamWriter sw = new StreamWriter(fs); 91 | //开始写入 92 | sw.Write(formatConfigData().ToString()); 93 | //清空缓冲区 94 | sw.Flush(); 95 | //关闭流 96 | sw.Close(); 97 | fs.Close(); 98 | } 99 | catch (Exception e) 100 | { 101 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(writeConfigToFile函数):" + e.ToString()); 102 | } 103 | } 104 | //初始化配置数据 105 | public static ArrayList initConfigData() 106 | { 107 | ArrayList result = new ArrayList(); 108 | //获取配置数据 109 | JObject config = readConfigFromFile(); 110 | 111 | if (config != null) 112 | { 113 | JArray rules = config["host"] as JArray; 114 | 115 | for (int i = 0, len = rules.Count; i < len; i++) 116 | { 117 | //获取规则 118 | JObject rule = rules[i] as JObject; 119 | //生成对应数据对象 120 | HostModel item = new HostModel(i, (bool)rule["enable"], rule["ip"].ToString(), rule["port"].ToString(), rule["url"].ToString()); 121 | //添加到结果中 122 | result.Add(item); 123 | } 124 | } 125 | 126 | //返回数据 127 | return result; 128 | } 129 | #endregion 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /007 Host Mapping/Tools/FiddlerTool.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using System.Collections; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace _007_Host_Mapping.Tools 6 | { 7 | class FiddlerTool 8 | { 9 | #region Fiddler监听事件 10 | //监听请求前的事件 11 | public static void handleRequest(Session session) 12 | { 13 | //HOST映射 14 | handleHostMapping(session); 15 | } 16 | //HOST映射 17 | private static void handleHostMapping(Session session) 18 | { 19 | ArrayList rules = getValidRulesByType(); 20 | 21 | //如果没有有效的host配置,直接返回 22 | if (rules.Count == 0) 23 | { 24 | return; 25 | } 26 | 27 | //获取Url的Path 28 | string path = getPathFromSession(session.fullUrl); 29 | 30 | //遍历配置去修改映射值 31 | for (int i = 0; i < rules.Count; i++) 32 | { 33 | //获取对应的各种参数 34 | string url = (rules[i] as HostModel).Url.ToString(); 35 | string ip = (rules[i] as HostModel).IP.ToString(); 36 | string port = (rules[i] as HostModel).Port.ToString(); 37 | //新建正则表达式来检测 38 | Regex urlRegex = new Regex(url); 39 | //判断当前session的path是否在配置中 40 | if (path.IndexOf(url) >= 0 || urlRegex.IsMatch(path)) 41 | { 42 | //修改背景颜色、字体颜色 43 | session["ui-color"] = "#FFFFFF"; 44 | session["ui-backcolor"] = "#9966CC"; 45 | 46 | if (port.Length > 0) 47 | { 48 | session["x-overrideHost"] = ip + ":" + port; 49 | } 50 | else 51 | { 52 | //映射到对应的ip和端口(这里必须写上端口号,不然https下会有问题) 53 | session["x-overrideHost"] = ip + ":" + session.port; 54 | } 55 | session.bypassGateway = true; 56 | break; 57 | } 58 | } 59 | } 60 | #endregion 61 | 62 | #region 内部工具函数 63 | //根据类型获取有效的规则 64 | private static ArrayList getValidRulesByType() 65 | { 66 | ArrayList rules = new ArrayList(); 67 | 68 | //遍历获取有效的数据 69 | for (int i = 0, len = Main.mainData.Count; i < len; i++) 70 | { 71 | HostModel item = Main.mainData[i] as HostModel; 72 | 73 | //为false则直接跳过 74 | if (!item.Enable) 75 | { 76 | continue; 77 | } 78 | 79 | rules.Add(item); 80 | } 81 | 82 | return rules; 83 | } 84 | //从Session中获取path 85 | private static string getPathFromSession(string fullUrl) 86 | { 87 | string path = fullUrl; 88 | 89 | if (path.IndexOf("?") > 0) 90 | { 91 | path = path.Substring(0, path.IndexOf("?")); 92 | } 93 | 94 | return path; 95 | } 96 | #endregion 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /007 Host Mapping/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /007 Host Mapping/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /008 Other.md: -------------------------------------------------------------------------------- 1 | # 其他 2 | ## 一、Icon 3 | 1、右键工程->属性->资源->图像,新增icon图标资源,修改新增资源的复制到输出目录属性为始终复制,生成操作属性为Resource 4 | 2、Main类增加构造函数 5 | ``` 6 | public Main() 7 | { 8 | //添加tab的icon图片进入列表 9 | FiddlerApplication.UI.tabsViews.ImageList.Images.Add("FiddlerExampleIcon", Properties.Resources.icon); 10 | } 11 | ``` 12 | 3、Main类的OnLoad增加初始化Icon的相关逻辑 13 | ``` 14 | //初始化icon 15 | page.ImageIndex = FiddlerApplication.UI.tabsViews.ImageList.Images.IndexOfKey("FiddlerExampleIcon"); 16 | ``` 17 | 4、AlertTool类的initWindow方法增加初始化Icon相关逻辑 18 | ``` 19 | IntPtr iconPtr = Properties.Resources.icon.GetHbitmap(); 20 | ImageSource icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(iconPtr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); 21 | //设置icon 22 | window.Icon = icon; 23 | ``` 24 | 5、打包预览 25 | ![Icon](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/008%20Other/001.png "Icon") 26 | ## 二、按需加载 27 | 1、Main类中将page提取成公有静态属性,并在构造函数中增加初始化相关逻辑 28 | ``` 29 | //新建一个Fiddler插件的page 30 | page = new TabPage("PlugExample"); 31 | //将page加入Fiddler的tab选项卡中 32 | FiddlerApplication.UI.tabsViews.TabPages.Add(page); 33 | //初始化icon 34 | page.ImageIndex = FiddlerApplication.UI.tabsViews.ImageList.Images.IndexOfKey("FiddlerExampleIcon"); 35 | ``` 36 | 2、Main类中增加私有Init方法,并删除OnLoad方法中初始化page的相关逻辑 37 | ``` 38 | private void Init() 39 | { 40 | //将WinForm和WPF联系起来(在WinForm中调用WPF) 41 | ElementHost element = new ElementHost(); 42 | element.Child = container; 43 | element.Dock = DockStyle.Fill; 44 | 45 | //将WPF挂载对象添加到page中 46 | page.Controls.Add(element); 47 | } 48 | ``` 49 | 3、Main类中的OnLoad方法增加Fiddler Tab选中委托相关逻辑 50 | ``` 51 | //创建委托对象 52 | TabControlEventHandler tabSelectedEvent = null; 53 | tabSelectedEvent = delegate (object obj, TabControlEventArgs e) 54 | { 55 | if (e.TabPage == page) 56 | { 57 | //初始化UI 58 | Init(); 59 | //移除委托监听 60 | FiddlerApplication.UI.tabsViews.Selected -= tabSelectedEvent; 61 | FiddlerApplication.Log.LogString("FiddlerExample初始化完成!"); 62 | } 63 | }; 64 | //添加委托监听 65 | FiddlerApplication.UI.tabsViews.Selected += tabSelectedEvent; 66 | ``` 67 | ## 三、数据备份 68 | 1、DataTool类新增私有静态属性backupPath 69 | ``` 70 | //备份数据路径 71 | private static string backupPath = path + "\\Backup"; 72 | ``` 73 | 2、替换DataTool类中initFolder方法的path为backupPath 74 | 3、DataTool类新增私有静态方法backupConfigFile 75 | ``` 76 | private static void backupConfigFile() 77 | { 78 | try 79 | { 80 | int fileNum = Directory.GetFiles(backupPath, "*.json").Length; 81 | 82 | if (fileNum < 10) 83 | { 84 | FileStream fs = new FileStream(backupPath + "\\backup_" + (fileNum + 1) + ".json", FileMode.Create); 85 | StreamWriter sw = new StreamWriter(fs); 86 | //开始写入 87 | sw.Write(formatConfigData().ToString()); 88 | //清空缓冲区 89 | sw.Flush(); 90 | //关闭流 91 | sw.Close(); 92 | fs.Close(); 93 | } 94 | else 95 | { 96 | //首先删除第一个文件 97 | File.Delete(backupPath + "\\backup_1.json"); 98 | //然后将之前的全部改名 99 | for (int i = 1; i < 10; i++) 100 | { 101 | File.Move(backupPath + "\\backup_" + (i + 1) + ".json", backupPath + "\\backup_" + i + ".json"); 102 | } 103 | //重新写入最新备份文件 104 | FileStream fs = new FileStream(backupPath + "\\backup_10.json", FileMode.Create); 105 | StreamWriter sw = new StreamWriter(fs); 106 | //开始写入 107 | sw.Write(formatConfigData().ToString()); 108 | //清空缓冲区 109 | sw.Flush(); 110 | //关闭流 111 | sw.Close(); 112 | fs.Close(); 113 | } 114 | } 115 | catch (Exception e) 116 | { 117 | FiddlerApplication.Log.LogString("FiddlerExample出现错误(backupConfigFile函数):" + e.ToString()); 118 | } 119 | } 120 | ``` 121 | 4、DataTool类的writeConfigToFile方法增加数据备份逻辑 122 | ``` 123 | //数据备份 124 | backupConfigFile(); 125 | ``` 126 | ## 四、补全说明 127 | 1、在Resources文件夹中新增ExplainImages文件夹 128 | 2、截取相关配置图片,并在ExplainImages文件夹上右键选择添加现有项,将截取的图片添加到ExplainImages文件夹 129 | 3、修改新增图片的生成操作属性为Resource,复制到输出目录属性为始终复制 130 | 4、ExplainAlertUI控件添加相关图片代码 131 | ``` 132 | 4、配置示例: 133 | 134 | 5、映射结果示例: 135 | 136 | ``` 137 | 5、打包预览 138 | ![说明弹框](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/008%20Other/002.png "说明弹框") 139 | ## 五、Release版 140 | 切换打包模式为Release,然后重新生成 141 | ![Release](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/008%20Other/003.png "Release") 142 | -------------------------------------------------------------------------------- /008 Other/AlertUI/ExplainAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 1、IP字段:填写映射机器的IP地址即可 21 | 2、端口字段:非必填,填写则替换为指定端口号,为空则使用请求本身的端口号 22 | 23 | 3、URL字段: 24 | 25 | 26 | 27 | 28 | 29 | 4、配置示例: 30 | 31 | 5、映射结果示例: 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /008 Other/AlertUI/ExplainAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace _008_Other.AlertUI 4 | { 5 | /// 6 | /// ExplainAlertUI.xaml 的交互逻辑 7 | /// 8 | public partial class ExplainAlertUI : UserControl 9 | { 10 | public ExplainAlertUI() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /008 Other/AlertUI/HostAlertUI.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /008 Other/AlertUI/HostAlertUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace _008_Other.AlertUI 6 | { 7 | /// 8 | /// HostAlertUI.xaml 的交互逻辑 9 | /// 10 | public partial class HostAlertUI : UserControl 11 | { 12 | private int _index; 13 | 14 | public HostAlertUI(int index = -1) 15 | { 16 | _index = index; 17 | 18 | InitializeComponent(); 19 | 20 | //初始化输入框内容 21 | initInputText(); 22 | } 23 | 24 | #region 初始化输入框内容 25 | private void initInputText() 26 | { 27 | //小于0代表是新增,直接返回 28 | if (_index < 0) 29 | { 30 | return; 31 | } 32 | 33 | //获取数据 34 | HostModel rule = Main.mainData[_index] as HostModel; 35 | 36 | //设置数据 37 | this.ip.Text = rule.IP; 38 | this.port.Text = rule.Port; 39 | this.url.Text = rule.Url; 40 | } 41 | #endregion 42 | 43 | #region 鼠标点击事件 44 | private void addHostRule(object sender, MouseButtonEventArgs e) 45 | { 46 | string ip = this.ip.Text; 47 | string port = this.port.Text; 48 | string url = this.url.Text; 49 | 50 | if (ip.Length == 0) 51 | { 52 | Fiddler.FiddlerApplication.DoNotifyUser("请填写IP", "输入提示"); 53 | return; 54 | } 55 | 56 | if (url.Length == 0) 57 | { 58 | Fiddler.FiddlerApplication.DoNotifyUser("请填写URL", "输入提示"); 59 | return; 60 | } 61 | 62 | if (_index >= 0) 63 | { 64 | //修改数据 65 | Main.modifyRuleByIndex(_index, ip, port, url); 66 | } 67 | else 68 | { 69 | //添加UI 70 | Main.addHostRule(ip, port, url); 71 | } 72 | 73 | //关闭弹框 74 | (this.Parent as Window).Close(); 75 | } 76 | #endregion 77 | 78 | #region 输入框按键监听事件 79 | private void inputKeyDown(object sender, KeyEventArgs e) 80 | { 81 | if (e.Key == Key.Enter) 82 | { 83 | addHostRule(null, null); 84 | } 85 | } 86 | #endregion 87 | } 88 | } -------------------------------------------------------------------------------- /008 Other/Container.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /008 Other/Container.xaml.cs: -------------------------------------------------------------------------------- 1 | using _008_Other.Tools; 2 | using System.Collections; 3 | using System.Windows.Controls; 4 | using System.Windows.Input; 5 | 6 | namespace _008_Other 7 | { 8 | /// 9 | /// Container.xaml 的交互逻辑 10 | /// 11 | public partial class Container : UserControl 12 | { 13 | public Container() 14 | { 15 | InitializeComponent(); 16 | //初始化Rule面板 17 | initRuleToUI(); 18 | } 19 | 20 | #region Alert--事件 21 | //显示说明弹框 22 | private void showExplainAlertUI(object sender, MouseButtonEventArgs e) 23 | { 24 | AlertTool.showExplainAlertUI(); 25 | } 26 | //增加Host 27 | private void addHost(object sender, MouseButtonEventArgs e) 28 | { 29 | AlertTool.showHostAlertUI(); 30 | } 31 | #endregion 32 | 33 | #region 全局事件 34 | //禁止所有Item 35 | private void disabledAllItem(object sender, MouseButtonEventArgs e) 36 | { 37 | Main.disabledAllHostFromData(); 38 | } 39 | #endregion 40 | 41 | #region 私有方法(内部工具方法) 42 | //初始化Rule面板 43 | private void initRuleToUI() 44 | { 45 | ArrayList items = Main.mainData; 46 | 47 | //遍历添加Rule到UI 48 | for (int i = 0, len = items.Count; i < len; i++) 49 | { 50 | addHostRule(items[i] as HostModel); 51 | } 52 | } 53 | #endregion 54 | 55 | #region 暴露出去的方法 56 | public void addHostRule(HostModel rule) 57 | { 58 | //创建UI对象 59 | Label label = new Label(); 60 | //设置UI对象属性 61 | label.Template = Resources["content_host"] as ControlTemplate; 62 | label.DataContext = rule; 63 | //添加Rule 64 | this.host.Children.Add(label); 65 | } 66 | //删除Rule控件 67 | public void deleteRuleFromUI(int index) 68 | { 69 | this.host.Children.RemoveAt(index); 70 | } 71 | //移动Rule控件 72 | public void moveRuleFromUI(int index, string moveType) 73 | { 74 | if (index <= 0 && moveType == "up") 75 | { 76 | Fiddler.FiddlerApplication.DoNotifyUser("已在最顶部", "无法上移"); 77 | return; 78 | } 79 | 80 | StackPanel panel = this.host; 81 | 82 | if (index == panel.Children.Count - 1 && moveType == "down") 83 | { 84 | Fiddler.FiddlerApplication.DoNotifyUser("已在最底部", "无法下移"); 85 | return; 86 | } 87 | 88 | //移除所有的Item 89 | panel.Children.Clear(); 90 | //重新渲染所有的Item 91 | initRuleToUI(); 92 | } 93 | #endregion 94 | } 95 | } -------------------------------------------------------------------------------- /008 Other/GlobalEvent.cs: -------------------------------------------------------------------------------- 1 | using _008_Other.Tools; 2 | using System; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Input; 6 | using System.Windows.Shapes; 7 | 8 | namespace _008_Other 9 | { 10 | partial class GlobalEvent 11 | { 12 | #region HOST事件 13 | //是否生效事件 14 | private void changeRuleEnable(object sender, MouseButtonEventArgs e) 15 | { 16 | int index = Convert.ToInt32((sender as Rectangle).Tag.ToString()); 17 | //变更状态 18 | Main.changeRuleEnableByIndex(index); 19 | } 20 | //修改规则 21 | private void modifyRule(object sender, MouseButtonEventArgs e) 22 | { 23 | int index = Convert.ToInt32((sender as Label).Tag.ToString()); 24 | //显示弹框 25 | AlertTool.showHostAlertUI(index); 26 | } 27 | #endregion 28 | 29 | #region 菜单点击事件 30 | private void handleRuleMenuClick(object sender, RoutedEventArgs e) 31 | { 32 | string type = (sender as MenuItem).Tag.ToString(); 33 | object target = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as object;//获取点击源控件 34 | int index = (int)(target as Label).Tag; 35 | 36 | if (type == "modify") 37 | { 38 | modifyRule(target, null); 39 | } 40 | else if (type == "delete") 41 | { 42 | //删除数据 43 | Main.deleteRuleByIndex(index); 44 | //删除对应UI 45 | Main.container.deleteRuleFromUI(index); 46 | } 47 | else if (type == "up" || type == "down") 48 | { 49 | //移动对应的数据 50 | Main.moveRuleByType(index, type); 51 | //移动对应的UI 52 | Main.container.moveRuleFromUI(index, type); 53 | } 54 | } 55 | #endregion 56 | } 57 | } -------------------------------------------------------------------------------- /008 Other/HostModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | 4 | namespace _008_Other 5 | { 6 | public class HostModel : INotifyPropertyChanged 7 | { 8 | public event PropertyChangedEventHandler PropertyChanged; 9 | 10 | #region index 11 | private int _index; 12 | public int Index 13 | { 14 | get { return _index; } 15 | set 16 | { 17 | if (_index != value) 18 | { 19 | _index = value; 20 | NotifyPropertyChanged("Index"); 21 | } 22 | } 23 | } 24 | #endregion 25 | 26 | #region enable 27 | private bool _enable; 28 | public bool Enable 29 | { 30 | get { return _enable; } 31 | set 32 | { 33 | if (_enable != value) 34 | { 35 | _enable = value; 36 | NotifyPropertyChanged("CheckShow"); 37 | NotifyPropertyChanged("CheckHide"); 38 | } 39 | } 40 | } 41 | public Visibility CheckShow 42 | { 43 | get 44 | { 45 | return _enable ? Visibility.Visible : Visibility.Collapsed; 46 | } 47 | } 48 | public Visibility CheckHide 49 | { 50 | get 51 | { 52 | return _enable ? Visibility.Collapsed : Visibility.Visible; 53 | } 54 | } 55 | #endregion 56 | 57 | #region ip and port 58 | private string _ip; 59 | public string IP 60 | { 61 | get { return _ip; } 62 | set 63 | { 64 | if (_ip != value) 65 | { 66 | _ip = value; 67 | NotifyPropertyChanged("IpAndPort"); 68 | } 69 | } 70 | } 71 | 72 | private string _port; 73 | public string Port 74 | { 75 | get { return _port; } 76 | set 77 | { 78 | if (_port != value) 79 | { 80 | _port = value; 81 | NotifyPropertyChanged("IpAndPort"); 82 | } 83 | } 84 | } 85 | 86 | public string IpAndPort 87 | { 88 | get 89 | { 90 | if (_port.Length <= 0) 91 | { 92 | return "IP / " + _ip; 93 | } 94 | else 95 | { 96 | return "IP / " + _ip + ":" + _port; 97 | } 98 | } 99 | } 100 | #endregion 101 | 102 | #region url 103 | private string _url; 104 | public string Url 105 | { 106 | get { return _url; } 107 | set 108 | { 109 | if (_url != value) 110 | { 111 | _url = value; 112 | NotifyPropertyChanged("TipsAndUrl"); 113 | } 114 | } 115 | } 116 | public string TipsAndUrl 117 | { 118 | get { return "URL / " + _url; } 119 | } 120 | #endregion 121 | 122 | public HostModel(int index, bool enable, string ip, string port, string url) 123 | { 124 | _index = index; 125 | _enable = enable; 126 | _ip = ip; 127 | _port = port; 128 | _url = url; 129 | } 130 | 131 | #region 通知UI更新数据 132 | protected void NotifyPropertyChanged(string propertyName) 133 | { 134 | PropertyChangedEventHandler handler = PropertyChanged; 135 | if (handler != null) 136 | { 137 | handler(this, new PropertyChangedEventArgs(propertyName)); 138 | } 139 | } 140 | #endregion 141 | } 142 | } -------------------------------------------------------------------------------- /008 Other/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("008 Other")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("008 Other")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("6c5b4111-934c-43a3-a37e-7e77d6991a5e")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: Fiddler.RequiredVersion("5.0.0.0")] 38 | -------------------------------------------------------------------------------- /008 Other/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace _008_Other.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("_008_Other.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 使用此强类型资源类,为所有资源查找 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap delete { 67 | get { 68 | object obj = ResourceManager.GetObject("delete", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 75 | /// 76 | internal static System.Drawing.Bitmap down { 77 | get { 78 | object obj = ResourceManager.GetObject("down", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 85 | /// 86 | internal static System.Drawing.Bitmap icon { 87 | get { 88 | object obj = ResourceManager.GetObject("icon", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 95 | /// 96 | internal static System.Drawing.Bitmap modify { 97 | get { 98 | object obj = ResourceManager.GetObject("modify", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 105 | /// 106 | internal static System.Drawing.Bitmap up { 107 | get { 108 | object obj = ResourceManager.GetObject("up", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /008 Other/Resources/ExplainImages/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/ExplainImages/001.png -------------------------------------------------------------------------------- /008 Other/Resources/ExplainImages/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/ExplainImages/002.png -------------------------------------------------------------------------------- /008 Other/Resources/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/delete.png -------------------------------------------------------------------------------- /008 Other/Resources/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/down.png -------------------------------------------------------------------------------- /008 Other/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/icon.png -------------------------------------------------------------------------------- /008 Other/Resources/modify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/modify.png -------------------------------------------------------------------------------- /008 Other/Resources/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/008 Other/Resources/up.png -------------------------------------------------------------------------------- /008 Other/Tools/AlertTool.cs: -------------------------------------------------------------------------------- 1 | using _008_Other.AlertUI; 2 | using System; 3 | using System.Windows; 4 | using System.Windows.Media; 5 | using System.Windows.Media.Imaging; 6 | 7 | namespace _008_Other.Tools 8 | { 9 | class AlertTool 10 | { 11 | #region 暴露出去的方法 12 | //显示说明弹框 13 | public static void showExplainAlertUI() 14 | { 15 | ExplainAlertUI explainAlertUI = new ExplainAlertUI(); 16 | //初始化窗体 17 | Window window = initWindow("explain", 450, 700); 18 | //设置window窗体内容 19 | window.Content = explainAlertUI; 20 | //显示窗体 21 | window.ShowDialog(); 22 | } 23 | //显示Host弹框 24 | public static void showHostAlertUI(int index = -1) 25 | { 26 | HostAlertUI hostAlertUI = new HostAlertUI(index); 27 | //初始化窗体 28 | Window window = initWindow("host", 310); 29 | //设置window窗体内容 30 | window.Content = hostAlertUI; 31 | //自动聚焦 32 | hostAlertUI.ip.Focus(); 33 | //显示窗体 34 | window.ShowDialog(); 35 | } 36 | #endregion 37 | 38 | #region 内部方法 39 | //初始化窗体 40 | private static Window initWindow(string type, int height, int width = 500) 41 | { 42 | IntPtr iconPtr = Properties.Resources.icon.GetHbitmap(); 43 | ImageSource icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(iconPtr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); 44 | 45 | Window window = new Window(); 46 | //设置宽和高 47 | window.Width = width; 48 | window.Height = height + 30;//状态栏的高度是30 49 | //去掉最小化、最大化按钮 50 | window.ResizeMode = 0; 51 | window.Title = type == "explain" ? "配置说明" : "Host配置"; 52 | //设置显示在中间 53 | window.WindowStartupLocation = WindowStartupLocation.CenterScreen; 54 | //设置icon 55 | window.Icon = icon; 56 | //返回对应的窗体 57 | return window; 58 | } 59 | #endregion 60 | } 61 | } -------------------------------------------------------------------------------- /008 Other/Tools/FiddlerTool.cs: -------------------------------------------------------------------------------- 1 | using Fiddler; 2 | using System.Collections; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace _008_Other.Tools 6 | { 7 | class FiddlerTool 8 | { 9 | #region Fiddler监听事件 10 | //监听请求前的事件 11 | public static void handleRequest(Session session) 12 | { 13 | //HOST映射 14 | handleHostMapping(session); 15 | } 16 | //HOST映射 17 | private static void handleHostMapping(Session session) 18 | { 19 | ArrayList rules = getValidRulesByType(); 20 | 21 | //如果没有有效的host配置,直接返回 22 | if (rules.Count == 0) 23 | { 24 | return; 25 | } 26 | 27 | //获取Url的Path 28 | string path = getPathFromSession(session.fullUrl); 29 | 30 | //遍历配置去修改映射值 31 | for (int i = 0; i < rules.Count; i++) 32 | { 33 | //获取对应的各种参数 34 | string url = (rules[i] as HostModel).Url.ToString(); 35 | string ip = (rules[i] as HostModel).IP.ToString(); 36 | string port = (rules[i] as HostModel).Port.ToString(); 37 | //新建正则表达式来检测 38 | Regex urlRegex = new Regex(url); 39 | //判断当前session的path是否在配置中 40 | if (path.IndexOf(url) >= 0 || urlRegex.IsMatch(path)) 41 | { 42 | //修改背景颜色、字体颜色 43 | session["ui-color"] = "#FFFFFF"; 44 | session["ui-backcolor"] = "#9966CC"; 45 | 46 | if (port.Length > 0) 47 | { 48 | session["x-overrideHost"] = ip + ":" + port; 49 | } 50 | else 51 | { 52 | //映射到对应的ip和端口(这里必须写上端口号,不然https下会有问题) 53 | session["x-overrideHost"] = ip + ":" + session.port; 54 | } 55 | session.bypassGateway = true; 56 | break; 57 | } 58 | } 59 | } 60 | #endregion 61 | 62 | #region 内部工具函数 63 | //根据类型获取有效的规则 64 | private static ArrayList getValidRulesByType() 65 | { 66 | ArrayList rules = new ArrayList(); 67 | 68 | //遍历获取有效的数据 69 | for (int i = 0, len = Main.mainData.Count; i < len; i++) 70 | { 71 | HostModel item = Main.mainData[i] as HostModel; 72 | 73 | //为false则直接跳过 74 | if (!item.Enable) 75 | { 76 | continue; 77 | } 78 | 79 | rules.Add(item); 80 | } 81 | 82 | return rules; 83 | } 84 | //从Session中获取path 85 | private static string getPathFromSession(string fullUrl) 86 | { 87 | string path = fullUrl; 88 | 89 | if (path.IndexOf("?") > 0) 90 | { 91 | path = path.Substring(0, path.IndexOf("?")); 92 | } 93 | 94 | return path; 95 | } 96 | #endregion 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /008 Other/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /008 Other/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /009 Executable File.md: -------------------------------------------------------------------------------- 1 | # 可执行文件 2 | ## 一、准备 3 | 1、Nsis 4 | 使用Nsis来制作可执行文件,下载地址:https://nsis.sourceforge.io/Download 5 | 2、ico文件 6 | 可执行文件设置图标需要使用.ico文件,http://www.bitbug.net在线生成.ico文件,并命名为icon.ico 7 | 3、dll文件 8 | 008 Other工程重新编译生成,复制其中的008 Other.dll、Newtonsoft.Json.dll,并重命名008 Other.dll为FiddlerExample.dll 9 | ## 二、基础功能 10 | 1、新建FiddlerExample.nsi文件,修改文件格式为Unix,同时修改编码为GB2312 11 | 2、基本设置 12 | ``` 13 | ;命名 14 | Name "Fiddler Example" 15 | ;输出的文件名字 16 | OutFile "FiddlerExample.exe" 17 | ;设置exe文件的图标样式 18 | Icon "icon.ico" 19 | ;安装的时候是否要求管理员权限 20 | RequestExecutionLevel "admin" 21 | ;指定压缩方式 22 | SetCompressor lzma 23 | ;显示在底部的文案 24 | BrandingText "Fiddler Example v1.0.0" 25 | ;设置安装路径 26 | ;$PROGRAMFILES:程序文件目录(通常为 C:\Program Files 但是运行时会检测) 27 | InstallDir "$PROGRAMFILES\Fiddler\Scripts\" 28 | ``` 29 | 3、安装页面 30 | ``` 31 | ;包含的页面 32 | Page directory ;installation directory selection page 33 | Page instfiles ;installation page where the sections are executed 34 | ``` 35 | 4、执行命令 36 | ``` 37 | ;一个命令区段 38 | Section "Main" 39 | ;$INSTDIR:用户定义的解压路径 40 | SetOutPath "$INSTDIR" 41 | ;是否开启覆写模式 42 | SetOverwrite on 43 | ;需要打包进exe的文件 44 | File "FiddlerExample.dll" 45 | File "Newtonsoft.Json.dll" 46 | ;输出到日志中 47 | DetailPrint "安装路径:$INSTDIR" 48 | DetailPrint "安装成功!" 49 | ;使用MessageBox弹出一个对话框 50 | MessageBox MB_OK|MB_ICONEXCLAMATION "安装成功" 51 | SectionEnd 52 | ``` 53 | 5、其他设置 54 | ``` 55 | ;是否显示安装日志 56 | ShowInstDetails show 57 | ``` 58 | 6、生成Exe文件 59 | 打开NSIS软件,选择Compile NSI scripts,然后将编写好的FiddlerExample.nsi文件拖入编辑器中;或者直接FiddlerExample.nsi右键选择Compile NSI scripts 60 | ![exe打包](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/009%20Executable%20File/001.png "exe打包") 61 | 7、预览 62 | 点击编译完成的Test Installer按钮或者直接打开编译好的FiddlerExample.exe文件,然后选择目录,点击Install,执行完成以后,对应目录里面就会增加FiddlerExample.dll、Newtonsoft.Json.dll两个文件 63 | ![执行exe](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/009%20Executable%20File/002.png "执行exe") 64 | 65 | ![执行结果](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/009%20Executable%20File/003.png "执行结果") 66 | ## 三、增强体验 67 | 1、读取注册表 68 | 在设置安装路径代码下面增加注册表相关逻辑 69 | ``` 70 | ;设置安装路径 71 | ;$PROGRAMFILES:程序文件目录(通常为 C:\Program Files 但是运行时会检测) 72 | InstallDir "$PROGRAMFILES\Fiddler\Scripts\" 73 | ;读取注册表中Fiddler的安装路径(读取失败的情况下会使用上一步的路径) 74 | InstallDirRegKey HKCU "SOFTWARE\Microsoft\Fiddler2\InstallerSettings" "ScriptPath" 75 | ``` 76 | 2、引入逻辑库 77 | ``` 78 | ;引用if操作库(逻辑库) 79 | !include "LogicLib.nsh" 80 | ``` 81 | 3、引入StrContains方法 82 | 由于Nsis没有现成的字符串包含方法,因此使用官方提供的StrContains方法,文档地址:https://nsis.sourceforge.io/StrContains,拷贝源码放在代码最上面 83 | 4、Main命令区段的顶部增加路径校验逻辑 84 | ``` 85 | ;判断是否包含必要字段 86 | ${StrContains} $0 "Fiddler\Scripts" $INSTDIR 87 | ;如果结果为空(即不包含必要字段) 88 | ${If} $0 == "" 89 | MessageBox MB_OK|MB_ICONEXCLAMATION "请选择Fiddler安装目录下的Scripts文件夹" 90 | ;返回目录选择页 91 | SendMessage $HWNDPARENT 0x408 -1 0 92 | ;不执行后面的代码 93 | Abort 94 | ${EndIf} 95 | ``` 96 | 5、打包预览 97 | ![异常提示](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/009%20Executable%20File/004.png "异常提示") 98 | -------------------------------------------------------------------------------- /009 Executable File/FiddlerExample.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/009 Executable File/FiddlerExample.dll -------------------------------------------------------------------------------- /009 Executable File/FiddlerExample.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/009 Executable File/FiddlerExample.exe -------------------------------------------------------------------------------- /009 Executable File/FiddlerExample.nsi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/009 Executable File/FiddlerExample.nsi -------------------------------------------------------------------------------- /009 Executable File/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/009 Executable File/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /009 Executable File/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/009 Executable File/icon.ico -------------------------------------------------------------------------------- /Fiddler-Plug-Example.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "001 Hello World", "001 Hello World\001 Hello World.csproj", "{C3B04B3F-2112-4EC7-81CF-5215DE04CA67}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "002 Global Style", "002 Global Style\002 Global Style.csproj", "{A7909D00-35BE-4D15-AE05-36E6F9A21902}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "003 Static Page", "003 Static Page\003 Static Page.csproj", "{EEB827FA-464B-4151-80CD-CC8574F7FD1F}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "004 Data Model", "004 Data Model\004 Data Model.csproj", "{8058CCB5-E232-4E01-95B5-947BB714A9A9}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "005 Global Event", "005 Global Event\005 Global Event.csproj", "{AA5D6C35-5EE4-413E-926C-163E87375B7C}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "006 Host Event", "006 Host Event\006 Host Event.csproj", "{0D16BBD1-D098-4CDD-B49C-6B1E639F9B0C}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "007 Host Mapping", "007 Host Mapping\007 Host Mapping.csproj", "{18EEC4FC-55B2-48ED-97EE-3397BB3A6E10}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "008 Other", "008 Other\008 Other.csproj", "{6C5B4111-934C-43A3-A37E-7E77D6991A5E}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Any CPU = Debug|Any CPU 25 | Release|Any CPU = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {C3B04B3F-2112-4EC7-81CF-5215DE04CA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {C3B04B3F-2112-4EC7-81CF-5215DE04CA67}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {C3B04B3F-2112-4EC7-81CF-5215DE04CA67}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {C3B04B3F-2112-4EC7-81CF-5215DE04CA67}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {A7909D00-35BE-4D15-AE05-36E6F9A21902}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {A7909D00-35BE-4D15-AE05-36E6F9A21902}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {A7909D00-35BE-4D15-AE05-36E6F9A21902}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {A7909D00-35BE-4D15-AE05-36E6F9A21902}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {EEB827FA-464B-4151-80CD-CC8574F7FD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {EEB827FA-464B-4151-80CD-CC8574F7FD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {EEB827FA-464B-4151-80CD-CC8574F7FD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {EEB827FA-464B-4151-80CD-CC8574F7FD1F}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {8058CCB5-E232-4E01-95B5-947BB714A9A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {8058CCB5-E232-4E01-95B5-947BB714A9A9}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {8058CCB5-E232-4E01-95B5-947BB714A9A9}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {8058CCB5-E232-4E01-95B5-947BB714A9A9}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {AA5D6C35-5EE4-413E-926C-163E87375B7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {AA5D6C35-5EE4-413E-926C-163E87375B7C}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {AA5D6C35-5EE4-413E-926C-163E87375B7C}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {AA5D6C35-5EE4-413E-926C-163E87375B7C}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {0D16BBD1-D098-4CDD-B49C-6B1E639F9B0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {0D16BBD1-D098-4CDD-B49C-6B1E639F9B0C}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {0D16BBD1-D098-4CDD-B49C-6B1E639F9B0C}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {0D16BBD1-D098-4CDD-B49C-6B1E639F9B0C}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {18EEC4FC-55B2-48ED-97EE-3397BB3A6E10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {18EEC4FC-55B2-48ED-97EE-3397BB3A6E10}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {18EEC4FC-55B2-48ED-97EE-3397BB3A6E10}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {18EEC4FC-55B2-48ED-97EE-3397BB3A6E10}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {6C5B4111-934C-43A3-A37E-7E77D6991A5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {6C5B4111-934C-43A3-A37E-7E77D6991A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {6C5B4111-934C-43A3-A37E-7E77D6991A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {6C5B4111-934C-43A3-A37E-7E77D6991A5E}.Release|Any CPU.Build.0 = Release|Any CPU 60 | EndGlobalSection 61 | GlobalSection(SolutionProperties) = preSolution 62 | HideSolutionNode = FALSE 63 | EndGlobalSection 64 | EndGlobal 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fiddler插件开发笔记 2 | ### 预览 3 | ![预览](https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/master/images/preview.gif "预览") 4 | ### 目录 5 | * [001 Hello World](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/001%20Hello%20World.md) 6 | * [002 全局样式](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/002%20Global%20Style.md) 7 | * [003 静态页面](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/003%20Static%20Page.md) 8 | * [004 数据层](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/004%20Data%20Model.md) 9 | * [005 全局事件](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/005%20Global%20Event.md) 10 | * [006 HOST事件](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/006%20Host%20Event.md) 11 | * [007 HOST映射](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/007%20Host%20Mapping.md) 12 | * [008 其他](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/008%20Other.md) 13 | * [009 可执行文件](https://github.com/Ke1992/Fiddler-Plug-Example/blob/master/009%20Executable%20File.md) 14 | ### 其他 15 | #### Fiddler开启调试模式 16 | 在Fiddler的控制台中分别键入以下代码: 17 | ``` 18 | prefs set fiddler.debug.extensions.showerrors True 19 | prefs set fiddler.debug.extensions.verbose True 20 | ``` 21 | #### [Fiddler-FPlug](https://github.com/Ke1992/Fiddler-FPlug) 22 | -------------------------------------------------------------------------------- /images/001 Hello World/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/001 Hello World/001.png -------------------------------------------------------------------------------- /images/001 Hello World/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/001 Hello World/002.png -------------------------------------------------------------------------------- /images/001 Hello World/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/001 Hello World/003.png -------------------------------------------------------------------------------- /images/001 Hello World/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/001 Hello World/004.png -------------------------------------------------------------------------------- /images/001 Hello World/005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/001 Hello World/005.png -------------------------------------------------------------------------------- /images/001 Hello World/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/001 Hello World/006.png -------------------------------------------------------------------------------- /images/002 Global Style/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/002 Global Style/001.png -------------------------------------------------------------------------------- /images/002 Global Style/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/002 Global Style/002.png -------------------------------------------------------------------------------- /images/002 Global Style/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/002 Global Style/003.png -------------------------------------------------------------------------------- /images/003 Static Page/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/003 Static Page/001.png -------------------------------------------------------------------------------- /images/003 Static Page/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/003 Static Page/002.png -------------------------------------------------------------------------------- /images/003 Static Page/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/003 Static Page/003.png -------------------------------------------------------------------------------- /images/004 Data Model/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/004 Data Model/001.png -------------------------------------------------------------------------------- /images/004 Data Model/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/004 Data Model/002.png -------------------------------------------------------------------------------- /images/005 Global Event/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/005 Global Event/001.png -------------------------------------------------------------------------------- /images/005 Global Event/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/005 Global Event/002.png -------------------------------------------------------------------------------- /images/005 Global Event/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/005 Global Event/003.png -------------------------------------------------------------------------------- /images/005 Global Event/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/005 Global Event/004.png -------------------------------------------------------------------------------- /images/006 Host Event/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/006 Host Event/001.png -------------------------------------------------------------------------------- /images/006 Host Event/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/006 Host Event/002.png -------------------------------------------------------------------------------- /images/006 Host Event/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/006 Host Event/003.png -------------------------------------------------------------------------------- /images/006 Host Event/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/006 Host Event/004.png -------------------------------------------------------------------------------- /images/006 Host Event/005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/006 Host Event/005.png -------------------------------------------------------------------------------- /images/006 Host Event/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/006 Host Event/006.png -------------------------------------------------------------------------------- /images/007 Host Mapping/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/007 Host Mapping/001.png -------------------------------------------------------------------------------- /images/007 Host Mapping/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/007 Host Mapping/002.png -------------------------------------------------------------------------------- /images/007 Host Mapping/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/007 Host Mapping/003.png -------------------------------------------------------------------------------- /images/007 Host Mapping/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/007 Host Mapping/004.png -------------------------------------------------------------------------------- /images/008 Other/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/008 Other/001.png -------------------------------------------------------------------------------- /images/008 Other/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/008 Other/002.png -------------------------------------------------------------------------------- /images/008 Other/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/008 Other/003.png -------------------------------------------------------------------------------- /images/009 Executable File/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/009 Executable File/001.png -------------------------------------------------------------------------------- /images/009 Executable File/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/009 Executable File/002.png -------------------------------------------------------------------------------- /images/009 Executable File/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/009 Executable File/003.png -------------------------------------------------------------------------------- /images/009 Executable File/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/009 Executable File/004.png -------------------------------------------------------------------------------- /images/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/images/preview.gif -------------------------------------------------------------------------------- /notes/001 Hello World.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/001 Hello World.docx -------------------------------------------------------------------------------- /notes/002 全局样式.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/002 全局样式.docx -------------------------------------------------------------------------------- /notes/003 静态页面.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/003 静态页面.docx -------------------------------------------------------------------------------- /notes/004 数据层.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/004 数据层.docx -------------------------------------------------------------------------------- /notes/005 全局事件.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/005 全局事件.docx -------------------------------------------------------------------------------- /notes/006 HOST事件.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/006 HOST事件.docx -------------------------------------------------------------------------------- /notes/007 HOST映射.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/007 HOST映射.docx -------------------------------------------------------------------------------- /notes/008 其他.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/008 其他.docx -------------------------------------------------------------------------------- /notes/009 可执行文件.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ke1992/Fiddler-Plug-Example/246ffabea7cd85134a82a1f9bd280ec2b9bb1bde/notes/009 可执行文件.docx --------------------------------------------------------------------------------