├── .gitignore ├── ChromeAutoUpdate.sln ├── ChromeAutoUpdate ├── ChromeAutoUpdate.csproj ├── Chrome_64px.ico ├── Chrome_64px_1183720_easyicon.net.ico ├── FrmMain.Designer.cs ├── FrmMain.cs ├── FrmMain.resx ├── INI.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ └── Interop.NATUPNPLib.dll ├── SimpleJson.cs ├── UdpListener.cs ├── app.config ├── app.manifest ├── node.cs ├── node_key.cs ├── rsa.cs └── update.cs ├── Chrome_64px.ico ├── LICENSE ├── README.md └── build.nsi /.gitignore: -------------------------------------------------------------------------------- 1 | ChromeAutoUpdate/bin 2 | ChromeAutoUpdate/obj 3 | .vs -------------------------------------------------------------------------------- /ChromeAutoUpdate.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChromeAutoUpdate", "ChromeAutoUpdate\ChromeAutoUpdate.csproj", "{2C85C4F1-22B3-4195-9BF2-9ACF112D6D88}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2C85C4F1-22B3-4195-9BF2-9ACF112D6D88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2C85C4F1-22B3-4195-9BF2-9ACF112D6D88}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2C85C4F1-22B3-4195-9BF2-9ACF112D6D88}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2C85C4F1-22B3-4195-9BF2-9ACF112D6D88}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/ChromeAutoUpdate.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2C85C4F1-22B3-4195-9BF2-9ACF112D6D88} 8 | WinExe 9 | Properties 10 | ChromeAutoUpdate 11 | ChromeAutoUpdate 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | Chrome_64px.ico 39 | 40 | 41 | app.manifest 42 | 43 | 44 | 45 | False 46 | True 47 | Resources\Interop.NATUPNPLib.dll 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Form 62 | 63 | 64 | FrmMain.cs 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | FrmMain.cs 77 | 78 | 79 | ResXFileCodeGenerator 80 | Resources.Designer.cs 81 | Designer 82 | 83 | 84 | True 85 | Resources.resx 86 | True 87 | 88 | 89 | 90 | 91 | SettingsSingleFileGenerator 92 | Settings.Designer.cs 93 | 94 | 95 | True 96 | Settings.settings 97 | True 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 113 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Chrome_64px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenjia404/ChromeAutoUpdate/65e7b91455b1b447ecb15f04b5278ccc397c2c87/ChromeAutoUpdate/Chrome_64px.ico -------------------------------------------------------------------------------- /ChromeAutoUpdate/Chrome_64px_1183720_easyicon.net.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenjia404/ChromeAutoUpdate/65e7b91455b1b447ecb15f04b5278ccc397c2c87/ChromeAutoUpdate/Chrome_64px_1183720_easyicon.net.ico -------------------------------------------------------------------------------- /ChromeAutoUpdate/FrmMain.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ChromeAutoUpdate 2 | { 3 | partial class FrmMain 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要修改 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain)); 33 | this.lb_status = new System.Windows.Forms.Label(); 34 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 35 | this.timer1 = new System.Windows.Forms.Timer(this.components); 36 | this.lst_runlog = new System.Windows.Forms.ListBox(); 37 | this.timer_updater = new System.Windows.Forms.Timer(this.components); 38 | this.chb_start = new System.Windows.Forms.CheckBox(); 39 | this.chb_dht = new System.Windows.Forms.CheckBox(); 40 | this.lbl_dir = new System.Windows.Forms.Label(); 41 | this.txt_dir = new System.Windows.Forms.TextBox(); 42 | this.btn_dir = new System.Windows.Forms.Button(); 43 | this.btn_check_update = new System.Windows.Forms.Button(); 44 | this.lbl_Channel = new System.Windows.Forms.Label(); 45 | this.rbtnStable = new System.Windows.Forms.RadioButton(); 46 | this.rbtnBeta = new System.Windows.Forms.RadioButton(); 47 | this.rbtnDev = new System.Windows.Forms.RadioButton(); 48 | this.rbtnCanary = new System.Windows.Forms.RadioButton(); 49 | this.lbl_bit = new System.Windows.Forms.Label(); 50 | this.rbtn_bit4 = new System.Windows.Forms.RadioButton(); 51 | this.rbtn_bit8 = new System.Windows.Forms.RadioButton(); 52 | this.panel1 = new System.Windows.Forms.Panel(); 53 | this.panel2 = new System.Windows.Forms.Panel(); 54 | this.btn_open = new System.Windows.Forms.Button(); 55 | this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); 56 | this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); 57 | this.toolStripMenuItem_about = new System.Windows.Forms.ToolStripMenuItem(); 58 | this.toolStripMenuItem_update = new System.Windows.Forms.ToolStripMenuItem(); 59 | this.toolStripMenuItem_exit = new System.Windows.Forms.ToolStripMenuItem(); 60 | this.lbl_Params = new System.Windows.Forms.Label(); 61 | this.txt_Params = new System.Windows.Forms.TextBox(); 62 | this.btn_opendir = new System.Windows.Forms.Button(); 63 | this.panel1.SuspendLayout(); 64 | this.panel2.SuspendLayout(); 65 | this.contextMenuStrip.SuspendLayout(); 66 | this.SuspendLayout(); 67 | // 68 | // lb_status 69 | // 70 | this.lb_status.AutoSize = true; 71 | this.lb_status.Location = new System.Drawing.Point(10, 499); 72 | this.lb_status.Name = "lb_status"; 73 | this.lb_status.Size = new System.Drawing.Size(89, 12); 74 | this.lb_status.TabIndex = 0; 75 | this.lb_status.Text = "等待配置中……"; 76 | // 77 | // progressBar1 78 | // 79 | this.progressBar1.Location = new System.Drawing.Point(12, 462); 80 | this.progressBar1.Name = "progressBar1"; 81 | this.progressBar1.Size = new System.Drawing.Size(470, 23); 82 | this.progressBar1.TabIndex = 1; 83 | // 84 | // timer1 85 | // 86 | this.timer1.Enabled = true; 87 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 88 | // 89 | // lst_runlog 90 | // 91 | this.lst_runlog.FormattingEnabled = true; 92 | this.lst_runlog.ItemHeight = 12; 93 | this.lst_runlog.Location = new System.Drawing.Point(16, 42); 94 | this.lst_runlog.Name = "lst_runlog"; 95 | this.lst_runlog.Size = new System.Drawing.Size(456, 196); 96 | this.lst_runlog.TabIndex = 2; 97 | // 98 | // timer_updater 99 | // 100 | this.timer_updater.Interval = 3600000; 101 | this.timer_updater.Tick += new System.EventHandler(this.timer_updater_Tick); 102 | // 103 | // chb_start 104 | // 105 | this.chb_start.AutoSize = true; 106 | this.chb_start.Location = new System.Drawing.Point(410, 499); 107 | this.chb_start.Name = "chb_start"; 108 | this.chb_start.Size = new System.Drawing.Size(72, 16); 109 | this.chb_start.TabIndex = 3; 110 | this.chb_start.Text = "开机启动"; 111 | this.chb_start.UseVisualStyleBackColor = true; 112 | this.chb_start.CheckedChanged += new System.EventHandler(this.chb_start_CheckedChanged); 113 | // 114 | // chb_dht 115 | // 116 | this.chb_dht.AutoSize = true; 117 | this.chb_dht.Location = new System.Drawing.Point(362, 499); 118 | this.chb_dht.Name = "chb_dht"; 119 | this.chb_dht.Size = new System.Drawing.Size(42, 16); 120 | this.chb_dht.TabIndex = 4; 121 | this.chb_dht.Text = "DHT"; 122 | this.chb_dht.UseVisualStyleBackColor = true; 123 | this.chb_dht.CheckedChanged += new System.EventHandler(this.chb_dht_CheckedChanged); 124 | // 125 | // lbl_dir 126 | // 127 | this.lbl_dir.AutoSize = true; 128 | this.lbl_dir.Location = new System.Drawing.Point(14, 17); 129 | this.lbl_dir.Name = "lbl_dir"; 130 | this.lbl_dir.Size = new System.Drawing.Size(29, 12); 131 | this.lbl_dir.TabIndex = 5; 132 | this.lbl_dir.Text = "目录"; 133 | // 134 | // txt_dir 135 | // 136 | this.txt_dir.Location = new System.Drawing.Point(49, 14); 137 | this.txt_dir.Name = "txt_dir"; 138 | this.txt_dir.Size = new System.Drawing.Size(342, 21); 139 | this.txt_dir.TabIndex = 6; 140 | // 141 | // btn_dir 142 | // 143 | this.btn_dir.Location = new System.Drawing.Point(397, 12); 144 | this.btn_dir.Name = "btn_dir"; 145 | this.btn_dir.Size = new System.Drawing.Size(75, 23); 146 | this.btn_dir.TabIndex = 7; 147 | this.btn_dir.Text = "选择"; 148 | this.btn_dir.UseVisualStyleBackColor = true; 149 | this.btn_dir.Click += new System.EventHandler(this.btn_dir_Click); 150 | // 151 | // btn_check_update 152 | // 153 | this.btn_check_update.Location = new System.Drawing.Point(397, 424); 154 | this.btn_check_update.Name = "btn_check_update"; 155 | this.btn_check_update.Size = new System.Drawing.Size(75, 23); 156 | this.btn_check_update.TabIndex = 8; 157 | this.btn_check_update.Text = "检测更新"; 158 | this.btn_check_update.UseVisualStyleBackColor = true; 159 | this.btn_check_update.Click += new System.EventHandler(this.btn_check_update_Click); 160 | // 161 | // lbl_Channel 162 | // 163 | this.lbl_Channel.AutoSize = true; 164 | this.lbl_Channel.Location = new System.Drawing.Point(10, 9); 165 | this.lbl_Channel.Name = "lbl_Channel"; 166 | this.lbl_Channel.Size = new System.Drawing.Size(41, 12); 167 | this.lbl_Channel.TabIndex = 9; 168 | this.lbl_Channel.Text = "版本:"; 169 | // 170 | // rbtnStable 171 | // 172 | this.rbtnStable.AutoSize = true; 173 | this.rbtnStable.Location = new System.Drawing.Point(58, 7); 174 | this.rbtnStable.Name = "rbtnStable"; 175 | this.rbtnStable.Size = new System.Drawing.Size(47, 16); 176 | this.rbtnStable.TabIndex = 10; 177 | this.rbtnStable.Text = "稳定"; 178 | this.rbtnStable.UseVisualStyleBackColor = true; 179 | this.rbtnStable.CheckedChanged += new System.EventHandler(this.rbtnStable_CheckedChanged); 180 | // 181 | // rbtnBeta 182 | // 183 | this.rbtnBeta.AutoSize = true; 184 | this.rbtnBeta.Location = new System.Drawing.Point(122, 7); 185 | this.rbtnBeta.Name = "rbtnBeta"; 186 | this.rbtnBeta.Size = new System.Drawing.Size(47, 16); 187 | this.rbtnBeta.TabIndex = 10; 188 | this.rbtnBeta.Text = "测试"; 189 | this.rbtnBeta.UseVisualStyleBackColor = true; 190 | this.rbtnBeta.CheckedChanged += new System.EventHandler(this.rbtn_Beta_CheckedChanged); 191 | // 192 | // rbtnDev 193 | // 194 | this.rbtnDev.AutoSize = true; 195 | this.rbtnDev.Location = new System.Drawing.Point(189, 7); 196 | this.rbtnDev.Name = "rbtnDev"; 197 | this.rbtnDev.Size = new System.Drawing.Size(47, 16); 198 | this.rbtnDev.TabIndex = 11; 199 | this.rbtnDev.Text = "开发"; 200 | this.rbtnDev.UseVisualStyleBackColor = true; 201 | this.rbtnDev.CheckedChanged += new System.EventHandler(this.rbtn_dev_CheckedChanged); 202 | // 203 | // rbtnCanary 204 | // 205 | this.rbtnCanary.AutoSize = true; 206 | this.rbtnCanary.Location = new System.Drawing.Point(253, 7); 207 | this.rbtnCanary.Name = "rbtnCanary"; 208 | this.rbtnCanary.Size = new System.Drawing.Size(59, 16); 209 | this.rbtnCanary.TabIndex = 12; 210 | this.rbtnCanary.Text = "金丝雀"; 211 | this.rbtnCanary.UseVisualStyleBackColor = true; 212 | this.rbtnCanary.CheckedChanged += new System.EventHandler(this.rbtn_Canary_CheckedChanged); 213 | // 214 | // lbl_bit 215 | // 216 | this.lbl_bit.AutoSize = true; 217 | this.lbl_bit.Location = new System.Drawing.Point(10, 14); 218 | this.lbl_bit.Name = "lbl_bit"; 219 | this.lbl_bit.Size = new System.Drawing.Size(41, 12); 220 | this.lbl_bit.TabIndex = 9; 221 | this.lbl_bit.Text = "系统:"; 222 | // 223 | // rbtn_bit4 224 | // 225 | this.rbtn_bit4.AutoSize = true; 226 | this.rbtn_bit4.Location = new System.Drawing.Point(58, 12); 227 | this.rbtn_bit4.Name = "rbtn_bit4"; 228 | this.rbtn_bit4.Size = new System.Drawing.Size(47, 16); 229 | this.rbtn_bit4.TabIndex = 10; 230 | this.rbtn_bit4.Text = "32位"; 231 | this.rbtn_bit4.UseVisualStyleBackColor = true; 232 | this.rbtn_bit4.CheckedChanged += new System.EventHandler(this.rbtn_bit4_CheckedChanged); 233 | // 234 | // rbtn_bit8 235 | // 236 | this.rbtn_bit8.AutoSize = true; 237 | this.rbtn_bit8.Location = new System.Drawing.Point(122, 12); 238 | this.rbtn_bit8.Name = "rbtn_bit8"; 239 | this.rbtn_bit8.Size = new System.Drawing.Size(47, 16); 240 | this.rbtn_bit8.TabIndex = 10; 241 | this.rbtn_bit8.Text = "64位"; 242 | this.rbtn_bit8.UseVisualStyleBackColor = true; 243 | this.rbtn_bit8.CheckedChanged += new System.EventHandler(this.rbtn_bit8_CheckedChanged); 244 | // 245 | // panel1 246 | // 247 | this.panel1.Controls.Add(this.rbtnStable); 248 | this.panel1.Controls.Add(this.rbtnCanary); 249 | this.panel1.Controls.Add(this.lbl_Channel); 250 | this.panel1.Controls.Add(this.rbtnDev); 251 | this.panel1.Controls.Add(this.rbtnBeta); 252 | this.panel1.Location = new System.Drawing.Point(16, 244); 253 | this.panel1.Name = "panel1"; 254 | this.panel1.Size = new System.Drawing.Size(358, 31); 255 | this.panel1.TabIndex = 13; 256 | // 257 | // panel2 258 | // 259 | this.panel2.Controls.Add(this.rbtn_bit4); 260 | this.panel2.Controls.Add(this.lbl_bit); 261 | this.panel2.Controls.Add(this.rbtn_bit8); 262 | this.panel2.Location = new System.Drawing.Point(16, 281); 263 | this.panel2.Name = "panel2"; 264 | this.panel2.Size = new System.Drawing.Size(200, 31); 265 | this.panel2.TabIndex = 14; 266 | // 267 | // btn_open 268 | // 269 | this.btn_open.AccessibleRole = System.Windows.Forms.AccessibleRole.PageTabList; 270 | this.btn_open.Location = new System.Drawing.Point(310, 424); 271 | this.btn_open.Name = "btn_open"; 272 | this.btn_open.Size = new System.Drawing.Size(81, 23); 273 | this.btn_open.TabIndex = 15; 274 | this.btn_open.Text = "打开浏览器"; 275 | this.btn_open.UseVisualStyleBackColor = true; 276 | this.btn_open.Click += new System.EventHandler(this.btn_open_Click); 277 | // 278 | // notifyIcon 279 | // 280 | this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; 281 | this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); 282 | this.notifyIcon.Text = "chrome自动升级工具"; 283 | this.notifyIcon.Visible = true; 284 | this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick); 285 | // 286 | // contextMenuStrip 287 | // 288 | this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 289 | this.toolStripMenuItem_about, 290 | this.toolStripMenuItem_update, 291 | this.toolStripMenuItem_exit}); 292 | this.contextMenuStrip.Name = "contextMenuStrip"; 293 | this.contextMenuStrip.Size = new System.Drawing.Size(125, 70); 294 | // 295 | // toolStripMenuItem_about 296 | // 297 | this.toolStripMenuItem_about.Name = "toolStripMenuItem_about"; 298 | this.toolStripMenuItem_about.Size = new System.Drawing.Size(124, 22); 299 | this.toolStripMenuItem_about.Text = "关于"; 300 | this.toolStripMenuItem_about.Click += new System.EventHandler(this.toolStripMenuItem_about_Click); 301 | // 302 | // toolStripMenuItem_update 303 | // 304 | this.toolStripMenuItem_update.Name = "toolStripMenuItem_update"; 305 | this.toolStripMenuItem_update.Size = new System.Drawing.Size(124, 22); 306 | this.toolStripMenuItem_update.Text = "检测更新"; 307 | this.toolStripMenuItem_update.Click += new System.EventHandler(this.toolStripMenuItem_update_Click); 308 | // 309 | // toolStripMenuItem_exit 310 | // 311 | this.toolStripMenuItem_exit.Name = "toolStripMenuItem_exit"; 312 | this.toolStripMenuItem_exit.RightToLeftAutoMirrorImage = true; 313 | this.toolStripMenuItem_exit.Size = new System.Drawing.Size(124, 22); 314 | this.toolStripMenuItem_exit.Text = "退出"; 315 | this.toolStripMenuItem_exit.Click += new System.EventHandler(this.toolStripMenuItem_exit_Click); 316 | // 317 | // lbl_Params 318 | // 319 | this.lbl_Params.AutoSize = true; 320 | this.lbl_Params.Location = new System.Drawing.Point(16, 331); 321 | this.lbl_Params.Name = "lbl_Params"; 322 | this.lbl_Params.Size = new System.Drawing.Size(53, 12); 323 | this.lbl_Params.TabIndex = 5; 324 | this.lbl_Params.Text = "启动参数"; 325 | // 326 | // txt_Params 327 | // 328 | this.txt_Params.Location = new System.Drawing.Point(74, 327); 329 | this.txt_Params.Name = "txt_Params"; 330 | this.txt_Params.Size = new System.Drawing.Size(317, 21); 331 | this.txt_Params.TabIndex = 16; 332 | this.txt_Params.TextChanged += new System.EventHandler(this.txt_Params_TextChanged); 333 | // 334 | // btn_opendir 335 | // 336 | this.btn_opendir.AccessibleRole = System.Windows.Forms.AccessibleRole.PageTabList; 337 | this.btn_opendir.Location = new System.Drawing.Point(221, 424); 338 | this.btn_opendir.Name = "btn_opendir"; 339 | this.btn_opendir.Size = new System.Drawing.Size(81, 23); 340 | this.btn_opendir.TabIndex = 17; 341 | this.btn_opendir.Text = "打开目录"; 342 | this.btn_opendir.UseVisualStyleBackColor = true; 343 | this.btn_opendir.Click += new System.EventHandler(this.btn_opendir_Click); 344 | // 345 | // FrmMain 346 | // 347 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 348 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 349 | this.ClientSize = new System.Drawing.Size(484, 524); 350 | this.Controls.Add(this.btn_opendir); 351 | this.Controls.Add(this.txt_Params); 352 | this.Controls.Add(this.btn_open); 353 | this.Controls.Add(this.panel2); 354 | this.Controls.Add(this.panel1); 355 | this.Controls.Add(this.btn_check_update); 356 | this.Controls.Add(this.btn_dir); 357 | this.Controls.Add(this.txt_dir); 358 | this.Controls.Add(this.lbl_Params); 359 | this.Controls.Add(this.lbl_dir); 360 | this.Controls.Add(this.chb_dht); 361 | this.Controls.Add(this.chb_start); 362 | this.Controls.Add(this.lst_runlog); 363 | this.Controls.Add(this.progressBar1); 364 | this.Controls.Add(this.lb_status); 365 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 366 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 367 | this.Name = "FrmMain"; 368 | this.Text = "chrome自动更新"; 369 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmMain_FormClosing); 370 | this.Load += new System.EventHandler(this.FrmMain_Load); 371 | this.panel1.ResumeLayout(false); 372 | this.panel1.PerformLayout(); 373 | this.panel2.ResumeLayout(false); 374 | this.panel2.PerformLayout(); 375 | this.contextMenuStrip.ResumeLayout(false); 376 | this.ResumeLayout(false); 377 | this.PerformLayout(); 378 | 379 | } 380 | 381 | #endregion 382 | 383 | private System.Windows.Forms.Label lb_status; 384 | private System.Windows.Forms.ProgressBar progressBar1; 385 | private System.Windows.Forms.Timer timer1; 386 | private System.Windows.Forms.ListBox lst_runlog; 387 | private System.Windows.Forms.Timer timer_updater; 388 | private System.Windows.Forms.CheckBox chb_start; 389 | private System.Windows.Forms.CheckBox chb_dht; 390 | private System.Windows.Forms.Label lbl_dir; 391 | private System.Windows.Forms.TextBox txt_dir; 392 | private System.Windows.Forms.Button btn_dir; 393 | private System.Windows.Forms.Button btn_check_update; 394 | private System.Windows.Forms.Label lbl_Channel; 395 | private System.Windows.Forms.RadioButton rbtnStable; 396 | private System.Windows.Forms.RadioButton rbtnBeta; 397 | private System.Windows.Forms.RadioButton rbtnDev; 398 | private System.Windows.Forms.RadioButton rbtnCanary; 399 | private System.Windows.Forms.Label lbl_bit; 400 | private System.Windows.Forms.RadioButton rbtn_bit4; 401 | private System.Windows.Forms.RadioButton rbtn_bit8; 402 | private System.Windows.Forms.Panel panel1; 403 | private System.Windows.Forms.Panel panel2; 404 | private System.Windows.Forms.Button btn_open; 405 | private System.Windows.Forms.NotifyIcon notifyIcon; 406 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip; 407 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_exit; 408 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_update; 409 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_about; 410 | private System.Windows.Forms.Label lbl_Params; 411 | private System.Windows.Forms.TextBox txt_Params; 412 | private System.Windows.Forms.Button btn_opendir; 413 | } 414 | } 415 | 416 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/FrmMain.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Net.NetworkInformation; 6 | using System.Threading; 7 | using System.Windows.Forms; 8 | 9 | namespace ChromeAutoUpdate 10 | { 11 | public partial class FrmMain : Form 12 | { 13 | public string[] cmd_args; 14 | 15 | System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 16 | { 17 | string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", ""); 18 | dllName = dllName.Replace(".", "_"); 19 | if (dllName.EndsWith("_resources")) return null; 20 | System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly()); 21 | byte[] bytes = (byte[])rm.GetObject(dllName); 22 | return System.Reflection.Assembly.Load(bytes); 23 | } 24 | 25 | 26 | public FrmMain(string[] args) 27 | { 28 | this.cmd_args = args; 29 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 30 | InitializeComponent(); 31 | } 32 | 33 | //升级模块 34 | public update updater; 35 | 36 | 37 | public UdpListener uListener; 38 | 39 | 40 | private INI config; 41 | 42 | 43 | delegate void AddItemToListBoxDelegate(string str); 44 | 45 | /// 46 | /// 在ListBox中追加状态信息 47 | /// 48 | /// 要追加的信息 49 | private void AddItemToListBox(string str) 50 | { 51 | if (lst_runlog.InvokeRequired) 52 | { 53 | AddItemToListBoxDelegate d = AddItemToListBox; 54 | lst_runlog.Invoke(d, str); 55 | } 56 | else 57 | { 58 | lst_runlog.Items.Add(str); 59 | lst_runlog.SelectedIndex = lst_runlog.Items.Count - 1; 60 | lst_runlog.ClearSelected(); 61 | } 62 | } 63 | 64 | 65 | /// 66 | /// 获取mac地址 67 | /// 68 | /// 69 | public string GetMacAddressByNetworkInformation() 70 | { 71 | string key = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; 72 | string macAddress = string.Empty; 73 | try 74 | { 75 | NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); 76 | foreach (NetworkInterface adapter in nics) 77 | { 78 | if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet 79 | && adapter.GetPhysicalAddress().ToString().Length != 0) 80 | { 81 | string fRegistryKey = key + adapter.Id + "\\Connection"; 82 | RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false); 83 | if (rk != null) 84 | { 85 | string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString(); 86 | int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0)); 87 | if (fPnpInstanceID.Length > 3 && 88 | fPnpInstanceID.Substring(0, 3) == "PCI") 89 | { 90 | macAddress = adapter.GetPhysicalAddress().ToString(); 91 | for (int i = 1; i < 6; i++) 92 | { 93 | macAddress = macAddress.Insert(3 * i - 1, ":"); 94 | } 95 | break; 96 | } 97 | } 98 | 99 | } 100 | } 101 | } 102 | catch 103 | { 104 | } 105 | return macAddress; 106 | } 107 | 108 | 109 | 110 | 111 | 112 | public static bool log(Exception ex) 113 | { 114 | try 115 | { 116 | if (!File.Exists(Application.StartupPath + @"\debug")) 117 | return false; 118 | if (!Directory.Exists(Application.StartupPath + @"\log")) 119 | Directory.CreateDirectory(Application.StartupPath + @"\log"); 120 | string filename = Application.StartupPath + @"\log\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log"; 121 | using (StreamWriter sw = new StreamWriter(@filename, true))//覆盖模式写入 122 | { 123 | sw.WriteLine(DateTime.Now.ToLongTimeString() + " update:" + ex.Message + ex.StackTrace); 124 | sw.Close(); 125 | } 126 | return true; 127 | } 128 | catch 129 | { 130 | return false; 131 | } 132 | } 133 | 134 | public static bool log(string msg) 135 | { 136 | try 137 | { 138 | if (!File.Exists(Application.StartupPath + @"\debug")) 139 | return false; 140 | if (!Directory.Exists(Application.StartupPath + @"\log")) 141 | Directory.CreateDirectory(Application.StartupPath + @"\log"); 142 | string filename = Application.StartupPath + @"\log\" + DateTime.Now.ToString("yyyy-MM-dd") + ".msg.log"; 143 | using (StreamWriter sw = new StreamWriter(@filename, true))//覆盖模式写入 144 | { 145 | sw.WriteLine(DateTime.Now.ToLongTimeString() + " update:" + msg); 146 | sw.Close(); 147 | } 148 | return true; 149 | } 150 | catch 151 | { 152 | return false; 153 | } 154 | } 155 | 156 | 157 | /// 158 | /// 获取chrome目录 159 | /// 160 | /// 161 | public string getAppPath() 162 | { 163 | string app_path = Application.StartupPath + @"\Chrome-bin\"; 164 | 165 | //如果有配置文件 166 | if (File.Exists(Application.StartupPath + @"\config.ini")) 167 | { 168 | string ini_path = config.ReadValue("app", "path"); 169 | if (ini_path.Length > 3) 170 | { 171 | string localappdata = System.Environment.GetEnvironmentVariable("localappdata"); 172 | 173 | //替换环境变量 174 | app_path = app_path.Replace("%localappdata%", localappdata); 175 | 176 | } 177 | } 178 | 179 | return app_path; 180 | } 181 | 182 | /// 183 | /// 获取chrome主程序路径 184 | /// 185 | /// 186 | public string getAppFilename() 187 | { 188 | string app_path = getAppPath(); 189 | 190 | string app_filename = "chrome.exe"; 191 | 192 | app_filename = app_path + app_filename; 193 | 194 | return app_filename; 195 | } 196 | 197 | 198 | /// 199 | /// 升级逻辑 200 | /// 201 | public void update() 202 | { 203 | if(this.updater == null) 204 | this.updater = new update(); 205 | try 206 | { 207 | this.updater.checkUpdate(); 208 | } 209 | catch(Exception ex) 210 | { 211 | log(ex); 212 | } 213 | } 214 | 215 | 216 | Thread update_th; 217 | 218 | private void FrmMain_Load(object sender, EventArgs e) 219 | { 220 | bool set_from = false; 221 | 222 | this.updater = new update(); 223 | 224 | if (this.cmd_args.Length > 0) 225 | { 226 | set_from = "-set" == this.cmd_args[0].ToString(); 227 | } 228 | 229 | //更改工作目录 230 | Directory.SetCurrentDirectory(Application.StartupPath); 231 | 232 | #region 配置文件 233 | 234 | //不存在就创建 235 | if (!File.Exists(Application.StartupPath + @"\config.ini")) 236 | System.IO.File.WriteAllLines(Application.StartupPath + @"\config.ini", new string[0]); 237 | 238 | if (File.Exists(Application.StartupPath + @"\config.ini")) 239 | { 240 | this.config = new INI(Application.StartupPath + @"\config.ini"); 241 | 242 | string dht = config.ReadValue("config", "dht"); 243 | 244 | if (dht == "1" || Directory.Exists("node")) 245 | { 246 | chb_dht.Checked = true; 247 | Thread th = new Thread(StartListener); 248 | th.Start(); 249 | } 250 | 251 | 252 | string startup = config.ReadValue("config", "startup"); 253 | if (startup == "1") 254 | chb_start.Checked = true; 255 | 256 | txt_dir.Text = config.ReadValue("app", "path"); 257 | 258 | 259 | //chrome启动参数 260 | string Params = config.ReadValue("config", "Params"); 261 | txt_Params.Text = Params; 262 | 263 | 264 | //版本选择 265 | string Channel = config.ReadValue("app", "Channel"); 266 | switch(Channel) 267 | { 268 | case "Stable": 269 | rbtnStable.Checked = true; 270 | break; 271 | case "Beta": 272 | rbtnBeta.Checked = true; 273 | break; 274 | case "Dev": 275 | rbtnDev.Checked = true; 276 | break; 277 | case "Canary": 278 | rbtnCanary.Checked = true; 279 | break; 280 | default: 281 | rbtnDev.Checked = true; 282 | break; 283 | 284 | } 285 | 286 | 287 | //位数 288 | string bit = config.ReadValue("app", "bit"); 289 | switch (bit) 290 | { 291 | case "4": 292 | rbtn_bit4.Checked = true; 293 | break; 294 | case "8": 295 | rbtn_bit8.Checked = true; 296 | break; 297 | default: 298 | rbtn_bit4.Checked = true; 299 | break; 300 | 301 | } 302 | } 303 | #endregion 304 | 305 | this.updater.deleteOld(); 306 | 307 | //获取chrome主程序位置 308 | string app_filename = getAppFilename(); 309 | 310 | 311 | int processCount = 0; 312 | Process[] pa = Process.GetProcesses();//获取当前进程数组。 313 | foreach (Process PTest in pa) 314 | { 315 | if (PTest.ProcessName == Process.GetCurrentProcess().ProcessName) 316 | { 317 | processCount += 1; 318 | } 319 | } 320 | 321 | //如果已经有当前实例,启动chrome并退出 322 | if (processCount > 1 && !set_from) 323 | { 324 | if (File.Exists(app_filename)) 325 | { 326 | this.startApp(); 327 | } 328 | System.Environment.Exit(0); 329 | } 330 | 331 | //只运行DHT 332 | if (this.config.ReadValue("config", "only_dht") == "1") 333 | { 334 | this.Visible = set_from; 335 | this.TopLevel = set_from; 336 | return; 337 | } 338 | 339 | 340 | if (File.Exists(app_filename)) 341 | { 342 | this.Visible = set_from; 343 | this.TopLevel = set_from; 344 | this.startApp(); 345 | 346 | 347 | //如果存在就直接启动更新 348 | try 349 | { 350 | update_th = new Thread(update); 351 | update_th.Start(); 352 | 353 | //启动定时更新检查 354 | timer_updater.Enabled = true; 355 | } 356 | catch (Exception ex) 357 | { 358 | log(ex); 359 | } 360 | } 361 | else 362 | { 363 | this.Visible = true; 364 | this.TopLevel = true; 365 | } 366 | 367 | if (File.Exists(Application.StartupPath + @"\debug")) 368 | { 369 | this.Visible = true; 370 | this.TopLevel = true; 371 | } 372 | 373 | } 374 | 375 | 376 | /// 377 | /// 启动监听 378 | /// 379 | public void StartListener() 380 | { 381 | try 382 | { 383 | uListener = new UdpListener(); 384 | uListener.StartListener(); 385 | } 386 | catch(Exception ex) 387 | { 388 | log(ex); 389 | } 390 | } 391 | 392 | public void startApp() 393 | { 394 | string app_filename = getAppFilename(); 395 | 396 | string index = ""; 397 | 398 | string chromeParams = ""; 399 | 400 | string user_agent = ""; 401 | 402 | if(!File.Exists(app_filename)) 403 | { 404 | AddItemToListBox(app_filename + "不存在"); 405 | return; 406 | } 407 | 408 | if (File.Exists(Application.StartupPath + @"\config.ini")) 409 | { 410 | string ini_index = config.ReadValue("app", "index"); 411 | if (ini_index.Length > 3) 412 | index = ini_index; 413 | 414 | string ini_user_agent = config.ReadValue("app", "user_agent"); 415 | if (ini_user_agent.Length > 3) 416 | user_agent = ini_user_agent; 417 | 418 | string ini_chromeParams = config.ReadValue("app", "Params"); 419 | if (ini_chromeParams.Length > 3) 420 | chromeParams = ini_chromeParams; 421 | } 422 | 423 | if (user_agent.Length > 35) 424 | chromeParams += " --user-agent=\"" + user_agent + "\""; 425 | chromeParams += " " + index; 426 | log("启动:" + app_filename); 427 | //启动 428 | Process.Start(app_filename, chromeParams); 429 | AddItemToListBox("启动chrome"); 430 | } 431 | 432 | private void timer1_Tick(object sender, EventArgs e) 433 | { 434 | if(this.updater != null && updater.run_log.Count>0) 435 | { 436 | AddItemToListBox((string)updater.run_log.Dequeue()); 437 | } 438 | 439 | if(this.updater != null) 440 | { 441 | //更新进度条 442 | progressBar1.Maximum = updater.prog_totalBytes; 443 | progressBar1.Value = updater.prog_Value; 444 | 445 | //更新提示 446 | lb_status.Text = updater.la_status; 447 | } 448 | } 449 | 450 | private void timer_updater_Tick(object sender, EventArgs e) 451 | { 452 | update_th = new Thread(update); 453 | update_th.Start(); 454 | } 455 | 456 | 457 | private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) 458 | { 459 | //后台状态,不提示 460 | if(!this.Visible) 461 | { 462 | return; 463 | } 464 | 465 | //关机不提示 466 | if(e.CloseReason == CloseReason.WindowsShutDown) 467 | { 468 | System.Environment.Exit(0); 469 | } 470 | 471 | 472 | if (MessageBox.Show("确定要退出吗?", "关闭提示", MessageBoxButtons.OKCancel) == DialogResult.OK)//如果点击“确定”按钮 473 | { 474 | System.Environment.Exit(0); 475 | } 476 | else//如果点击“取消”按钮 477 | { 478 | e.Cancel = true; 479 | } 480 | } 481 | 482 | 483 | 484 | 485 | private void chb_start_CheckedChanged(object sender, EventArgs e) 486 | { 487 | RegistryKey reg = null; 488 | try 489 | { 490 | string fileName = Application.StartupPath + @"\ChromeAutoUpdate.exe"; 491 | String name = "ChromeAutoUpdate_" + Application.StartupPath.GetHashCode(); 492 | 493 | 494 | if (chb_start.Checked && config.ReadValue("config", "startup") != "1") 495 | { 496 | reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); 497 | config.Writue("config", "startup", "1"); 498 | reg.SetValue(name, fileName); 499 | } 500 | else if(chb_start.Checked == false && config.ReadValue("config", "startup") == "1") 501 | { 502 | reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); 503 | reg.SetValue(name, false); 504 | config.Writue("config", "startup", "0"); 505 | } 506 | } 507 | catch(System.Security.SecurityException) 508 | { 509 | MessageBox.Show("需要管理员权限,请重新打开本程序(右键『已管理员身份运行』后再设置)"); 510 | } 511 | } 512 | 513 | private void chb_dht_CheckedChanged(object sender, EventArgs e) 514 | { 515 | if (File.Exists(Application.StartupPath + @"\config.ini")) 516 | { 517 | if(chb_dht.Checked) 518 | config.Writue("config", "dht","1"); 519 | else 520 | config.Writue("config", "dht", "0"); 521 | } 522 | } 523 | 524 | private void btn_dir_Click(object sender, EventArgs e) 525 | { 526 | FolderBrowserDialog dilog = new FolderBrowserDialog(); 527 | dilog.Description = "请选择文件夹"; 528 | if (dilog.ShowDialog() == DialogResult.OK || dilog.ShowDialog() == DialogResult.Yes) 529 | { 530 | txt_dir.Text = dilog.SelectedPath + @"\"; 531 | } 532 | } 533 | 534 | private void btn_check_update_Click(object sender, EventArgs e) 535 | { 536 | update_th = new Thread(update); 537 | update_th.Start(); 538 | } 539 | 540 | private void rbtn_Canary_CheckedChanged(object sender, EventArgs e) 541 | { 542 | config.Writue("app", "Channel", "Canary"); 543 | } 544 | 545 | private void rbtn_Beta_CheckedChanged(object sender, EventArgs e) 546 | { 547 | config.Writue("app", "Channel", "Beta"); 548 | } 549 | 550 | private void rbtn_dev_CheckedChanged(object sender, EventArgs e) 551 | { 552 | config.Writue("app", "Channel", "Dev"); 553 | } 554 | 555 | private void rbtnStable_CheckedChanged(object sender, EventArgs e) 556 | { 557 | config.Writue("app", "Channel", "Stable"); 558 | } 559 | 560 | private void rbtn_bit8_CheckedChanged(object sender, EventArgs e) 561 | { 562 | config.Writue("app", "bit", "8"); 563 | } 564 | 565 | private void rbtn_bit4_CheckedChanged(object sender, EventArgs e) 566 | { 567 | config.Writue("app", "bit", "4"); 568 | } 569 | 570 | private void btn_open_Click(object sender, EventArgs e) 571 | { 572 | startApp(); 573 | } 574 | 575 | 576 | /// 577 | /// 通知栏右下角双击 578 | /// 579 | /// 580 | /// 581 | private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) 582 | { 583 | this.Visible = !this.TopLevel; 584 | this.TopLevel = !this.TopLevel; 585 | } 586 | 587 | 588 | /// 589 | /// 关于 590 | /// 591 | /// 592 | /// 593 | private void toolStripMenuItem_about_Click(object sender, EventArgs e) 594 | { 595 | System.Diagnostics.Process.Start("https://github.com/chenjia404/ChromeAutoUpdate"); 596 | } 597 | 598 | 599 | /// 600 | /// 检测更新 601 | /// 602 | /// 603 | /// 604 | private void toolStripMenuItem_update_Click(object sender, EventArgs e) 605 | { 606 | update_th = new Thread(update); 607 | update_th.Start(); 608 | } 609 | 610 | /// 611 | /// 退出 612 | /// 613 | /// 614 | /// 615 | private void toolStripMenuItem_exit_Click(object sender, EventArgs e) 616 | { 617 | if (MessageBox.Show("确定要退出吗?", "关闭提示", MessageBoxButtons.OKCancel) == DialogResult.OK)//如果点击“确定”按钮 618 | { 619 | System.Environment.Exit(0); 620 | } 621 | } 622 | 623 | private void txt_Params_TextChanged(object sender, EventArgs e) 624 | { 625 | config.Writue("app", "Params", txt_Params.Text); 626 | } 627 | 628 | /// 629 | /// 打开程序目录 630 | /// 631 | /// 632 | /// 633 | private void btn_opendir_Click(object sender, EventArgs e) 634 | { 635 | string OpenFolderPath = config.ReadValue("path", "path"); 636 | if(OpenFolderPath.Length == 0) 637 | { 638 | OpenFolderPath = Application.StartupPath; 639 | } 640 | System.Diagnostics.Process.Start("explorer.exe", OpenFolderPath); 641 | } 642 | } 643 | } 644 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/FrmMain.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 107, 17 125 | 126 | 127 | 242, 17 128 | 129 | 130 | 353, 17 131 | 132 | 133 | 134 | 135 | AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAA 136 | AAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAABIAAAAeAAAAIgAAACIAAAAeAAAAEgAAAAYAAAAAAAAAAAAA 137 | AAAAAAAAAAAAAAAAAAAAAAAAAAAACgkUBywlUh1uMnEqryt/ZL8cjL6/HIS0rxZghW4FGCEsAAAACgAA 138 | AAAAAAAAAAAAAAAAAAAAAAAABQsEFCJOHlQ5hTTbQJc9/0SjRP9Fpkr/ILnQ/xi77P8br+L/G5vN2xFc 139 | e1QCDhMUAAAAAAAAAAAAAAAAAAAABidaI1Y7izfbRaVF/0ivSf9Is0v/SLRL/zG2iP8Qyu3/Ecj1/xa+ 140 | 7v8YpNTbEmqNVgAAAAYAAAAAAAAAAg8jDhw8kDvZRqpH/0m1S/9Jt0z/ULpT/2LAZv9et2b/Kbyv/wnR 141 | +/8L0Pr/EsXz/xWr2dkGKjccAAAAAgAAAAQvcS9eQ6ZE/0i0S/9Jt0z/WL1b/6G/if+jlVr/pZhg/5e6 142 | nP8d0/f/CdL8/wzP+v8Pwu//EIisXgAAAAQAAAAGPJU9oUeySv9Jt0z/ULtU/6vIkf+xdCv/s3Mo/7R0 143 | KP+ydSz/jMzN/xHT/P8J0fv/C834/w6w26EAAAAGAAAABj+gQbFJtkz/SbhN/16yaP+2n3P/wH82/8OB 144 | O//Dgjz/wIA4/620mf8s2Pz/CdL8/wrR+/8JvOexAAAABgAAAAY/pUGxSbdM/0i2TP9DY5D/so+K/8qN 145 | Tv/NkVX/zZJW/8uOUP+zuqP/K9b6/wnS/P8J0vz/BsHqsQAAAAYAAAAEP6VCnUe2S/89k1v/JibE/5mM 146 | x//RmmL/1aBo/9ahaf/TnGX/kNHX/xHS+/8J0vz/B9D6/wXA6J0AAAAEAAAAADuaPU5Bp0//LEuk/yYi 147 | 3P8tKd//mpHP/7ulsP+8qbH/ma7Q/yCg5v8Xo+n/E6rv/wyr7v8Fs9lOAAAAAAAAAAAqbSsMM3N20Sgs 148 | 0f8sK+D/Ly/i/zY54v9KTeP/Sk/i/zRH4v8qQuH/Jz/g/yM63/8dO9jRCHWSDAAAAAAAAAAAAAAAACMi 149 | yjwpK9nTNTrj/zpC5f8/SOf/QEno/z9I5/88ROb/Nzzk/zAz4f8lJNjTIBzJPAAAAAAAAAAAAAAAAAAA 150 | AAAeIZ8CLDDROjhB3s9ATOX/SVfq/01c7P9LWev/RVLp/ztE4/8zOd3PJynPOhsanwIAAAAAAAAAAAAA 151 | AAAAAAAAAAAAAAAAAAA8SNEIQ1HcSk5f5pdSZOqrUWLpq0pZ5Jc+SdpKN0HPCAAAAAAAAAAAAAAAAAAA 152 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 153 | AAAAAAAA//8AAPw/AADwDwAA4AcAAMADAADAAwAAgAEAAIABAACAAQAAgAEAAMADAADAAwAA4AcAAPAP 154 | AAD8PwAA//8AAA== 155 | 156 | 157 | 158 | 159 | AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA 160 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 161 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 162 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 163 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 164 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 165 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmd 166 | EABZnRAAWZ0QAFmdEABZnAwAULiSAEnP/wBJzvwASc78AEnO/ABJzvwASc78AEnO/ABJzvwAAAAAAAAA 167 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 168 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 169 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFea 170 | DwBZnhAAWZ0QAFmdEABZnRAAWZ0QAFmdEABZnRACWZwLCE+8pQ5I0P8PSc78D0nO/AxJzvwHSc78AUnO 171 | /ABJzvwASc78AEnO/ABJzvwASc78AEnO/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 172 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 173 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 174 | AABZnRAAWZ0QAFmdEABZnRAAWZ0QAFibDwBZnRAUWZ0QN1mdEGBZnRCHWZ0QpVmcDLtTrmHISc34zEnO 175 | /MxJzvzFSc78uEnO/KJJzvyCSc78W0nO/DJJzvwRSc78AEnO/ABJzvwASc78AEnO/AAAAAAAAAAAAAAA 176 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 177 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 178 | AAAAAAAAAAAAAFmdEABZnRAAWZ0QAFmdEABZnRAAWZ0QGFmdEFNZnRCZWZ0Q0FmdEPBZnRD+WZ0Q/1md 179 | EP9ZnQ//WKAh/03Bwf9Jz///Sc78/0nO/P9Jzvz/Sc78/0nO/P1JzvztSc78yknO/JFJzvxKSc78E0nO 180 | /ABJzvwASc78AEnO/ABJzvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 181 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 182 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QAFmdEAFZnRAsWZ0Qg1mdENNZnRD6WZ0Q/1md 183 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mcDf9Tqlf/Sszy/0nO/f9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 184 | /P9Jzvz/Sc7890nO/MtJzvx3Sc78JEnO/ABJzvwASc78AEnO/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 185 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 186 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEABZnRAAWZ0QAFmdECdZnRCNWZ0Q5Fmd 187 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnQ//V5wV/067p/9Jz///Sc78/0nO 188 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/NxJzvx/Sc78HknO/ABJzvwASc78AEnO 189 | /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 190 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEABZnRAAWZ0QDlmd 191 | EG1ZnRDcWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1eZ 192 | DP9UpD//Ssnm/0nO/v9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 193 | /NFJzvxeSc78CEnO/ABJzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 194 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmd 195 | EABZnRAAWZ0QLVmdELBZnRD8WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 196 | EP9ZnRD/WZ0Q/1mdEP9Xmg//VpcP/0+0jP9Jzv7/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 197 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78+EnO/J9JzvwhSc78AEnO/ABJzvwAAAAAAAAAAAAAAAAAAAAAAAAA 198 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 199 | AAAAAAAAWZ0QAFmdEABZnRAAWZ0QUFmdENlZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 200 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WJsQ/1WWDf9UnS3/S8XV/0nP/v9Jzvz/Sc78/0nO 201 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78zEnO/D9JzvwASc78AEnO 202 | /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 203 | AAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEABZnRADWZ0QaFmdEO1ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 204 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1icEP9Vlg//VJQM/1Ct 205 | cP9Jzfn/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 206 | /P9JzvzjSc78VUnO/ABJzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 207 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEABZnRADWZ0QclmdEPRZnRD/WZ0Q/1md 208 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 209 | EP9ZnRD/VZYP/1OTDf9TmB7/TMDA/0nP//9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 210 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/OtJzvxdSc78AEnO/ABJzvwAAAAAAAAAAAAAAAAAAAAAAAAA 211 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEABZnRABWZ0Qalmd 212 | EPRZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 213 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1aXD/9Tkg7/U5IL/1ClVv9KzPL/Sc79/0nO/P9Jzvz/Sc78/0nO 214 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc7860nO/FVJzvwASc78AEnO 215 | /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmd 216 | EABZnRAAWZ0QU1mdEO5ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 217 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9WmQ//UpEO/1KRDf9SkxT/Tbmn/0nP 218 | //9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 219 | /P9JzvzjSc78P0nO/ABJzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 220 | AAAAAAAAAAAAAFmdEABZnRAAWZ0QMlmdENxZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 221 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WJoQ/1KR 222 | Dv9Rjw7/UY8L/1CdP/9KyOb/Sc7+/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 223 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/MxJzvwhSc78AEnO/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 224 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QEVmdELZZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 225 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 226 | EP9ZnRD/WZ0Q/1icEP9SkQ7/UI4O/1CODv9Qjg7/TbGL/0nO/v9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 227 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78n0nO/AhJzvwASc78AAAA 228 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QAFmdEHdZnRD+WZ0Q/1md 229 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 230 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/U5MO/0+MDf9PjQ3/T4wL/0+VK/9KxNX/Sc///0nO 231 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 232 | /PhJzvxeSc78AEnO/ABJzvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZnRAAWZ0QAFmd 233 | EC9ZnRDiWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 234 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1idD/9YnA7/WJ0O/1SVDv9Oiw3/TosN/06L 235 | Df9Oigr/Tadv/0nN+f9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 236 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc780UnO/B5JzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 237 | AABZnRAAWZ0QAFmdEANZnRCZWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 238 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1idD/9XnA3/WJwO/16gF/9mpCP/aqcq/2qn 239 | Kf9hniD/UYwS/0uICv9LiAr/TYgL/02OHf9Lvb//Sc///0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 240 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvx/Sc78AEnO/AAAAAAAAAAAAAAA 241 | AAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEABZnRA3WZ0Q61mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 242 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WJ0P/1ecDf9jox//hbVR/6zL 243 | i//I27X/2OPM/97m1f/d5tP/1OHH/7/Rq/+cu3z/cZ9A/1GLFP9KhQb/TJ5V/0nL8v9Jzv3/Sc78/0nO 244 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc783EnO 245 | /CRJzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRABWZ0QklmdEP9ZnRD/WZ0Q/1md 246 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/V5wO/2Ch 247 | Gv+RvGT/zt69/+zv6//z9Pf/8/T3//Px8v/y8PD/8vDw//Py9P/09Pf/8/P1/+fq4/+9z6j/d6JJ/02J 248 | FP9JtKX/Sc///0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 249 | /P9Jzvz/Sc78/0nO/P9Jzvx3Sc78AEnO/AAAAAAAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QIlmd 250 | EN1ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 251 | EP9ZnRD/V5wO/3GqM/+/1af/7vDt//Pz9v/x6ub/8dTC//K9nP/yrYP/8qZ5//Koe//ysov/8sWq//Hd 252 | 0f/y7+//8/T2/+fq4/+kvYT/V5xO/0jH4/9Jzv7/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 253 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78y0nO/BNJzvwASc78AAAAAAAAAAAAAAAAAAAA 254 | AABZnRAAWZ0QAFmdEGRZnRD+WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 255 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/V5wO/3qvQf/U4cf/8/P2//Ht6v/yybH/8p9t//OLTP/zhkT/84VD//OF 256 | Q//zhUP/84VD//OHRv/zkFX/8q2D//Hay//y8vL/8fHy/7vOqP9ct6P/SM77/0nO/P9Jzvz/Sc78/0nO 257 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/PdJzvxKSc78AEnO 258 | /AAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEAVZnRCrWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 259 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/V5wO/3SsOP/W4sr/8/P2//Hj2//yrIH/84lJ//OG 260 | RP/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84ZF//OFQ//zkVb/8sKm//Hu7f/z8vL/u9fF/1bK 261 | 5f9Izv3/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 262 | /P9Jzvz/Sc78kUnO/ABJzvwAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAfWZ0Q3lmdEP9ZnRD/WZ0Q/1md 263 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WJ0P/2SjIP/G2bL/8/P2//Hi 264 | 2f/yoXD/84ZE//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84ZF//OJ 265 | Sv/yupn/8e7t//Hx7/+k3ej/S877/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 266 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/MpJzvwRSc78AAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QSVmd 267 | EPhZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1ic 268 | D/+fw3n+8fHx//Hq5v/yp3r/84ZE//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 269 | Rv/zh0b/84dG//OHRv/zhkX/84pK//LFqf/y8vL/5+/w/3bX9/9Hzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 270 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9JzvztSc78MknO/ABJzvwAAAAAAAAA 271 | AABZnRAAWZ0QAFmdEHZZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 272 | EP9ZnRD/WZ0Q/1idDv9rpTP+2uPV/vPz9P/ywKL/84dH//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 273 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OGRP/zk1n/8d3R//Tz8/+85vX/Ts/8/0nO 274 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/UnO 275 | /FtJzvwASc78AAAAAAAAAAAAWZ0QAFmdEABZnRCeWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 276 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9WmhH/krGL/fHx9P/x5Nv/85df//OGRP/zh0b/84dG//OH 277 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84ZE//Kz 278 | jP/y8PD/5u/y/2/W+v9Hzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 279 | /P9Jzvz/Sc78/0nO/P9JzvyCSc78AEnO/AAAAAAAAAAAAFmdEABZnRAIWZ0Qu1mdEP9ZnRD/WZ0Q/1md 280 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9Zng7/U4k9/ri/1v709fX/8sas//OH 281 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 282 | Rv/zh0b/84dG//OGRf/zlFv/8eLZ//Py8v+b3/f/R878/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 283 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78oknO/AFJzvwAAAAAAAAAAABZnRAAWZ0QEVmd 284 | EM5ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnQ//VpgX/1Br 285 | j/7V1u3/8/Hv//KrgP/zhUP/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 286 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84hI//LNt//08/T/vub0/0zP/P9Jzvz/Sc78/0nO 287 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/LhJzvwHSc78AAAA 288 | AAAAAAAAWZ0QAFmdEBlZnRDaWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 289 | EP9ZnRD/Wp4O/0d4Tf5VXsb/5ebv//Lr5v/znGf/84ZE//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 290 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OGRP/yu5v/8/Pz/9Lr 291 | 8/9V0fv/SM78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 292 | /P9JzvzFSc78DEnO/AAAAAAAAAAAAFmdEABZnRAeWZ0Q31mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 293 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ4P/1aVIP8ySZz+X2XR/+vs8f/y5t7/85Vd//OGRf/zh0b/84dG//OH 294 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 295 | Rv/zhUP/8rKM//Ly8v/b7PP/XNL7/0jO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 296 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78zEnO/A9JzvwAAAAAAAAAAABZnRAAWZ0QHlmdEOBZnRD/WZ0Q/1md 297 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1meD/9GcGL+KDLD/2Jo0P/s7fH/8eXe//OV 298 | XP/zhkX/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 299 | Rv/zh0b/84dG//OHRv/zh0b/84VD//Kyi//y8vL/3O3y/1zS+/9Izvz/Sc78/0nO/P9Jzvz/Sc78/0nO 300 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/MxJzvwPSc78AAAAAAAAAAAAWZ0QAFmd 301 | EBpZnRDbWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1meDv9Tjyz/M0Wt/ykx 302 | xv9ZYM7/6Onw//Lq5P/zmmX/84ZE//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 303 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OFRP/yupj/8/Pz/9Xr8/9X0fv/SM78/0nO 304 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9JzvzGSc78DUnO 305 | /AAAAAAAAAAAAFmdEABZnRATWZ0Q0FmdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 306 | EP9ZnRH/QmV4/y02yP8rNMX/R0/L/9vd7P/y8O7/8ql8//OFQ//zh0b/84dG//OHRv/zh0b/84dG//OH 307 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/ziEf/8suz//Tz 308 | 9P/E6PT/T8/8/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 309 | /P9Jzvz/Sc78uknO/AdJzvwAAAAAAAAAAABZnRAAWZ0QCVmdEL5ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1md 310 | EP9ZnRD/WZ0Q/1mdEP9ang7/UIc8/zJBu/8uN8n/LTbG/zU+x//Awub/9PX0//LCpv/zh0X/84dG//OH 311 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 312 | Rv/zhkX/85JX//Hg1f/z8/P/peH2/0jO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 313 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/KVJzvwCSc78AAAAAAAAAAAAWZ0QAFmdEAFZnRCiWZ0Q/1md 314 | EP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnQ//WJoX/z5cjv8vOMz/LznJ/y43x/8vOcv/lJrj//P0 315 | 8//x4Nb/85Na//OGRf/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 316 | Rv/zh0b/84dG//OHRv/zh0b/84VD//KuhP/x7+7/7PDy/3nY+f9Hzfz/Sc78/0nO/P9Jzvz/Sc78/0nO 317 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9JzvyHSc78AEnO/AAAAAAAAAAAAFmd 318 | EABZnRAAWZ0QfFmdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/Wp4N/01+T/8yP8b/MDrL/y85 319 | yf8xPMz/OEXY/19q4P/h4u//8vLx//K6mP/zhkX/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 320 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84ZF//OPU//x2Mn/8/Pz/8rp9P9U0Pv/SM78/0nO 321 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz+Sc78YEnO 322 | /ABJzvwAAAAAAAAAAABZnRAAWZ0QAFmdEE9ZnRD6WZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRD/WZ4P/1aW 323 | H/88VKP/MTvP/zE7y/8yPc7/OkfY/z1K3P8/S9z/pKro//P08v/x5+D/8qFv//OFRP/zh0b/84dG//OH 324 | Rv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dF//OIR//yvZ3/8fHw/+7w 325 | 8f+H2/j/R878/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 326 | /P9Jzvz/Sc788EnO/DdJzvwASc78AAAAAAAAAAAAAAAAAFmdEABZnRAkWZ0Q4lmdEP9ZnRD/WZ0Q/1md 327 | EP9ZnRD/WZ0Q/1meDv9JdGX/Mz/O/zI9zv80P8//O0fZ/z1K3P89Stz/O0jc/1Zi3//S1e3/8/Tz//Hc 328 | 0P/zmmX/84VE//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OHRv/zh0b/84ZF//OH 329 | Rv/ysYr/8ezp//Py8v+65vX/UdD8/0jO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 330 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/NBJzvwUSc78AAAAAAAAAAAAAAAAAAAAAABZnRAAWZ0QB1md 331 | ELNZnRD/WZ0Q/1mdEP9ZnRD/WZ0Q/1meDv9UkCz/Ok61/zM+0f81QNH/O0fZ/z1K3P89Stz/PUrc/z1K 332 | 3P87SNz/c3zi/+Pk7//z9PP/8d3R//Kjc//zh0b/84ZE//OHRv/zh0b/84dG//OHRv/zh0b/84dG//OH 333 | Rv/zh0b/84VD//OMTv/yuJb/8evn//Tz8v/N5vH/W8r2/0TK+v9Izfz/Sc78/0nO/P9Jzvz/Sc78/0nO 334 | /P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9JzvyZSc78AEnO/AAAAAAAAAAAAAAA 335 | AAAAAAAAWZ0QAFmdEABZnRBtWZ0Q/1mdEP9ZnRD/WZ0Q/1mdEP9ZnRH/Rmt8/zVA0/82QdL/O0jZ/z1K 336 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P9/h+T/4+Tv//P08//x6OP/8r+g//OXYP/ziEf/84VD//OF 337 | Q//zhkT/84ZE//OFQ//zhkT/84tN//Kjc//y0b3/8e/u//Ty8v/P5vD/WsHv/y+07/80uPH/Or70/0DE 338 | 9/9Fyvr/SM38/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO/P9Jzvz6Sc78U0nO 339 | /ABJzvwAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QKVmdEORZnRD/WZ0Q/1mdEP9Zng3/Uok8/zpK 340 | xP83QtX/O0ja/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/3N84v/S1e3/8/Py//Lz 341 | 8v/x5N3/8sqy//Kxiv/yonL/851p//Oea//yp3n/8rmX//HUw//x6+j/8/Pz//Dx8f+73/D/Ur7u/y6z 342 | 7v8xtO//MrXv/zO28P80uPH/N7vy/zu/9P9Bxff/Rcr6/0jN+/9Jzvz/Sc78/0nO/P9Jzvz/Sc78/0nO 343 | /P9Jzvz/Sc7800nO/BhJzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAWZ0QAFmdEANZnRCeWZ0Q/1md 344 | EP9ZnQ//WJoW/0Nik/84Q9j/PEja/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 345 | 3P87SNz/VmLf/6Sq6P/h4u//8/Py//T19P/y8vH/8u7r//Hr5//x7Oj/8u/t//Pz8//09PT/8fHy/9Tn 346 | 8P+Hzu//Pbbu/y2y7v8wtO7/MbXv/zK27/8zt/D/NLjx/za58f83u/L/OLzz/zu/9P8+w/b/Q8f5/0bL 347 | +v9Izfz/Sc78/0nO/P9Jzvz/Sc78/0nO/INJzvwASc78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmd 348 | EABZnRAAWZ0QQVmdEPFZnRD/WZ4N/0+BUP87SdD/PEjb/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 349 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/ztI3P8/S9z/X2rg/5ad5v/Ex+z/3d/v/+np8P/s7fH/7O3x/+br 350 | 8P/X5vD/ttvv/3/J7v9Gtu3/La7t/y6v7f8wsO7/MLHu/zGy7/8ys+//M7Tw/zW28P82t/H/N7jy/zm6 351 | 8v86u/P/PL30/z2/9f9Awfb/QsT4/0XI+f9Hyvv/SMv7/0nL++RJzvwsSc78AEnO/AAAAAAAAAAAAAAA 352 | AAAAAAAAAAAAAAAAAABZnRAAWZ0QAFmdEAZZnRCmWZ0P/1eXHv9CXKn/PEjd/z1K3P89Stz/PUrc/z1K 353 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/ztI3P87SNz/RVHd/1Zh 354 | 3/9nceH/b3ji/2554v9ideH/Tm7h/z1p4f82ZuH/N2fh/zlo4f85aOH/OWjh/zlo4f86aOH/Omni/zpp 355 | 4v87aeL/O2ri/ztq4v88a+P/PGvj/z1s4/89bOP/Pm3k/z5t5P8/buT/P2/l/0Bw5f9BfeiNUv//AUW9 356 | 9wBJzvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmdEABZnRAAWZ0QOlmeDupNemb/PUra/z1K 357 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 358 | 3P89Stz/PUrc/zxK3P87Sdz/O0jc/zpH3P86R9z/O0jc/zxI3P89SNz/PUjc/z1I3P89SNz/PUjc/z1I 359 | 3P89SNz/PUjc/z1I3P89SNz/PUjc/z1I3P89SNz/PUjc/z1I3P89SNz/PUjc/z1I3P89SNz/PUjc/z1I 360 | 3P89SNvcPD/ZJz5V3wBHzfsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZnRAAWZ0QAIv/ 361 | AAFTij+HQVe7/z1J3v89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 362 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 363 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 364 | 3P89Stz/PUrc/z1K3P89Stz8PUrcbT1K3AA9StwAPUrcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 365 | AAAAAAAAAAAAAFmdEABCWbcAPk7SGj1K3MU9Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 366 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 367 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 368 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrcsD1K3A49StwAPUrcAAAAAAAAAAAAAAAAAAAA 369 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZnRAAQFTEAD9P0AA9StxAPUrc5z1K3P89Stz/PUrc/z1K 370 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 371 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 372 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc2T1K3C09StwAPUrcAAAA 373 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1K3AA9StwAPUrcAD1K 374 | 3GY9Stz2PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 375 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 376 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc7T1K 377 | 3FA9StwAPUrcAD1K3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 378 | AAAAAAAAPUrcAD1K3AA9StwEPUrcfz1K3Po9Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 379 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 380 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 381 | 3P89Stz/PUrc9D1K3Gg9StwAPUrcAD1K3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 382 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9StwAPUrcAD1K3Ag9StyHPUrc+j1K3P89Stz/PUrc/z1K 383 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 384 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 385 | 3P89Stz/PUrc/z1K3P89Stz/PUrc9D1K3HI9StwDPUrcAD1K3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 386 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUrcAD1K3AA9StwAPUrcCD1K 387 | 3H89Stz2PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 388 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 389 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc7j1K3Go9StwDPUrcAD1K3AAAAAAAAAAAAAAA 390 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 391 | AAA9StwAPUrcAD1K3AA9StwEPUrcZj1K3Oc9Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 392 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 393 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc3D1K3FM9StwBPUrcAD1K 394 | 3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 395 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1K3AA9StwAPUrcAD1K3AA9StxAPUrcxT1K3P89Stz/PUrc/z1K 396 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 397 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz+PUrctj1K 398 | 3DI9StwAPUrcAD1K3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 399 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1K3AA9StwAPUrcAD1K 400 | 3Bk9StyHPUrc6j1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 401 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 402 | 3P89StziPUrcdz1K3BE9StwAPUrcAD1K3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 403 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 404 | AAAAAAAAPUrcAD1K3AA9StwAPUrcAT1K3Do9StymPUrc8T1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 405 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 406 | 3P89Stz/PUrc/z1K3Os9StyZPUrcLz1K3AA9StwAPUrcAD1K3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 407 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 408 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9StwAPUrcAD1K3AA9StwAPUrcBj1K3EE9StyePUrc5D1K 409 | 3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 410 | 3P89Stz/PUrc/z1K3P89Stz+PUrc3T1K3JI9Stw3PUrcAz1K3AA9StwAPUrcAAAAAAAAAAAAAAAAAAAA 411 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 412 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9StwAPUrcAD1K 413 | 3AA9StwAPUrcAz1K3Ck9StxtPUrcsz1K3OI9Stz6PUrc/z1K3P89Stz/PUrc/z1K3P89Stz/PUrc/z1K 414 | 3P89Stz/PUrc/z1K3P89Stz/PUrc+D1K3N49StyrPUrcZD1K3CI9StwBPUrcAD1K3AA9StwAPUrcAAAA 415 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 416 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 417 | AAAAAAAAAAAAAAAAAAA9StwAPUrcAD1K3AA9StwAPUrcAD1K3Ac9StwkPUrcTz1K3Hw9StyiPUrcvj1K 418 | 3NA9StzbPUrc4D1K3N89StzaPUrczj1K3Ls9StyePUrcdj1K3Ek9StwfPUrcBT1K3AA9StwAPUrcAD1K 419 | 3AA9StwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 420 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 421 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPUrcAD1K3AA9StwAPUrcAD1K 422 | 3AA9StwAPUrcAT1K3Ak9StwTPUrcGj1K3B49StwePUrcGT1K3BE9StwIPUrcAD1K3AA9StwAPUrcAD1K 423 | 3AA9StwAPUrcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 424 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 425 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 426 | AAAAAAAAAAAAAAAAAAA9StwAPUrcAD1K3AA9StwAPUrcAD1K3AA9StwAPUrcAD1K3AA9StwAPUrcAD1K 427 | 3AA9StwAPUrcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 428 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 429 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 430 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 431 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 432 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 433 | AAAAAAAA//////////////+AAf//////+AAAH//////AAAAH/////wAAAAD////+AAAAAH////gAAAAA 434 | H///8AAAAAAP///gAAAAAAf//8AAAAAAA///gAAAAAAB//8AAAAAAAD//gAAAAAAAH/8AAAAAAAAP/wA 435 | AAAAAAA/+AAAAAAAAB/wAAAAAAAAD/AAAAAAAAAP4AAAAAAAAA/gAAAAAAAAB+AAAAAAAAAHwAAAAAAA 436 | AAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAOAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAGAAAAAAAAAAYAA 437 | AAAAAAABgAAAAAAAAAGAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAGAAAAAAAAAAYAAAAAAAAABgAAAAAAA 438 | AAGAAAAAAAAAAYAAAAAAAAABwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPgAAAAAAAAB+AA 439 | AAAAAAAH4AAAAAAAAAfwAAAAAAAAD/AAAAAAAAAP+AAAAAAAAB/4AAAAAAAAP/wAAAAAAAA//gAAAAAA 440 | AH//AAAAAAAA//8AAAAAAAH//4AAAAAAA///wAAAAAAH///wAAAAAA////gAAAAAH////AAAAAB///// 441 | AAAAAP/////AAAAD//////gAAB///////4AB//////////////8= 442 | 443 | 444 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/INI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ChromeAutoUpdate 7 | { 8 | public class INI 9 | { 10 | // 声明INI文件的写操作函数 WritePrivateProfileString() 11 | 12 | [System.Runtime.InteropServices.DllImport("kernel32")] 13 | 14 | private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); 15 | 16 | // 声明INI文件的读操作函数 GetPrivateProfileString() 17 | 18 | [System.Runtime.InteropServices.DllImport("kernel32")] 19 | 20 | private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath); 21 | 22 | 23 | private string sPath = null; 24 | 25 | public INI(string path) 26 | { 27 | this.sPath = path; 28 | } 29 | 30 | public void Writue(string section, string key, string value) 31 | { 32 | 33 | // section=配置节,key=键名,value=键值,path=路径 34 | 35 | WritePrivateProfileString(section, key, value, sPath); 36 | 37 | } 38 | public string ReadValue(string section, string key) 39 | { 40 | 41 | // 每次从ini中读取多少字节 42 | 43 | System.Text.StringBuilder temp = new System.Text.StringBuilder(255); 44 | 45 | // section=配置节,key=键名,temp=上面,path=路径 46 | 47 | GetPrivateProfileString(section, key, "", temp, 255, sPath); 48 | 49 | return temp.ToString(); 50 | 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace ChromeAutoUpdate 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// 应用程序的主入口点。 12 | /// 13 | [STAThread] 14 | static void Main(string[] args) 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new FrmMain(args)); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // 有关程序集的一般信息由以下 7 | // 控制。更改这些特性值可修改 8 | // 与程序集关联的信息。 9 | [assembly: AssemblyTitle("chrome自动更新")] 10 | [assembly: AssemblyDescription("chrome自动更新")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("chrome自动更新")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | //将 ComVisible 设置为 false 将使此程序集中的类型 19 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 20 | //请将此类型的 ComVisible 特性设置为 true。 21 | [assembly: ComVisible(false)] 22 | 23 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 24 | [assembly: Guid("2c85c4f1-22b3-4195-9bf2-9acf112d6d88")] 25 | 26 | // 程序集的版本信息由下列四个值组成: 27 | // 28 | // 主版本 29 | // 次版本 30 | // 生成号 31 | // 修订号 32 | // 33 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 34 | // 方法是按如下所示使用“*”: : 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.2017.11.06")] 37 | [assembly: AssemblyFileVersion("1.2017.11.06")] 38 | [assembly: NeutralResourcesLanguage("zh-CN")] 39 | 40 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ChromeAutoUpdate.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("ChromeAutoUpdate.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.Byte[] 类型的本地化资源。 65 | /// 66 | internal static byte[] Interop_NATUPNPLib { 67 | get { 68 | object obj = ResourceManager.GetObject("Interop_NATUPNPLib", resourceCulture); 69 | return ((byte[])(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\Interop.NATUPNPLib.dll;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 123 | 124 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ChromeAutoUpdate.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/Resources/Interop.NATUPNPLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenjia404/ChromeAutoUpdate/65e7b91455b1b447ecb15f04b5278ccc397c2c87/ChromeAutoUpdate/Resources/Interop.NATUPNPLib.dll -------------------------------------------------------------------------------- /ChromeAutoUpdate/UdpListener.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using NATUPNPLib; 3 | using SimpleJson; 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Net; 10 | using System.Net.NetworkInformation; 11 | using System.Net.Sockets; 12 | using System.Text; 13 | using System.Threading; 14 | 15 | namespace ChromeAutoUpdate 16 | { 17 | public class UdpListener 18 | { 19 | /// 20 | /// 用于UDP接收的网络服务类 21 | /// 22 | private UdpClient udpcRecv; 23 | 24 | private rsa UserRsa = new rsa(); 25 | 26 | 27 | /// 28 | /// 消息格式版本 29 | /// 30 | private int version = 1; 31 | 32 | 33 | private int udp_port = 20172; 34 | 35 | private string id = ""; 36 | 37 | /// 38 | /// 本地ip 39 | /// 40 | private IPAddress local_ip; 41 | 42 | 43 | private SortedDictionary node_list; 44 | 45 | private Hashtable node_table = new Hashtable(); 46 | 47 | 48 | 49 | public UdpListener() 50 | { 51 | local_ip = get_local_ip(); 52 | 53 | //不存在就创建 54 | if (!File.Exists("Private.xml") || !File.Exists("Public.xml")) 55 | { 56 | UserRsa.RSAKey("Private.xml", "Public.xml"); 57 | this.id = UserRsa.sha1(UserRsa.readFile("Public.xml")); 58 | } 59 | else 60 | { 61 | this.id = UserRsa.sha1(UserRsa.readFile("Public.xml")); 62 | } 63 | 64 | if(!Directory.Exists("node")) 65 | { 66 | Directory.CreateDirectory("node"); 67 | } 68 | 69 | } 70 | 71 | public void StartListener() 72 | { 73 | while (PortInUse(this.udp_port)) 74 | this.udp_port++; 75 | IPEndPoint localIpep = new IPEndPoint(IPAddress.Any, this.udp_port); // 本机IP和监听端口号 76 | log("监听端口:" + localIpep.ToString()); 77 | udpcRecv = new UdpClient(localIpep); 78 | 79 | thrRecv = new Thread(ReceiveMessage); 80 | thrRecv.Start(); 81 | 82 | log("UDP监听器已成功启动"); 83 | 84 | node_list = new SortedDictionary(); 85 | 86 | IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Broadcast, this.udp_port); // 发送到的IP地址和端口号 87 | 88 | 89 | if (File.Exists("node/node.json")) 90 | { 91 | log("读取node/node.json"); 92 | loadNode(); 93 | } 94 | 95 | 96 | //UPnP绑定端口 97 | log("UPnP绑定端口"); 98 | upnp(); 99 | 100 | 101 | while (true) 102 | { 103 | if (node_table.Count <= 5) 104 | { 105 | for(int i= 20172;i<20182;i++) 106 | this.ping(new IPEndPoint(IPAddress.Broadcast, i)); 107 | log("广播局域网"); 108 | } 109 | else 110 | { 111 | log("已有用户"+ node_table.Count.ToString()); 112 | } 113 | 114 | Hashtable node_table_tmp = (Hashtable) node_table.Clone(); 115 | 116 | foreach (node n in node_table_tmp.Values) 117 | { 118 | log("循环ping:"+ n.ip.ToString()); 119 | if(node_table.Count > 100) 120 | { 121 | this.ping(n.ip); 122 | Thread.Sleep(1000); 123 | } 124 | else 125 | { 126 | this.find_node(n.ip, "888888888888888888888888888888888888"); 127 | } 128 | } 129 | 130 | Thread.Sleep(5000); 131 | 132 | foreach (node n in node_table_tmp.Values) 133 | { 134 | if( node.unixtime() - n.last_time > 60) 135 | { 136 | node_table.Remove(n.uid); 137 | log("用户下线:" + n.ip.ToString()); 138 | } 139 | } 140 | 141 | 142 | node_table_tmp = (Hashtable)node_table.Clone(); 143 | JsonArray list_share_node = new JsonArray(); 144 | 145 | foreach (node ns in node_table_tmp.Values) 146 | { 147 | JsonObject jsonObject = new JsonObject(); 148 | jsonObject["uid"] = ns.uid; 149 | jsonObject["ip"] = ns.ip.Address.ToString(); 150 | jsonObject["port"] = ns.ip.Port.ToString(); 151 | list_share_node.Add(jsonObject); 152 | } 153 | 154 | if(node_table_tmp.Values.Count > 0) 155 | { 156 | string json = SimpleJson.SimpleJson.SerializeObject(list_share_node); 157 | writeFile("node/node.json", json); 158 | log("保存node.json"); 159 | } 160 | else 161 | { 162 | log("没有节点"); 163 | } 164 | } 165 | 166 | } 167 | 168 | public void writeFile(string path, string txt) 169 | { 170 | try 171 | { 172 | FileStream file = new FileStream(path, FileMode.Create); 173 | StreamWriter sw = new StreamWriter(file); 174 | sw.WriteLine(txt); 175 | sw.Close(); 176 | file.Close(); 177 | } 178 | catch 179 | { 180 | throw; 181 | } 182 | } 183 | 184 | /// 185 | /// 读取文件 186 | /// 187 | /// 188 | /// 189 | public string readFile(string filename) 190 | { 191 | StreamReader reader = new StreamReader(filename); 192 | string str = reader.ReadToEnd(); 193 | reader.Close(); 194 | return str.Trim(); 195 | } 196 | 197 | 198 | /// 199 | /// 加载节点 200 | /// 201 | public void loadNode() 202 | { 203 | string node_json = readFile("node/node.json"); 204 | try 205 | { 206 | var nodes = SimpleJson.SimpleJson.DeserializeObject(node_json.Trim()); 207 | JsonArray file_nodes = (JsonArray)nodes; 208 | 209 | foreach (JsonObject n in file_nodes) 210 | { 211 | //添加节点 212 | if (!node_table.ContainsKey(n["uid"].ToString())) 213 | { 214 | node_table.Add(n["uid"].ToString(), 215 | new node(n["uid"].ToString(), 216 | new IPEndPoint(IPAddress.Parse(n["ip"].ToString()), 217 | int.Parse(n["port"].ToString()) 218 | ))); 219 | log("find新节点 " + n["uid"].ToString() + ":" + n["ip"].ToString()); 220 | } 221 | else 222 | { 223 | log("find重复节点"); 224 | } 225 | } 226 | } 227 | catch(Exception ex) 228 | { 229 | log("node/node.json 解析异常"); 230 | return; 231 | } 232 | } 233 | 234 | 235 | /// 236 | /// 线程:不断监听UDP报文 237 | /// 238 | Thread thrRecv; 239 | 240 | /// 241 | /// 接收数据 242 | /// 243 | private void ReceiveMessage() 244 | { 245 | IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0); 246 | while (true) 247 | { 248 | try 249 | { 250 | byte[] bytRecv = udpcRecv.Receive(ref remoteIpep); 251 | 252 | if(remoteIpep.Address.ToString() == local_ip.ToString()) 253 | { 254 | continue; 255 | } 256 | 257 | string message = Encoding.Unicode.GetString(bytRecv, 0, bytRecv.Length); 258 | 259 | log(string.Format("{0}:{1}[{2}]",remoteIpep.Address,remoteIpep.Port, message)); 260 | 261 | //处理消息 262 | var json = (IDictionary)SimpleJson.SimpleJson.DeserializeObject(message); 263 | string type = ""; 264 | string uid = ""; 265 | if (json.ContainsKey("type")) 266 | type = (string)json["type"]; 267 | 268 | 269 | if (json.ContainsKey("uid")) 270 | uid = (string)json["uid"]; 271 | 272 | if (json.ContainsKey("type")) 273 | { 274 | switch (type) 275 | { 276 | case "ping": 277 | log("收到ping"); 278 | this.pong(remoteIpep); 279 | if(json.ContainsKey("uid") && !File.Exists(@"node\"+ (string)json["uid"])) 280 | { 281 | this.who(remoteIpep); 282 | } 283 | else 284 | { 285 | log("已知用户"); 286 | } 287 | break; 288 | case "pong": 289 | log("收到pong"); 290 | 291 | if (node_table.ContainsKey(uid)) 292 | { 293 | log("重复"); 294 | node_table[uid] = new node(uid, remoteIpep); 295 | } 296 | else 297 | { 298 | log("不重复" + node_list.Count); 299 | node_table.Add(uid, new node(uid, remoteIpep)); 300 | } 301 | 302 | 303 | break; 304 | case "who": 305 | log("收到who"); 306 | this.me(remoteIpep); 307 | break; 308 | case "me": 309 | log("收到who"); 310 | if(json.ContainsKey("msg")) 311 | { 312 | //todo 证书有效性验证 313 | this.UserRsa.writeFile(@"node\" + this.UserRsa.sha1(json["msg"].ToString().Trim()), (string)json["msg"]); 314 | } 315 | break; 316 | case "find_node": 317 | if(json.ContainsKey("msg")) 318 | { 319 | this.reply_node(remoteIpep, json["msg"].ToString()); 320 | } 321 | break; 322 | case "reply_node": 323 | if (json.ContainsKey("msg")) 324 | { 325 | try 326 | { 327 | JsonArray nodes = (JsonArray)json["msg"]; 328 | foreach(JsonObject n in nodes) 329 | { 330 | //添加节点 331 | if(!node_table.ContainsKey(n["uid"].ToString())) 332 | { 333 | node_table.Add(n["uid"].ToString(), 334 | new node(n["uid"].ToString(), 335 | new IPEndPoint(IPAddress.Parse(n["ip"].ToString()), 336 | (int)n["port"] 337 | ))); 338 | log("find新节点 "+ n["uid"].ToString() + ":" + n["ip"].ToString()); 339 | } 340 | else 341 | { 342 | log("find重复节点"); 343 | } 344 | } 345 | } 346 | catch 347 | { 348 | continue; 349 | } 350 | } 351 | break; 352 | case "cmd": 353 | if (json.ContainsKey("msg")) 354 | { 355 | switch (json["msg"].ToString()) 356 | { 357 | case "update": 358 | update updater = new update(); 359 | updater.checkUpdate(); 360 | break; 361 | default: 362 | break; 363 | } 364 | } 365 | break; 366 | default: 367 | log("收到未知消息"); 368 | break; 369 | } 370 | } 371 | 372 | } 373 | catch (Exception ex) 374 | { 375 | log( ex.Message); 376 | } 377 | } 378 | } 379 | 380 | 381 | public static bool log(string msg) 382 | { 383 | if (!File.Exists("debug")) 384 | return false; 385 | string filename = DateTime.Now.ToString("yyyy-MM-dd") + ".udplog.log"; 386 | try 387 | { 388 | using (StreamWriter sw = new StreamWriter(@filename, true))//覆盖模式写入 389 | { 390 | sw.WriteLine(DateTime.Now.ToLongTimeString() + " udp:" + msg); 391 | sw.Close(); 392 | } 393 | } 394 | catch 395 | { 396 | return false; 397 | } 398 | return true; 399 | } 400 | 401 | 402 | public void ping(IPEndPoint remoteIpep) 403 | { 404 | 405 | var obj = new Dictionary(); 406 | obj["type"] = "ping"; 407 | obj["msg"] = ""; 408 | obj["version"] = this.version; 409 | obj["uid"] = this.id; 410 | 411 | string json = SimpleJson.SimpleJson.SerializeObject(obj); 412 | 413 | byte[] sendbytes = Encoding.Unicode.GetBytes(json); 414 | 415 | udpcRecv.Send(sendbytes, sendbytes.Length, remoteIpep); 416 | } 417 | 418 | 419 | /// 420 | /// 回应ping 421 | /// 422 | /// 423 | public void pong(IPEndPoint remoteIpep) 424 | { 425 | 426 | var obj = new Dictionary(); 427 | obj["type"] = "pong"; 428 | obj["msg"] = ""; 429 | obj["version"] = this.version; 430 | obj["uid"] = this.id; 431 | 432 | string json = SimpleJson.SimpleJson.SerializeObject(obj); 433 | 434 | byte[] sendbytes = Encoding.Unicode.GetBytes(json); 435 | 436 | log("发送pong:"+ remoteIpep.ToString()); 437 | udpcRecv.Send(sendbytes, sendbytes.Length, remoteIpep); 438 | } 439 | 440 | 441 | /// 442 | /// 询问身份(交换证书,后面可以加入昵称、地区、简介这些 443 | /// 444 | /// 445 | public void who(IPEndPoint remoteIpep) 446 | { 447 | var obj = new Dictionary(); 448 | obj["type"] = "who"; 449 | obj["msg"] = ""; 450 | obj["version"] = this.version; 451 | obj["uid"] = this.id; 452 | 453 | string json = SimpleJson.SimpleJson.SerializeObject(obj); 454 | 455 | byte[] sendbytes = Encoding.Unicode.GetBytes(json); 456 | 457 | udpcRecv.Send(sendbytes, sendbytes.Length, remoteIpep); 458 | } 459 | 460 | 461 | /// 462 | /// 463 | /// 464 | /// 465 | public void me(IPEndPoint remoteIpep) 466 | { 467 | var obj = new Dictionary(); 468 | obj["type"] = "me"; 469 | obj["msg"] = this.UserRsa.readFile("Public.xml"); 470 | obj["version"] = this.version; 471 | obj["uid"] = this.id; 472 | 473 | string json = SimpleJson.SimpleJson.SerializeObject(obj); 474 | 475 | byte[] sendbytes = Encoding.Unicode.GetBytes(json); 476 | 477 | udpcRecv.Send(sendbytes, sendbytes.Length, remoteIpep); 478 | } 479 | 480 | 481 | 482 | /// 483 | /// 查找节点 484 | /// 485 | /// 486 | /// 487 | public void reply_node(IPEndPoint remoteIpep, string uid) 488 | { 489 | var obj = new Dictionary(); 490 | obj["type"] = "reply_node"; 491 | obj["version"] = this.version; 492 | obj["uid"] = this.id; 493 | 494 | Hashtable share_node = new Hashtable(); 495 | 496 | Hashtable node_table_tmp = (Hashtable)node_table.Clone(); 497 | 498 | foreach (node n in node_table_tmp.Values) 499 | { 500 | if (share_node.Values.Count < 10) 501 | { 502 | share_node.Add(n.uid, n); 503 | } 504 | else 505 | { 506 | foreach (node ns in share_node.Values) 507 | { 508 | if (distance(ns.uid, uid) < distance(n.uid, uid)) 509 | { 510 | share_node.Remove(n.uid); 511 | share_node.Add(n.uid, n); 512 | } 513 | } 514 | } 515 | } 516 | 517 | JsonArray list_share_node = new JsonArray(); 518 | 519 | foreach (node ns in share_node.Values) 520 | { 521 | JsonObject jsonObject = new JsonObject(); 522 | jsonObject["uid"] = ns.uid; 523 | jsonObject["ip"] = ns.ip.Address.ToString(); 524 | jsonObject["port"] = ns.ip.Port.ToString(); 525 | list_share_node.Add(jsonObject); 526 | } 527 | 528 | obj["msg"] = list_share_node; 529 | 530 | string json = SimpleJson.SimpleJson.SerializeObject(obj); 531 | 532 | byte[] sendbytes = Encoding.Unicode.GetBytes(json); 533 | log("发送reply_node"); 534 | udpcRecv.Send(sendbytes, sendbytes.Length, remoteIpep); 535 | } 536 | 537 | 538 | /// 539 | /// 查找节点 540 | /// 541 | /// 542 | /// 543 | public void find_node(IPEndPoint remoteIpep, string uid) 544 | { 545 | var obj = new Dictionary(); 546 | obj["type"] = "find_node"; 547 | obj["msg"] = uid; 548 | obj["version"] = this.version; 549 | obj["uid"] = this.id; 550 | 551 | string json = SimpleJson.SimpleJson.SerializeObject(obj); 552 | 553 | byte[] sendbytes = Encoding.Unicode.GetBytes(json); 554 | 555 | log("发送find_node"); 556 | udpcRecv.Send(sendbytes, sendbytes.Length, remoteIpep); 557 | } 558 | 559 | 560 | /// 561 | /// 用户距离 562 | /// 563 | /// 564 | public int distance(string a,string b) 565 | { 566 | int distance = 0; 567 | 568 | for (int i = 0; i < a.Length && i < b.Length;i++) 569 | { 570 | if(a.Substring(i) != b.Substring(i)) 571 | { 572 | distance++; 573 | } 574 | } 575 | 576 | return distance; 577 | } 578 | 579 | 580 | /// 581 | /// 获取本地ip 582 | /// 583 | /// 584 | public IPAddress get_local_ip() 585 | { 586 | NetworkInterface[] fNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 587 | foreach (NetworkInterface adapter in fNetworkInterfaces) 588 | { 589 | string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection"; 590 | RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false); 591 | if (rk != null) 592 | { 593 | // 区分 PnpInstanceID 594 | // 如果前面有 PCI 就是本机的真实网卡 595 | // MediaSubType 为 01 则是常见网卡,02为无线网卡。 596 | string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString(); 597 | int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0)); 598 | if (fPnpInstanceID.Length > 3 && fPnpInstanceID.Substring(0, 3) == "PCI") 599 | { 600 | IPInterfaceProperties fIPInterfaceProperties = adapter.GetIPProperties(); 601 | 602 | UnicastIPAddressInformationCollection UnicastIPAddressInformationCollection = fIPInterfaceProperties.UnicastAddresses; 603 | foreach (UnicastIPAddressInformation UnicastIPAddressInformation in UnicastIPAddressInformationCollection) 604 | { 605 | if(UnicastIPAddressInformation.Address.AddressFamily == AddressFamily.InterNetwork) 606 | return UnicastIPAddressInformation.Address; 607 | } 608 | 609 | } 610 | } 611 | } 612 | return null; 613 | } 614 | 615 | 616 | 617 | public void upnp() 618 | { 619 | INI config = new INI(System.Windows.Forms.Application.StartupPath + @"\config.ini"); 620 | 621 | //设置端口 622 | Random rd = new Random(); 623 | var eport = rd.Next(12000,13000); 624 | string ini_eport = config.ReadValue("dht", "eport"); 625 | 626 | //使用上次端口 627 | if(ini_eport.Length>3) 628 | int.TryParse(ini_eport,out eport); 629 | log("外部端口:" + eport.ToString()); 630 | 631 | IPAddress ipv4 = this.local_ip; 632 | 633 | //创建COM类型 634 | var upnpnat = new UPnPNAT(); 635 | var mappings = upnpnat.StaticPortMappingCollection; 636 | 637 | //错误判断 638 | if (mappings == null) 639 | { 640 | log("没有检测到路由器,或者路由器不支持UPnP功能。"); 641 | return; 642 | } 643 | else 644 | { 645 | log("ipv4:" + ipv4.ToString()); 646 | } 647 | 648 | //添加之前的ipv4变量(内网IP),内部端口,和外部端口 649 | mappings.Add(eport, "UDP", this.udp_port, ipv4.ToString(), true, "ChromeAutoUpdate"); 650 | log("UPnP " + ipv4.ToString() + ":" + eport.ToString()); 651 | config.Writue("dht", "eport", eport.ToString()); 652 | } 653 | 654 | 655 | public static bool PortInUse(int port) 656 | { 657 | bool inUse = false; 658 | 659 | IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); 660 | IPEndPoint[] ipEndPoints = ipProperties.GetActiveUdpListeners(); 661 | 662 | foreach (IPEndPoint endPoint in ipEndPoints) 663 | { 664 | if (endPoint.Port == port) 665 | { 666 | return true; 667 | } 668 | } 669 | 670 | 671 | ipEndPoints = ipProperties.GetActiveTcpListeners(); 672 | 673 | foreach (IPEndPoint endPoint in ipEndPoints) 674 | { 675 | if (endPoint.Port == port) 676 | { 677 | inUse = true; 678 | break; 679 | } 680 | } 681 | return inUse; 682 | } 683 | } 684 | } 685 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 59 | 60 | 61 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/node.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace ChromeAutoUpdate 5 | { 6 | public class node 7 | { 8 | public IPEndPoint ip; 9 | 10 | public string uid; 11 | 12 | public int last_time; 13 | 14 | public node(string uid, IPEndPoint ip) 15 | { 16 | this.uid = uid; 17 | this.ip = ip; 18 | this.last_time = unixtime(); 19 | } 20 | 21 | 22 | public static int unixtime() 23 | { 24 | System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); 25 | return (int)(DateTime.Now - startTime).TotalSeconds; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/node_key.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ChromeAutoUpdate 7 | { 8 | class node_key : IComparable 9 | { 10 | 11 | public int last_time { get; private set; } 12 | 13 | public node_key(int last_time) 14 | { 15 | this.last_time = last_time; 16 | } 17 | public int CompareTo(node_key other) 18 | { 19 | return -last_time.CompareTo(other.last_time); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/rsa.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Security.Cryptography; 7 | 8 | namespace ChromeAutoUpdate 9 | { 10 | public class rsa 11 | { 12 | 13 | private string dev_public = "vlGWGWZRjS0EWSId260zvcLc7hPx6yruN5zUZGAbdo7VAo6PfCX8e6VPBY8I9QXqD8mFYH92/mF/0SlIjOSTZYdSwW9a+wEb87UZTbpCQxiWfys+8jdPPg2CLB7Em4OMTKlnh5+3Qx3OlZ197eLtpZ/6cHfrvAtOLqAYJkHi1Sz2o7SV74R+4YHECjBHnbA94FYY7QSJbDxv/GwhS2DrRQ5PR4JQBil7ZC2hjGNq2yJAFfVr95kr4iizzoyiGFc2fobF52wEEIqZ5+OwHqzXtu3ipxxV3MIvuxekbNVhZCOHBMjyuoG8VZD/LOlOU699wX5IUyq2KEx5p6wBSXsnt0uUNvR19Z+Iriqm2o72QilGCae7EjGXZmocBgh1yXphRRICPnTg0lYTl9xaPjVzyY2iMYAm4jKZAtGu+l+b9cXk2rUeVTOXecUwdTG37XfF7mteUUlYmH/boBTJjEksdfBNAo4YjKQm6m1zlfM52/kLtlLE3ceGDNBkZKuPEFMsufOFMHM9ZISFMU7fFVMNzu5oPkzbJSaWYLpRrTIs6BvGkxkrSjMzhaPyef/GxlDLu0bPut2qKBdJ5PF9oeg/A0F3Emf4IkCO6K+tfvEi95/48w+xxmj5t8yUJySkr1VEsWis4TBgoKxEIA6gKEHIqXGVpXZB9PKnDWqmQydAuE0=AQAB"; 14 | 15 | 16 | /// 17 | /// 计算哈希值 18 | /// 19 | /// 要计算哈希值的 Stream 20 | /// 哈希值字节数组 21 | public string sha1_file( string fileName) 22 | { 23 | 24 | System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); 25 | byte[] hashBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(fs); 26 | fs.Close(); 27 | return BitConverter.ToString(hashBytes).Replace("-", ""); 28 | } 29 | 30 | /// 31 | /// 计算哈希值 32 | /// 33 | /// 要计算哈希值的字符串 34 | /// sha1 35 | public string sha1(string str) 36 | { 37 | byte[] StrRes = Encoding.Default.GetBytes(str); 38 | byte[] hashBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(StrRes); 39 | return BitConverter.ToString(hashBytes).Replace("-", ""); 40 | } 41 | 42 | /// 43 | /// 生成公私钥 44 | /// 45 | /// 46 | /// 47 | public void RSAKey(string PrivateKeyPath, string PublicKeyPath) 48 | { 49 | try 50 | { 51 | RSACryptoServiceProvider provider = new RSACryptoServiceProvider(4096); 52 | 53 | this.writeFile(PrivateKeyPath, provider.ToXmlString(true)); 54 | this.writeFile(PublicKeyPath, provider.ToXmlString(false)); 55 | 56 | } 57 | catch (Exception exception) 58 | { 59 | throw exception; 60 | } 61 | } 62 | 63 | 64 | /// 65 | /// RSA加密 66 | /// 67 | /// 公钥 68 | /// MD5加密后的数据 69 | /// RSA公钥加密后的数据 70 | public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString) 71 | { 72 | string str2; 73 | try 74 | { 75 | RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 76 | provider.FromXmlString(xmlPublicKey); 77 | byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString); 78 | str2 = Convert.ToBase64String(provider.Encrypt(bytes, false)); 79 | } 80 | catch (Exception exception) 81 | { 82 | throw exception; 83 | } 84 | return str2; 85 | } 86 | 87 | public void writeFile(string path, string txt) 88 | { 89 | try 90 | { 91 | FileStream file = new FileStream(path, FileMode.Create); 92 | StreamWriter sw = new StreamWriter(file); 93 | sw.WriteLine(txt); 94 | sw.Close(); 95 | file.Close(); 96 | } 97 | catch 98 | { 99 | throw; 100 | } 101 | } 102 | 103 | 104 | /// 105 | /// 读取文件 106 | /// 107 | /// 108 | /// 109 | public string readFile(string filename) 110 | { 111 | StreamReader reader = new StreamReader(filename); 112 | string str = reader.ReadToEnd(); 113 | reader.Close(); 114 | return str.Trim(); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /ChromeAutoUpdate/update.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.IO.Compression; 8 | using System.Net; 9 | using System.Security.Cryptography.X509Certificates; 10 | using System.Text.RegularExpressions; 11 | using System.Threading; 12 | using System.Windows.Forms; 13 | 14 | namespace ChromeAutoUpdate 15 | { 16 | public class update 17 | { 18 | public Queue run_log = new Queue(); 19 | 20 | //唯一用户id,用于统计用户数 21 | public string uid = ""; 22 | 23 | private INI config; 24 | 25 | public update() 26 | { 27 | this.run_log.Enqueue("升级模块初始化"); 28 | 29 | 30 | rsa UserRsa = new rsa(); 31 | //不存在就创建 32 | if (!File.Exists("Private.xml") || !File.Exists("Public.xml")) 33 | { 34 | UserRsa.RSAKey("Private.xml", "Public.xml"); 35 | this.uid = UserRsa.sha1(UserRsa.readFile("Public.xml")); 36 | } 37 | else 38 | { 39 | this.uid = UserRsa.sha1(UserRsa.readFile("Public.xml")); 40 | } 41 | 42 | if (File.Exists(Application.StartupPath + @"\config.ini")) 43 | { 44 | this.config = new INI(Application.StartupPath + @"\config.ini"); 45 | } 46 | } 47 | 48 | /// 49 | /// 抓取网页,支持gzip 50 | /// 51 | /// 52 | /// 53 | public string GetWebContent(string sUrl) 54 | { 55 | string strResult = ""; 56 | string charset = "UTF-8"; 57 | try 58 | { 59 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sUrl); 60 | request.UserAgent = this.user_agent(); 61 | //声明一个HttpWebRequest请求 62 | request.Timeout = 5000; 63 | //设置连接超时时间 64 | request.Headers.Set("Pragma", "no-cache"); 65 | request.Headers.Set("Accept-Encoding", "gzip"); 66 | HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 67 | if (response.CharacterSet != "") 68 | charset = response.CharacterSet; 69 | if (response.ToString() == "") 70 | return ""; 71 | 72 | if (response.ContentEncoding.ToLower().Contains("gzip") | (response.Headers["Content-Encoding"] != null && response.Headers["Content-Encoding"].Contains("gzip"))) 73 | { 74 | using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)) 75 | { 76 | using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding(charset))) 77 | { 78 | strResult = reader.ReadToEnd(); 79 | } 80 | } 81 | } 82 | else 83 | { 84 | Stream myStream = response.GetResponseStream(); 85 | using (StreamReader reader = new StreamReader(myStream, System.Text.Encoding.GetEncoding(charset))) 86 | { 87 | strResult = reader.ReadToEnd(); 88 | } 89 | } 90 | } 91 | catch 92 | { 93 | strResult = ""; 94 | } 95 | return strResult; 96 | } 97 | 98 | 99 | /// 100 | /// 生成接口请求user-agent 101 | /// 102 | /// 103 | public string user_agent() 104 | { 105 | Version local = new Version(Application.ProductVersion); 106 | string user_agent = "Updater/" + local.ToString() + " " + this.GetOSType() + " net4.5/" + this.GetNet45Version(); 107 | return user_agent; 108 | } 109 | 110 | 111 | /// 112 | /// 获取.net4.5的版本 113 | /// 114 | /// 115 | public string GetNet45Version() 116 | { 117 | try 118 | { 119 | RegistryKey net45 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", false); 120 | if (net45 == null) 121 | return ""; 122 | 123 | return net45.GetValue("Version").ToString(); 124 | } 125 | catch 126 | { 127 | return ""; 128 | } 129 | } 130 | 131 | 132 | /// 133 | /// 生成系统版本 134 | /// 135 | /// 136 | public string GetOSType() 137 | { 138 | //定义系统版本 139 | Version ver = System.Environment.OSVersion.Version; 140 | string OSType = "(Windows NT " + ver.Major + "." + ver.Minor + ")"; 141 | return OSType; 142 | } 143 | 144 | 145 | /// 146 | /// 获取chrome目录 147 | /// 148 | /// 149 | public string getAppPath() 150 | { 151 | string app_path = Application.StartupPath + @"\Chrome-bin\"; 152 | 153 | //如果有配置文件 154 | if (File.Exists(Application.StartupPath + @"\config.ini")) 155 | { 156 | string ini_path = config.ReadValue("app", "path"); 157 | if (ini_path.Length > 3) 158 | { 159 | string localappdata = System.Environment.GetEnvironmentVariable("localappdata"); 160 | 161 | //替换环境变量 162 | app_path = app_path.Replace("%localappdata%", localappdata); 163 | 164 | } 165 | } 166 | 167 | return app_path; 168 | } 169 | 170 | 171 | /// 172 | /// 获取chrome主程序路径 173 | /// 174 | /// 175 | public string getAppFilename() 176 | { 177 | string app_path = getAppPath(); 178 | 179 | string app_filename = "chrome.exe"; 180 | 181 | app_filename = app_path + app_filename; 182 | 183 | return app_filename; 184 | } 185 | 186 | 187 | /// 188 | /// 删除老版本 189 | /// 190 | public void deleteOld() 191 | { 192 | //获取chrome主程序位置 193 | string app_filename = getAppFilename(); 194 | string path = this.getAppPath(); 195 | 196 | 197 | //更新chrome.exe 198 | if (File.Exists(app_filename + ".new")) 199 | { 200 | try 201 | { 202 | File.Delete(app_filename); 203 | File.Move(app_filename + ".new", app_filename); 204 | 205 | //当前chrome版本 206 | Version AppFileVersion = new Version("0.0.0.1"); 207 | if (File.Exists(app_filename)) 208 | { 209 | AppFileVersion = new Version(FileVersionInfo.GetVersionInfo(app_filename).FileVersion); 210 | } 211 | 212 | //定义用于验证正整数的表达式 213 | // ^ 表示从字符串的首部开始验证 214 | // $ 表示从字符串的尾部开始验证 215 | Regex rx = new Regex(@"^(\d+\.\d+\.\d+\.\d+)$", RegexOptions.Compiled); 216 | //删除多余的目录 217 | DirectoryInfo dir = new DirectoryInfo(path); 218 | DirectoryInfo[] info = dir.GetDirectories(); 219 | foreach (DirectoryInfo d in info) 220 | { 221 | //判断是否是当前运行版本 222 | if (rx.IsMatch(d.ToString()) && d.ToString() != AppFileVersion.ToString()) 223 | { 224 | try 225 | { 226 | d.MoveTo(dir.ToString() + @"delete_" + d.ToString()); 227 | Directory.Delete(d.ToString(), true); 228 | } 229 | catch (Exception ee) 230 | { 231 | //如果正在运行,就不能删除 232 | log(ee); 233 | } 234 | } 235 | else if (d.ToString().IndexOf("delete_") > 0) 236 | { 237 | Directory.Delete(d.ToString(), true); 238 | } 239 | } 240 | } 241 | catch 242 | { 243 | 244 | } 245 | } 246 | 247 | } 248 | 249 | 250 | /// 251 | /// 下载文件 252 | /// 253 | /// url地址 254 | /// 本地文件,任意目录均可 255 | /// 256 | public bool DownloadFile(string url, string filename) 257 | { 258 | try 259 | { 260 | FileInfo fi = new FileInfo(filename); 261 | var di = fi.Directory; 262 | if (!di.Exists) 263 | di.Create(); 264 | 265 | HttpWebRequest Myrq = (HttpWebRequest)HttpWebRequest.Create(url); 266 | Myrq.UserAgent = this.user_agent(); 267 | Myrq.Timeout = 10 * 1000; 268 | HttpWebResponse myrp = (HttpWebResponse)Myrq.GetResponse(); 269 | long totalBytes = myrp.ContentLength; 270 | Stream st = myrp.GetResponseStream(); 271 | Stream so = new FileStream(filename, FileMode.Create); 272 | byte[] by = new byte[1024]; 273 | int osize = st.Read(by, 0, (int)by.Length); 274 | while (osize > 0) 275 | { 276 | so.Write(by, 0, osize); 277 | osize = st.Read(by, 0, (int)by.Length); 278 | } 279 | so.Close(); 280 | st.Close(); 281 | return true; 282 | } 283 | catch (Exception) 284 | { 285 | return false; 286 | } 287 | } 288 | 289 | public int prog_totalBytes = 0; 290 | public int prog_Value = 0; 291 | public string la_status = ""; 292 | 293 | 294 | /// 295 | /// 带进度的下载文件 296 | /// 297 | /// 下载文件地址 298 | /// 下载后的存放地址 299 | /// 300 | public bool DownloadFileProg(string URL, string filename) 301 | { 302 | float percent = 0; 303 | try 304 | { 305 | System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL); 306 | Myrq.Timeout = 20000; 307 | System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse(); 308 | long totalBytes = myrp.ContentLength; 309 | this.prog_totalBytes = (int)totalBytes; 310 | System.IO.Stream st = myrp.GetResponseStream(); 311 | System.IO.Stream so = new System.IO.FileStream(filename, System.IO.FileMode.Create); 312 | long totalDownloadedByte = 0; 313 | byte[] by = new byte[1024]; 314 | int osize = st.Read(by, 0, (int)by.Length); 315 | while (osize > 0) 316 | { 317 | totalDownloadedByte = osize + totalDownloadedByte; 318 | System.Windows.Forms.Application.DoEvents(); 319 | so.Write(by, 0, osize); 320 | this.prog_Value = (int)totalDownloadedByte; 321 | osize = st.Read(by, 0, (int)by.Length); 322 | 323 | percent = (float)totalDownloadedByte / (float)totalBytes * 100; 324 | this.la_status = "当前下载进度" + percent.ToString() + "%"; 325 | } 326 | so.Close(); 327 | st.Close(); 328 | return true; 329 | } 330 | catch (System.Exception ex) 331 | { 332 | AddItemToListBox("下载失败:" + URL); 333 | return false; 334 | } 335 | } 336 | 337 | public static bool log(Exception ex) 338 | { 339 | if (!File.Exists(Application.StartupPath + @"\debug")) 340 | return false; 341 | if (!Directory.Exists(Application.StartupPath + @"\log")) 342 | Directory.CreateDirectory(Application.StartupPath + @"\log"); 343 | string filename = Application.StartupPath + @"\log\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log"; 344 | using (StreamWriter sw = new StreamWriter(@filename, true))//覆盖模式写入 345 | { 346 | sw.WriteLine(DateTime.Now.ToLongTimeString() + " update:" + ex.Message + ex.StackTrace); 347 | sw.Close(); 348 | } 349 | return true; 350 | } 351 | 352 | public static bool log(string msg) 353 | { 354 | if (!File.Exists(Application.StartupPath + @"\debug")) 355 | return false; 356 | if (!Directory.Exists(Application.StartupPath + @"\log")) 357 | Directory.CreateDirectory(Application.StartupPath + @"\log"); 358 | string filename = Application.StartupPath + @"\log\" + DateTime.Now.ToString("yyyy-MM-dd") + ".msg.log"; 359 | using (StreamWriter sw = new StreamWriter(@filename, true))//覆盖模式写入 360 | { 361 | sw.WriteLine(DateTime.Now.ToLongTimeString() + " update:" + msg); 362 | sw.Close(); 363 | } 364 | return true; 365 | } 366 | 367 | 368 | public void AddItemToListBox(string msg) 369 | { 370 | this.run_log.Enqueue(msg); 371 | } 372 | 373 | 374 | public void checkUpdate() 375 | { 376 | string app_update_url = "http://weibo.wbdacdn.com/chrome/update/"; 377 | 378 | string update_url = "http://chrome.wbdacdn.com/update.php"; 379 | 380 | string index = ""; 381 | 382 | string chromeParams = ""; 383 | 384 | string user_agent = ""; 385 | 386 | string app_path = Application.StartupPath + @"\Chrome-bin\"; 387 | 388 | string app_filename = "chrome.exe"; 389 | 390 | string Channel = "Dev"; 391 | 392 | string bit = IntPtr.Size.ToString(); 393 | 394 | bool app_is_run = File.Exists(app_path + app_filename); 395 | 396 | //定义系统版本 397 | Version os_ver = System.Environment.OSVersion.Version; 398 | string OSType = os_ver.Major + "." + os_ver.Minor; 399 | 400 | 401 | #region 获取配置文件 402 | if (File.Exists(Application.StartupPath + @"\config.ini")) 403 | { 404 | INI config = new INI(Application.StartupPath + @"\config.ini"); 405 | 406 | 407 | string config_version = config.ReadValue("config", "version"); 408 | if (config_version.Length == 0) 409 | { 410 | config.Writue("config", "version", "1"); 411 | config.Writue("server", "Params", ""); 412 | config.Writue("app", "Params", ""); 413 | config.Writue("app", "user_agent", "\"Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/56.0.2902.0 Safari/537.36\""); 414 | user_agent = "Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/56.0.2902.0 Safari/537.36"; 415 | } 416 | else if (config_version == "1") 417 | { 418 | config.Writue("server", "update_url", update_url); 419 | config.Writue("server", "app_update_url", app_update_url); 420 | config.Writue("config", "version", "2"); 421 | } 422 | else if (config_version == "2") 423 | { 424 | config.Writue("config", "version", "3"); 425 | config.Writue("app", "user_agent", "\"Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/56.0.2902.0 Safari/537.36\""); 426 | user_agent = "Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/56.0.2902.0 Safari/537.36"; 427 | } 428 | else if (config_version == "3") 429 | { 430 | //增加渠道默认参数 431 | config.Writue("config", "version", "4"); 432 | config.Writue("app", "Channel", "Dev"); 433 | } 434 | 435 | else if (config_version == "4") 436 | { 437 | //增加渠道默认参数 438 | config.Writue("config", "version", "5"); 439 | config.Writue("app", "Channel", "Dev"); 440 | } 441 | else if (config_version == "5") 442 | { 443 | config.Writue("config", "version", "6"); 444 | config.Writue("server", "app_update_url", app_update_url); 445 | config.Writue("app", "user_agent", ""); 446 | config.Writue("app", "path", "");//默认为当前目录 447 | } 448 | 449 | string ini_app_update_url = config.ReadValue("server", "app_update_url"); 450 | if (ini_app_update_url.Length > 3) 451 | app_update_url = ini_app_update_url; 452 | 453 | 454 | 455 | string ini_update_url = config.ReadValue("server", "update_url"); 456 | if (ini_update_url.Length > 3) 457 | update_url = ini_update_url; 458 | 459 | string ini_chromeParams = config.ReadValue("app", "Params"); 460 | if (ini_chromeParams.Length > 3) 461 | chromeParams = ini_chromeParams; 462 | 463 | 464 | string ini_index = config.ReadValue("app", "index"); 465 | if (ini_index.Length > 3) 466 | index = ini_index; 467 | 468 | 469 | string ini_user_agent = config.ReadValue("app", "user_agent"); 470 | if (ini_user_agent.Length > 3) 471 | user_agent = ini_user_agent; 472 | 473 | 474 | string ini_path = config.ReadValue("app", "path"); 475 | if (ini_path.Length > 3) 476 | { 477 | app_path = ini_path; 478 | if (app_path.Substring(app_path.Length - 1) != @"\") 479 | { 480 | config.Writue("app", "path", app_path + @"\"); 481 | app_path = app_path + @"\"; 482 | } 483 | } 484 | 485 | 486 | string ini_Channel = config.ReadValue("app", "Channel"); 487 | if (ini_Channel.Length > 3) 488 | Channel = ini_Channel; 489 | 490 | string ini_bit = config.ReadValue("app", "bit"); 491 | if (ini_bit.Length > 3) 492 | bit = ini_bit; 493 | 494 | AddItemToListBox("读取配置文件成功"); 495 | } 496 | #endregion 497 | 498 | 499 | string localappdata = System.Environment.GetEnvironmentVariable("localappdata"); 500 | 501 | //替换环境变量 502 | app_path = app_path.Replace("%localappdata%", localappdata); 503 | log("安装目录:" + app_path); 504 | 505 | //判断chrome目录是否存在,不存在就创建 506 | FileInfo fi = new FileInfo(app_path); 507 | var di = fi.Directory; 508 | if (!di.Exists) 509 | di.Create(); 510 | 511 | app_filename = app_path + "chrome.exe"; 512 | 513 | user_agent += " ChromeAutoUpdate/" + Application.ProductVersion.ToString(); 514 | 515 | if (File.Exists("chrome.7z")) 516 | { 517 | File.Delete("chrome.7z"); 518 | } 519 | if (File.Exists("ChromeAutoUpdate.exe.old")) 520 | { 521 | File.Delete("ChromeAutoUpdate.exe.old"); 522 | } 523 | if (File.Exists("ChromeAutoUpdate.exe.new")) 524 | { 525 | File.Delete("ChromeAutoUpdate.exe.new"); 526 | } 527 | if (File.Exists(app_filename + ".old")) 528 | { 529 | File.Delete(app_filename + ".old"); 530 | } 531 | 532 | 533 | //删除老文件 534 | this.deleteOld(); 535 | 536 | //删除更新目录 537 | if (Directory.Exists("update")) 538 | { 539 | Directory.Delete("update", true); 540 | } 541 | 542 | 543 | //升级自身 544 | string updater = GetWebContent(update_url + "?v=" + Application.ProductVersion + "&uid=" + this.uid + "&os_type=" + OSType); 545 | if (updater.Length > 10) 546 | { 547 | AddItemToListBox("更新ChromeAutoUpdate"); 548 | try 549 | { 550 | //需要判断文件是否成功下载,因为有时候会失败 551 | if (DownloadFile(updater, "ChromeAutoUpdate.exe.new")) 552 | { 553 | File.Move("ChromeAutoUpdate.exe", "ChromeAutoUpdate.exe.old"); 554 | File.Move("ChromeAutoUpdate.exe.new", "ChromeAutoUpdate.exe"); 555 | } 556 | } 557 | catch (Exception ex) 558 | { 559 | log(ex.Message.ToString()); 560 | } 561 | } 562 | 563 | //升级app 564 | Version AppFileVersion = new Version("0.0.0.1"); 565 | 566 | //如果已经更新了,但是还没有替换文件 567 | if (File.Exists(app_filename + ".new")) 568 | { 569 | AppFileVersion = new Version(FileVersionInfo.GetVersionInfo(app_filename + ".new").FileVersion); 570 | } 571 | else if (File.Exists(app_filename)) 572 | { 573 | AppFileVersion = new Version(FileVersionInfo.GetVersionInfo(app_filename).FileVersion); 574 | } 575 | 576 | 577 | string api = GetWebContent(app_update_url + "?v=" + AppFileVersion.ToString() + "&bit=" + bit + "&Channel=" + Channel + "&format=json" + "&uid=" + this.uid + "&os_type=" + OSType); 578 | 579 | var apiJson = (IDictionary)SimpleJson.SimpleJson.DeserializeObject(api); 580 | 581 | Version serverVersion = new Version(apiJson["version"].ToString()); 582 | 583 | #region 升级chrome流程 584 | if (serverVersion > AppFileVersion) 585 | { 586 | //this.Visible = true; 587 | //this.TopLevel = true; 588 | //lb_status.Text = "升级chrome中"; 589 | AddItemToListBox("升级chrome(" + apiJson["version"].ToString()); 590 | 591 | string tmp_file = Path.GetTempFileName() + ".tmp"; 592 | 593 | ///多个下载地址重试 594 | string[] urls = apiJson["url"].ToString().Split('|'); 595 | foreach (string url in urls) 596 | { 597 | AddItemToListBox("下载:" + url); 598 | if (DownloadFileProg(url, tmp_file)) 599 | break; 600 | } 601 | 602 | 603 | //验证文件签名 604 | try 605 | { 606 | X509Certificate cert = X509Certificate.CreateFromSignedFile(tmp_file); 607 | if (cert.Subject.IndexOf("CN=Google Inc") < 0) 608 | { 609 | return; 610 | } 611 | } 612 | catch (Exception ex) 613 | { 614 | log(ex); 615 | return; 616 | } 617 | 618 | //实例化process对象 619 | Process p = new Process(); 620 | //要执行的程序名称,cmd 621 | p.StartInfo.FileName = "cmd.exe"; 622 | p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动 623 | p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息 624 | p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息 625 | p.StartInfo.RedirectStandardError = true;//重定向标准错误输出 626 | p.StartInfo.CreateNoWindow = true;//不显示程序窗口 627 | p.Start();//启动程序 628 | 629 | AddItemToListBox("7z解压chrome.7z"); 630 | string cmd = @"7zr.exe -y e " + tmp_file + System.Environment.NewLine; 631 | cmd += @"7zr.exe -y x chrome.7z -oupdate" + Environment.NewLine; 632 | cmd += "del " + tmp_file + Environment.NewLine + "exit" + Environment.NewLine; 633 | 634 | //向CMD窗口发送输入信息: 635 | p.StandardInput.WriteLine(cmd); 636 | string cmd_log = p.StandardOutput.ReadToEnd(); 637 | //记录cmd执行情况 638 | log(cmd_log); 639 | p.WaitForExit();//等待程序执行完退出进程 640 | 641 | /** 解压完成,移动文件 **/ 642 | Version chromeVersion = new Version(FileVersionInfo.GetVersionInfo(@"update\Chrome-bin\chrome.exe").FileVersion); 643 | 644 | //移动chrome.exe 645 | log(@"update\Chrome-bin\chrome.exe" + "到" + app_filename + @".new"); 646 | 647 | //如果存在新版本,就删除新版本 648 | if (File.Exists(app_filename + @".new")) 649 | { 650 | File.Delete(app_filename + @".new"); 651 | } 652 | 653 | //如果存在,就保存新版本,不然就直接移动 654 | if (File.Exists(app_filename)) 655 | File.Move(@"update\Chrome-bin\chrome.exe", app_filename + @".new"); 656 | else 657 | File.Move(@"update\Chrome-bin\chrome.exe", app_filename); 658 | 659 | try 660 | { 661 | string move_dir = "xcopy /s /e /h /y \"" + Application.StartupPath + @"\update\Chrome-bin\" + chromeVersion.ToString() + "\\*\" \"" + app_path + chromeVersion.ToString() + "\\\"" + Environment.NewLine + "exit" + Environment.NewLine; 662 | log(move_dir); 663 | 664 | //移动目录 665 | Process p2 = new Process(); 666 | //要执行的程序名称,cmd 667 | p2.StartInfo.FileName = "cmd.exe"; 668 | p2.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动 669 | p2.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息 670 | p2.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息 671 | p2.StartInfo.RedirectStandardError = true;//重定向标准错误输出 672 | p2.StartInfo.CreateNoWindow = true;//不显示程序窗口 673 | p2.Start();//启动程序 674 | p2.StandardInput.WriteLine(move_dir); 675 | 676 | //记录cmd执行情况 677 | cmd_log = p2.StandardOutput.ReadToEnd(); 678 | log(cmd_log); 679 | p2.WaitForExit();//等待程序执行完退出进程 680 | } 681 | catch (Exception ex) 682 | { 683 | log(ex); 684 | 685 | } 686 | 687 | //删除目录 688 | Directory.Delete(Application.StartupPath + @"\update", true); 689 | 690 | File.Delete("chrome.7z"); 691 | 692 | 693 | } 694 | else 695 | { 696 | AddItemToListBox("没有新版本chrome"); 697 | 698 | //升级chrome 699 | //有的时候正在使用chrome,所有这里需要更新 700 | if (File.Exists(app_filename + ".new")) 701 | { 702 | try 703 | { 704 | this.deleteOld(); 705 | } 706 | catch 707 | { 708 | 709 | } 710 | } 711 | } 712 | #endregion 713 | 714 | while (!File.Exists(app_filename)) 715 | { 716 | Thread.Sleep(1000); 717 | } 718 | 719 | if (!app_is_run && File.Exists(app_filename)) 720 | { 721 | if (user_agent.Length > 35) 722 | chromeParams += " --user-agent=\"" + user_agent + "\""; 723 | chromeParams += " " + index; 724 | //启动 725 | Process.Start(app_filename, chromeParams); 726 | } 727 | AddItemToListBox("结束本次更新"); 728 | } 729 | } 730 | } 731 | -------------------------------------------------------------------------------- /Chrome_64px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenjia404/ChromeAutoUpdate/65e7b91455b1b447ecb15f04b5278ccc397c2c87/Chrome_64px.ico -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChromeAutoUpdate 2 | 一个自动更新chrome的小工具 3 | 4 | 第一次使用的时候会下载chrome最新版,需要稍微等待。 5 | 6 | 360会有各种提示,卸载360即可[doge]。 7 | 8 | 打开桌面快捷方式时,会检测更新,然后打开chrome。 9 | 10 | 会根据你的操作系统,自动选择32位、64位版chrome。 11 | 12 | 每次更新后,下次启动chrome即可生效。 13 | 14 | 提示adobe flash版本过旧,下载:http://fpdownload.macromedia.com/pub/flashplayer/latest/help/install_flash_player_ppapi.exe 即可。 15 | 16 | 目前是测试版,功能还不齐全,每天都会更新添加功能。 17 | 18 | 注意:本工具不支持xp。 19 | 20 | bug反馈联系微博@你的档案。 21 | 22 | 主页:http://chrome.wbdacdn.com/ 23 | 24 | # 更新原理 25 | 26 | 请求更新接口,下载chrome新版安装包,验证签名,解压覆盖。 27 | 28 | # To Do List 29 | - 使用安装包更新 30 | 31 | - 没有.net4.5的,安装.net4.5 32 | 33 | - 升级.net框架到4.5 34 | 35 | - 增加从zeronet源更新功能 36 | 37 | # 更新日志 38 | 1.11.1.17:支持升级默认安装的chrome(如果安装在系统目录,会申请管理员权限),也可以修改配置文件定义chrome安装路径。 39 | 40 | 1.11.5.18:增加下载超时处理,增加更新渠道默认参数,添加多地址下载支持,解决部分网络用户无法更新。 41 | 42 | 1.11.6.23:默认保存chrome到安装目录,不和原有chrome冲突 43 | 44 | 1.11.16.21:判断chrome安装目录是否存在,解决第一次使用的时候,由于目录不存在,导致程序无法响应。 45 | 46 | 1.11.18.21:增加bit参数,int字节位数 8是64系统,4是32位 47 | 48 | 1.11.21.22:自动删除老的目录 49 | 50 | 1.11.22.14:修正目录处理错误,导致删除失败的问题 51 | 52 | 1.12.05.20:解决更新的时候,文件占用的问题。 53 | 54 | 1.2017.02.07:增加下载进度显示。 55 | 56 | 1.2017.02.09:增加图形化配置,第一次使用时需要配置,增加DHT网络(实验)。 57 | 58 | 1.2017.02.11:设置工作目录,解决开机启动的时候,目录不正确;解决重复打开的时候,有弹窗提示;解决写入日志文件冲突的问题。 59 | 60 | 1.2017.04.26:去掉关机提示 61 | 62 | 1.2017.05.14:任务栏右下角通知区域增加图标显示 63 | 64 | 65 | # 配置文件 66 | 67 | [server] 68 | 69 | update_url=http://chrome.wbdacdn.com/update.php #主程序升级接口 70 | 71 | app_update_url=http://chrome.wbdacdn.com/app_update.php #chrome升级接口 72 | 73 | [config] 74 | 75 | version=4 #配置文件版本,请勿修改 76 | 77 | [app] 78 | 79 | index= #默认打开页面 80 | 81 | Params= #启动chrome的参数 82 | 83 | user_agent="Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/56.0.2902.0 Safari/537.36" 84 | 85 | path=C:\soft\ChromeAutoUpdate\ #chrome安装目录,需要 \ 结尾 86 | 87 | Channel=dev #取值 'Stable','Beta','Dev','Canary' 88 | 89 | bit=8 # int字节位数 8是64系统,4是32位 90 | -------------------------------------------------------------------------------- /build.nsi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenjia404/ChromeAutoUpdate/65e7b91455b1b447ecb15f04b5278ccc397c2c87/build.nsi --------------------------------------------------------------------------------