• 自动查找并关闭窗口


    Form1界面及VS生成代码:
    View Code
    namespace WindowCloser
    {
        partial class Form1
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.components = new System.ComponentModel.Container();
                this.groupBox1 = new System.Windows.Forms.GroupBox();
                this.dgWindowFilter = new System.Windows.Forms.DataGridView();
                this.WindowTextFilter = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.WindowProcNameFilter = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.WindowOperateMode = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.WindowClickButtonTextFilter = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.btnDeleteWindowFilter = new System.Windows.Forms.Button();
                this.btnEditWindowFilter = new System.Windows.Forms.Button();
                this.groupBox2 = new System.Windows.Forms.GroupBox();
                this.cmbOperateType = new System.Windows.Forms.ComboBox();
                this.label4 = new System.Windows.Forms.Label();
                this.txtButtonTextFilter = new System.Windows.Forms.TextBox();
                this.label3 = new System.Windows.Forms.Label();
                this.txtProcessFilter = new System.Windows.Forms.TextBox();
                this.label2 = new System.Windows.Forms.Label();
                this.txtTextFilter = new System.Windows.Forms.TextBox();
                this.label1 = new System.Windows.Forms.Label();
                this.btnSave = new System.Windows.Forms.Button();
                this.btnResetWindowsFilter = new System.Windows.Forms.Button();
                this.btnAddWindowsFilter = new System.Windows.Forms.Button();
                this.btnStart = new System.Windows.Forms.Button();
                this.timer1 = new System.Windows.Forms.Timer(this.components);
                this.btnStop = new System.Windows.Forms.Button();
                this.chkAutoStart = new System.Windows.Forms.CheckBox();
                this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
                this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
                this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.groupBox1.SuspendLayout();
                ((System.ComponentModel.ISupportInitialize)(this.dgWindowFilter)).BeginInit();
                this.groupBox2.SuspendLayout();
                this.contextMenuStrip1.SuspendLayout();
                this.SuspendLayout();
                // 
                // groupBox1
                // 
                this.groupBox1.Controls.Add(this.dgWindowFilter);
                this.groupBox1.Controls.Add(this.btnDeleteWindowFilter);
                this.groupBox1.Controls.Add(this.btnEditWindowFilter);
                this.groupBox1.Location = new System.Drawing.Point(12, 12);
                this.groupBox1.Name = "groupBox1";
                this.groupBox1.Size = new System.Drawing.Size(710, 290);
                this.groupBox1.TabIndex = 0;
                this.groupBox1.TabStop = false;
                this.groupBox1.Text = "Window Filters";
                // 
                // dgWindowFilter
                // 
                this.dgWindowFilter.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
                this.dgWindowFilter.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
                this.dgWindowFilter.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
                this.WindowTextFilter,
                this.WindowProcNameFilter,
                this.WindowOperateMode,
                this.WindowClickButtonTextFilter});
                this.dgWindowFilter.Location = new System.Drawing.Point(20, 19);
                this.dgWindowFilter.Name = "dgWindowFilter";
                this.dgWindowFilter.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
                this.dgWindowFilter.Size = new System.Drawing.Size(673, 226);
                this.dgWindowFilter.TabIndex = 2;
                this.dgWindowFilter.SelectionChanged += new System.EventHandler(this.dgWindowFilter_SelectionChanged);
                // 
                // WindowTextFilter
                // 
                this.WindowTextFilter.DataPropertyName = "WindowTextFilter";
                this.WindowTextFilter.HeaderText = "Window Text Filter";
                this.WindowTextFilter.Name = "WindowTextFilter";
                this.WindowTextFilter.ReadOnly = true;
                // 
                // WindowProcNameFilter
                // 
                this.WindowProcNameFilter.DataPropertyName = "WindowProcNameFilter";
                this.WindowProcNameFilter.HeaderText = "Window Process Name Filter";
                this.WindowProcNameFilter.Name = "WindowProcNameFilter";
                this.WindowProcNameFilter.ReadOnly = true;
                // 
                // WindowOperateMode
                // 
                this.WindowOperateMode.DataPropertyName = "WindowOperateMode";
                this.WindowOperateMode.HeaderText = "Operate Type";
                this.WindowOperateMode.Name = "WindowOperateMode";
                this.WindowOperateMode.ReadOnly = true;
                // 
                // WindowClickButtonTextFilter
                // 
                this.WindowClickButtonTextFilter.DataPropertyName = "WindowClickButtonTextFilter";
                this.WindowClickButtonTextFilter.HeaderText = "Click Button Text Filter";
                this.WindowClickButtonTextFilter.Name = "WindowClickButtonTextFilter";
                this.WindowClickButtonTextFilter.ReadOnly = true;
                // 
                // btnDeleteWindowFilter
                // 
                this.btnDeleteWindowFilter.AutoSize = true;
                this.btnDeleteWindowFilter.Enabled = false;
                this.btnDeleteWindowFilter.Location = new System.Drawing.Point(523, 251);
                this.btnDeleteWindowFilter.Name = "btnDeleteWindowFilter";
                this.btnDeleteWindowFilter.Size = new System.Drawing.Size(82, 23);
                this.btnDeleteWindowFilter.TabIndex = 1;
                this.btnDeleteWindowFilter.Text = "Delete";
                this.btnDeleteWindowFilter.UseVisualStyleBackColor = true;
                this.btnDeleteWindowFilter.Click += new System.EventHandler(this.btnDeleteWindowFilter_Click);
                // 
                // btnEditWindowFilter
                // 
                this.btnEditWindowFilter.AutoSize = true;
                this.btnEditWindowFilter.Enabled = false;
                this.btnEditWindowFilter.Location = new System.Drawing.Point(611, 251);
                this.btnEditWindowFilter.Name = "btnEditWindowFilter";
                this.btnEditWindowFilter.Size = new System.Drawing.Size(82, 23);
                this.btnEditWindowFilter.TabIndex = 1;
                this.btnEditWindowFilter.Text = "Edit";
                this.btnEditWindowFilter.UseVisualStyleBackColor = true;
                this.btnEditWindowFilter.Click += new System.EventHandler(this.btnEditWindowFilter_Click);
                // 
                // groupBox2
                // 
                this.groupBox2.Controls.Add(this.cmbOperateType);
                this.groupBox2.Controls.Add(this.label4);
                this.groupBox2.Controls.Add(this.txtButtonTextFilter);
                this.groupBox2.Controls.Add(this.label3);
                this.groupBox2.Controls.Add(this.txtProcessFilter);
                this.groupBox2.Controls.Add(this.label2);
                this.groupBox2.Controls.Add(this.txtTextFilter);
                this.groupBox2.Controls.Add(this.label1);
                this.groupBox2.Controls.Add(this.btnSave);
                this.groupBox2.Controls.Add(this.btnResetWindowsFilter);
                this.groupBox2.Controls.Add(this.btnAddWindowsFilter);
                this.groupBox2.Location = new System.Drawing.Point(12, 308);
                this.groupBox2.Name = "groupBox2";
                this.groupBox2.Size = new System.Drawing.Size(710, 163);
                this.groupBox2.TabIndex = 0;
                this.groupBox2.TabStop = false;
                this.groupBox2.Text = "Window Property Filter Add";
                // 
                // cmbOperateType
                // 
                this.cmbOperateType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
                this.cmbOperateType.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.cmbOperateType.FormattingEnabled = true;
                this.cmbOperateType.Items.AddRange(new object[] {
                "Close window via SendMessage to the window directly",
                "Close window via clicking child button"});
                this.cmbOperateType.Location = new System.Drawing.Point(167, 76);
                this.cmbOperateType.Name = "cmbOperateType";
                this.cmbOperateType.Size = new System.Drawing.Size(526, 21);
                this.cmbOperateType.TabIndex = 4;
                this.cmbOperateType.SelectedIndexChanged += new System.EventHandler(this.cmbOperateType_SelectedIndexChanged);
                // 
                // label4
                // 
                this.label4.AutoSize = true;
                this.label4.Location = new System.Drawing.Point(17, 80);
                this.label4.Name = "label4";
                this.label4.Size = new System.Drawing.Size(78, 13);
                this.label4.TabIndex = 2;
                this.label4.Text = "Operate Mode:";
                // 
                // txtButtonTextFilter
                // 
                this.txtButtonTextFilter.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.txtButtonTextFilter.Location = new System.Drawing.Point(167, 103);
                this.txtButtonTextFilter.Name = "txtButtonTextFilter";
                this.txtButtonTextFilter.Size = new System.Drawing.Size(526, 20);
                this.txtButtonTextFilter.TabIndex = 3;
                // 
                // label3
                // 
                this.label3.AutoSize = true;
                this.label3.Location = new System.Drawing.Point(17, 106);
                this.label3.Name = "label3";
                this.label3.Size = new System.Drawing.Size(114, 13);
                this.label3.TabIndex = 2;
                this.label3.Text = "Click Button Text Like:";
                // 
                // txtProcessFilter
                // 
                this.txtProcessFilter.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.txtProcessFilter.Location = new System.Drawing.Point(167, 51);
                this.txtProcessFilter.Name = "txtProcessFilter";
                this.txtProcessFilter.Size = new System.Drawing.Size(526, 20);
                this.txtProcessFilter.TabIndex = 3;
                // 
                // label2
                // 
                this.label2.AutoSize = true;
                this.label2.Location = new System.Drawing.Point(17, 54);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(144, 13);
                this.label2.TabIndex = 2;
                this.label2.Text = "Window Process Name Like:";
                // 
                // txtTextFilter
                // 
                this.txtTextFilter.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.txtTextFilter.Location = new System.Drawing.Point(167, 25);
                this.txtTextFilter.Name = "txtTextFilter";
                this.txtTextFilter.Size = new System.Drawing.Size(526, 20);
                this.txtTextFilter.TabIndex = 3;
                // 
                // label1
                // 
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(17, 28);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(96, 13);
                this.label1.TabIndex = 2;
                this.label1.Text = "Window Text Like:";
                // 
                // btnSave
                // 
                this.btnSave.AutoSize = true;
                this.btnSave.Enabled = false;
                this.btnSave.Location = new System.Drawing.Point(435, 129);
                this.btnSave.Name = "btnSave";
                this.btnSave.Size = new System.Drawing.Size(82, 23);
                this.btnSave.TabIndex = 1;
                this.btnSave.Text = "Save";
                this.btnSave.UseVisualStyleBackColor = true;
                this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
                // 
                // btnResetWindowsFilter
                // 
                this.btnResetWindowsFilter.AutoSize = true;
                this.btnResetWindowsFilter.Location = new System.Drawing.Point(523, 129);
                this.btnResetWindowsFilter.Name = "btnResetWindowsFilter";
                this.btnResetWindowsFilter.Size = new System.Drawing.Size(82, 23);
                this.btnResetWindowsFilter.TabIndex = 1;
                this.btnResetWindowsFilter.Text = "Reset";
                this.btnResetWindowsFilter.UseVisualStyleBackColor = true;
                this.btnResetWindowsFilter.Click += new System.EventHandler(this.btnResetWindowsFilter_Click);
                // 
                // btnAddWindowsFilter
                // 
                this.btnAddWindowsFilter.AutoSize = true;
                this.btnAddWindowsFilter.Location = new System.Drawing.Point(611, 129);
                this.btnAddWindowsFilter.Name = "btnAddWindowsFilter";
                this.btnAddWindowsFilter.Size = new System.Drawing.Size(82, 23);
                this.btnAddWindowsFilter.TabIndex = 1;
                this.btnAddWindowsFilter.Text = "Add";
                this.btnAddWindowsFilter.UseVisualStyleBackColor = true;
                this.btnAddWindowsFilter.Click += new System.EventHandler(this.btnAddWindowsFilter_Click);
                // 
                // btnStart
                // 
                this.btnStart.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.btnStart.Location = new System.Drawing.Point(623, 477);
                this.btnStart.Name = "btnStart";
                this.btnStart.Size = new System.Drawing.Size(82, 28);
                this.btnStart.TabIndex = 1;
                this.btnStart.Text = "Start";
                this.btnStart.UseVisualStyleBackColor = true;
                this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
                // 
                // timer1
                // 
                this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
                // 
                // btnStop
                // 
                this.btnStop.Enabled = false;
                this.btnStop.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.btnStop.Location = new System.Drawing.Point(535, 477);
                this.btnStop.Name = "btnStop";
                this.btnStop.Size = new System.Drawing.Size(82, 28);
                this.btnStop.TabIndex = 1;
                this.btnStop.Text = "Stop";
                this.btnStop.UseVisualStyleBackColor = true;
                this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
                // 
                // chkAutoStart
                // 
                this.chkAutoStart.AutoSize = true;
                this.chkAutoStart.Location = new System.Drawing.Point(12, 484);
                this.chkAutoStart.Name = "chkAutoStart";
                this.chkAutoStart.Size = new System.Drawing.Size(205, 17);
                this.chkAutoStart.TabIndex = 2;
                this.chkAutoStart.Text = "Auto press start button when lanched.";
                this.chkAutoStart.UseVisualStyleBackColor = true;
                this.chkAutoStart.CheckedChanged += new System.EventHandler(this.chkAutoStart_CheckedChanged);
                // 
                // notifyIcon1
                // 
                this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
                this.notifyIcon1.Text = "Window Closer";
                this.notifyIcon1.Visible = true;
                this.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);
                // 
                // contextMenuStrip1
                // 
                this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.exitToolStripMenuItem});
                this.contextMenuStrip1.Name = "contextMenuStrip1";
                this.contextMenuStrip1.Size = new System.Drawing.Size(93, 26);
                // 
                // exitToolStripMenuItem
                // 
                this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
                this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
                this.exitToolStripMenuItem.Text = "Exit";
                this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(734, 512);
                this.Controls.Add(this.chkAutoStart);
                this.Controls.Add(this.btnStop);
                this.Controls.Add(this.btnStart);
                this.Controls.Add(this.groupBox2);
                this.Controls.Add(this.groupBox1);
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
                this.MaximizeBox = false;
                this.Name = "Form1";
                this.ShowInTaskbar = false;
                this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
                this.Text = "Window Closer";
                this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
                this.Load += new System.EventHandler(this.Form1_Load);
                this.SizeChanged += new System.EventHandler(this.Form1_SizeChanged);
                this.groupBox1.ResumeLayout(false);
                this.groupBox1.PerformLayout();
                ((System.ComponentModel.ISupportInitialize)(this.dgWindowFilter)).EndInit();
                this.groupBox2.ResumeLayout(false);
                this.groupBox2.PerformLayout();
                this.contextMenuStrip1.ResumeLayout(false);
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.Windows.Forms.GroupBox groupBox1;
            private System.Windows.Forms.GroupBox groupBox2;
            private System.Windows.Forms.Button btnAddWindowsFilter;
            private System.Windows.Forms.Button btnStart;
            private System.Windows.Forms.Button btnDeleteWindowFilter;
            private System.Windows.Forms.Timer timer1;
            private System.Windows.Forms.TextBox txtTextFilter;
            private System.Windows.Forms.Label label1;
            private System.Windows.Forms.TextBox txtProcessFilter;
            private System.Windows.Forms.Label label2;
            private System.Windows.Forms.TextBox txtButtonTextFilter;
            private System.Windows.Forms.Label label3;
            private System.Windows.Forms.Button btnResetWindowsFilter;
            private System.Windows.Forms.DataGridView dgWindowFilter;
            private System.Windows.Forms.Button btnEditWindowFilter;
            private System.Windows.Forms.Label label4;
            private System.Windows.Forms.ComboBox cmbOperateType;
            private System.Windows.Forms.Button btnStop;
            private System.Windows.Forms.DataGridViewTextBoxColumn WindowTextFilter;
            private System.Windows.Forms.DataGridViewTextBoxColumn WindowProcNameFilter;
            private System.Windows.Forms.DataGridViewTextBoxColumn WindowOperateMode;
            private System.Windows.Forms.DataGridViewTextBoxColumn WindowClickButtonTextFilter;
            private System.Windows.Forms.Button btnSave;
            private System.Windows.Forms.CheckBox chkAutoStart;
            private System.Windows.Forms.NotifyIcon notifyIcon1;
            private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
            private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
        }
    }
    Form1事件及方法代码(查找并关闭窗口的核心代码都在这里):
    View Code
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Microsoft.VisualBasic;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Threading;
    using System.Configuration;
    
    namespace WindowCloser
    {
        public partial class Form1 : Form
        {
            private const int WM_CLOSE = 0x0010;
            private const int GWL_STYLE = -16;
            private const uint WS_POPUP = 0x80000000;
            private const int WM_CLICK = 0xF5;
            private delegate bool EnumWindowsCallBack(int hwnd, int lParam);
            private delegate bool EnumChildWindowsCallBack(int hwnd, int lParam);
    
            [DllImport("user32.dll")]
            private static extern int EnumWindows(EnumWindowsCallBack callback, int lParam);
            [DllImport("user32.dll")]
            private static extern int EnumChildWindows(IntPtr hWndParent, EnumChildWindowsCallBack lpfn, int lParam);
            [DllImport("user32")]
            private static extern int GetWindowText(int hwnd, StringBuilder lptrString, int nMaxCount);
            [DllImport("user32")]
            private static extern int GetParent(int hwnd);
            [DllImport("user32")]
            private static extern int IsWindowVisible(int hwnd);
            [DllImport("user32.dll", EntryPoint = "SendMessageA")]
            private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
            [DllImport("user32.dll", SetLastError = true)]
            private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
            [DllImport("kernel32.dll", EntryPoint = "GetModuleFileNameA")]
            private static extern int GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize);
            [DllImport("user32.dll")]
            private extern static uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
            [DllImport("user32.dll")]
            private extern static uint GetWindowLong(IntPtr hwnd, int nIndex);
    
            public class WindowFilter
            {
                public string WindowTextFilter { get; set; }
                public string WindowProcNameFilter { get; set; }
                public int WindowOperateMode { get; set; }
                public string WindowClickButtonTextFilter { get; set; }
            }
    
            private List<WindowFilter> WindowFilterList = new List<WindowFilter>();
            private string[] args;
    
            public Form1()
            {
                InitializeComponent();
                Control.CheckForIllegalCrossThreadCalls = false;
            }
    
            public Form1(string[] args)
            {
                InitializeComponent();
                this.args = args;
            }
    
            private bool AutoStart
            {
                get
                {
                    var config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
                    var section = config.GetSection("appSettings") as AppSettingsSection;
                    if (section.Settings["autostart"] == null)
                        section.Settings.Add("autostart", string.Empty);
                    else if (!string.IsNullOrWhiteSpace(section.Settings["autostart"].Value))
                        return true;
                    return false;
                }
                set
                {
                    var config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
                    var section = config.GetSection("appSettings") as AppSettingsSection;
                    if (value)
                    {
                        if (section.Settings["autostart"] == null)
                            section.Settings.Add("autostart", "1");
                        else
                            section.Settings["autostart"].Value = "1";
    
                        CreateShortcut();
                    }
                    else
                    {
                        if (section.Settings["autostart"] == null)
                            section.Settings.Add("autostart", "");
                        else
                            section.Settings["autostart"].Value = "";
    
                        DeleteShortcut();
                    }
                    config.Save(ConfigurationSaveMode.Modified, true);
                }
            }
    
            private void CreateShortcut()
            {
                var linkPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup) + "\\WindowCloser.lnk";
                var sc = new Shortcut(System.Reflection.Assembly.GetExecutingAssembly().Location);
                sc.WorkingDirectory = System.Environment.CurrentDirectory;
                sc.Description = "Window Closer";
                sc.Arguments = "hide";
                sc.Save(linkPath);
            }
    
            private void DeleteShortcut()
            {
                var linkPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup) + "\\WindowCloser.lnk";
                if (System.IO.File.Exists(linkPath))
                {
                    try
                    {
                        System.IO.File.Delete(linkPath);
                    }
                    catch (Exception)
                    {
                        
                    }
                    
                }
            }
    
            private List<WindowFilter> GetData()
            {
                var config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
                var section = config.GetSection("appSettings") as AppSettingsSection;
                var data = section.Settings["data"];
                if (data == null)
                    return null;
                try
                {
                    var result = JsonHelper.JsonDeserialize<List<WindowFilter>>(data.Value);
                    return result;
                }
                catch (Exception)
                {
                    return null;
                }
                
            }
    
            private void SaveData(List<WindowFilter> data)
            {
                var config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
                var section = config.GetSection("appSettings") as AppSettingsSection;
                if (section.Settings["data"] == null)
                    section.Settings.Add("data", string.Empty);
                section.Settings["data"].Value = JsonHelper.JsonSerialize<List<WindowFilter>>(data);
                config.Save(ConfigurationSaveMode.Modified, true);
                ConfigurationManager.RefreshSection("AppSettings");
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                dgWindowFilter.AutoGenerateColumns = false;
                cmbOperateType.SelectedIndex = 0;
                var data = this.GetData();
                if (data != null)
                    WindowFilterList = data;
                if (WindowFilterList != null)
                {
                    dgWindowFilter.DataSource = WindowFilterList;
                }
                if (this.AutoStart)
                {
                    chkAutoStart.Checked = true;
                }
    
                this.notifyIcon1.Icon = this.Icon;
                this.notifyIcon1.Visible = true;
    
                if (args != null && args.Length > 0 && args[0].ToUpper() == "HIDE")
                {
                    new Thread(new ThreadStart(delegate()
                    {
                        this.Invoke(new MethodInvoker(delegate()
                        {
                            this.Toggle();
                        }));
                    })) { IsBackground = true }.Start();
                }
    
                CreateShortcut();
    
                btnStart_Click(btnStart, new EventArgs());
            }
    
            public bool EnumWindowsProc(int hwnd, int lParam)
            {
                Application.DoEvents();
                DoMyProcess(hwnd, 0);
                EnumChildWindows(new IntPtr(hwnd), EnumChildWindowsProc, hwnd);
                return true;
            }
    
            public bool EnumChildWindowsProc(int hwnd, int lParam)
            {
                Application.DoEvents();
                DoMyProcess(hwnd,lParam);
                return true;
            }
    
            public void DoMyProcess(int hwnd,int parent)
            {
                if (IsWindowVisible(hwnd) != 1)
                    return;
    
                var windowText = string.Empty;
                var processName = string.Empty;
                var parentText = string.Empty;
                windowText = GetWindowText(hwnd);
                processName = GetExeNameFromWindow(hwnd) + ".exe";
                parentText = GetWindowText(parent);
    
                if (parent == 0)
                {
                    foreach (var item in WindowFilterList)
                    {
                        if (item.WindowOperateMode == 0)
                        {
                            if (windowText.ToUpper().Contains(item.WindowTextFilter.ToUpper()))
                            {
                                if (!string.IsNullOrEmpty(item.WindowProcNameFilter) && processName.ToUpper().Contains(item.WindowProcNameFilter.ToUpper()))
                                {
                                    SendMessage(new IntPtr(hwnd), WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                                }
                                else if (string.IsNullOrWhiteSpace(item.WindowProcNameFilter))
                                {
                                    SendMessage(new IntPtr(hwnd), WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                                }
                            }
                        }
                    }
                        
                }
                else
                {
                    foreach (var item in WindowFilterList)
                    {
                        if (item.WindowOperateMode == 1)
                        { 
                            if(parentText.ToUpper().Contains(item.WindowTextFilter.ToUpper()))
                            {
                                if (!string.IsNullOrEmpty(item.WindowProcNameFilter) && processName.ToUpper().Contains(item.WindowProcNameFilter.ToUpper()))
                                {
                                    if (windowText.ToUpper().Contains(item.WindowClickButtonTextFilter.ToUpper()))
                                    {
                                        SendMessage(new IntPtr(hwnd), WM_CLICK, IntPtr.Zero, IntPtr.Zero);
                                    }
                                }
                                else if (string.IsNullOrWhiteSpace(item.WindowProcNameFilter))
                                {
                                    if (windowText.ToUpper().Contains(item.WindowClickButtonTextFilter.ToUpper()))
                                    {
                                        SendMessage(new IntPtr(hwnd), WM_CLICK, IntPtr.Zero, IntPtr.Zero);
                                    }
                                }
                            }
                        }
                    }
                }
                //lstWindowOperator.Items.Add(windowText + "::::::::::::::::::::" + processName);
            }
    
            public string GetWindowText(int hwnd)
            {
                StringBuilder sb = new StringBuilder(1024);
                GetWindowText(hwnd, sb, sb.Capacity);
                if (sb.Length > 0)
                {
                    return sb.ToString();
                }
                return string.Empty;
            }
    
            public string GetExeNameFromWindow(int hwnd)
            {
                uint processID = 0;
                uint threadID = GetWindowThreadProcessId(new IntPtr(hwnd), out processID);
                var proc = Process.GetProcessById((int)processID);
                if (proc != null)
                    return proc.ProcessName;
                else
                    return string.Empty;
            }
    
            public bool IsPopupWindow(int hwnd)
            {
                uint style = GetWindowLong(new IntPtr(hwnd), GWL_STYLE);
                if ((style & WS_POPUP)>0)
                    return true;
                else
                    return false;
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                timer1.Start();
                timer1.Tag = 1;
                btnStart.Enabled = false;
                btnStop.Enabled = true;
            }
    
            private void btnStop_Click(object sender, EventArgs e)
            {
                timer1.Stop();
                timer1.Tag = 0;
                btnStart.Enabled = true;
                btnStop.Enabled = false;
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                timer1.Stop();
                EnumWindows(this.EnumWindowsProc, 0);
                if (timer1.Tag != null && timer1.Tag.ToString() == "1")
                {
                    timer1.Start();
                }
            }
    
            private void btnResetWindowsFilter_Click(object sender, EventArgs e)
            {
                ClearInput();
            }
    
            private void ClearInput()
            {
                txtButtonTextFilter.Clear();
                txtProcessFilter.Clear();
                txtTextFilter.Clear();
                cmbOperateType.SelectedIndex = 0;
            }
    
            private void cmbOperateType_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (cmbOperateType.SelectedIndex < 0)
                    return;
                else if (cmbOperateType.SelectedIndex == 0)
                {
                    txtButtonTextFilter.Clear();
                    txtButtonTextFilter.Enabled = false;
                }
                else
                {
                    txtButtonTextFilter.Enabled = true;
                }
            }
    
            private void btnAddWindowsFilter_Click(object sender, EventArgs e)
            {
                var filter = new WindowFilter();
                filter.WindowTextFilter = txtTextFilter.Text;
                filter.WindowProcNameFilter = txtProcessFilter.Text;
                filter.WindowOperateMode = cmbOperateType.SelectedIndex;
                filter.WindowClickButtonTextFilter = txtButtonTextFilter.Text;
                if (!CheckAdd(filter))
                    return;
                WindowFilterList.Add(filter);
                ClearInput();
                BindData();
            }
    
            private bool CheckAdd(WindowFilter filter)
            { 
                if(string.IsNullOrWhiteSpace(filter.WindowTextFilter))
                {
                    MessageBox.Show("Please input the Window Text Filter!");
                    return false;
                }
    
                if (filter.WindowOperateMode == 1 && string.IsNullOrWhiteSpace(filter.WindowClickButtonTextFilter))
                {
                    MessageBox.Show("Please input the Click Button Text Filter!");
                    return false;
                }
                return true;
            }
    
            private void BindData()
            {
                dgWindowFilter.DataSource = null;
                dgWindowFilter.DataSource = WindowFilterList;
                this.SaveData(WindowFilterList);
                for (int i = 0; i < dgWindowFilter.Columns.Count; i++)
                {
                    dgWindowFilter.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
                }
            }
    
            private void dgWindowFilter_SelectionChanged(object sender, EventArgs e)
            {
                if (dgWindowFilter.SelectedRows.Count > 0)
                    btnDeleteWindowFilter.Enabled = btnEditWindowFilter.Enabled = true;
                else
                    btnDeleteWindowFilter.Enabled = btnEditWindowFilter.Enabled = false;
            }
    
            private void btnDeleteWindowFilter_Click(object sender, EventArgs e)
            {
                if (MessageBox.Show(this, "Do you rearly want to delete the selected items?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Information) != System.Windows.Forms.DialogResult.Yes)
                {
                    return;
                }
    
                if (dgWindowFilter.SelectedRows.Count > 0)
                {
                    foreach (DataGridViewRow row in dgWindowFilter.SelectedRows.Cast<DataGridViewRow>().OrderByDescending(x=>x.Index))
                    {
                        WindowFilterList.RemoveAt(row.Index);
                    }
    
                    BindData();
                }
            }
    
            private void btnEditWindowFilter_Click(object sender, EventArgs e)
            {
                if (dgWindowFilter.SelectedRows.Count <= 0)
                {
                    return;
                }
    
                if (dgWindowFilter.SelectedRows.Count > 1 )
                {
                    MessageBox.Show("Too many rows selected to Edit!");
                    return;
                }
    
                var filter = WindowFilterList[dgWindowFilter.SelectedRows[0].Index];
                txtTextFilter.Text = filter.WindowTextFilter;
                txtProcessFilter.Text = filter.WindowProcNameFilter;
                cmbOperateType.SelectedIndex = filter.WindowOperateMode;
                txtButtonTextFilter.Text = filter.WindowClickButtonTextFilter;
                btnSave.Enabled = true;
                btnSave.Tag = dgWindowFilter.SelectedRows[0].Index;
                btnAddWindowsFilter.Enabled = false;
                btnResetWindowsFilter.Enabled = false;
            }
    
            private void btnSave_Click(object sender, EventArgs e)
            {
                var filter = new WindowFilter();
                filter.WindowTextFilter = txtTextFilter.Text;
                filter.WindowProcNameFilter = txtProcessFilter.Text;
                filter.WindowOperateMode = cmbOperateType.SelectedIndex;
                filter.WindowClickButtonTextFilter = txtButtonTextFilter.Text;
                if (!CheckAdd(filter))
                    return;
                WindowFilterList[Convert.ToInt32(btnSave.Tag)] = filter;
                ClearInput();
                BindData();
                btnSave.Tag = null;
                btnSave.Enabled = false;
                btnAddWindowsFilter.Enabled = true;
                btnResetWindowsFilter.Enabled = true;
            }
    
            private void chkAutoStart_CheckedChanged(object sender, EventArgs e)
            {
                this.AutoStart = chkAutoStart.Checked;
            }
    
            private void Toggle()
            {
                if (this.WindowState== FormWindowState.Normal)
                {
                    base.Hide();
                    base.WindowState = FormWindowState.Minimized;                
                }
                else
                {
                    base.Show();
                    base.WindowState = FormWindowState.Normal;                
                }
            }
    
            private void notifyIcon1_DoubleClick(object sender, EventArgs e)
            {
                Toggle();
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (e.CloseReason == CloseReason.UserClosing)
                {
                    e.Cancel = true;
                    this.Hide();
                }
            }
    
            private void exitToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
    
            private void Form1_SizeChanged(object sender, EventArgs e)
            {
                if (this.WindowState == FormWindowState.Minimized && this.Visible)
                {
                    base.Hide();
                }
            }
    
        }
    }
    创建快捷方式类及引用到的Win32API(这段代码可能没多大用,与其它程序联系比较小,因创建快捷方式有缺陷,后期代码可能没有用到):
    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace WindowCloser
    {
        static internal class NativeClasses
        {
            [Flags]
            internal enum SLR_MODE : uint
            {
                SLR_INVOKE_MSI = 0x80,
                SLR_NOLINKINFO = 0x40,
                SLR_NO_UI = 0x1,
                SLR_NOUPDATE = 0x8,
                SLR_NOSEARCH = 0x10,
                SLR_NOTRACK = 0x20,
                SLR_UPDATE = 0x4,
                SLR_NO_UI_WITH_MSG_PUMP = 0x101
            }
    
            [Flags]
            internal enum STGM_ACCESS : uint
            {
                STGM_READ = 0x00000000,
                STGM_WRITE = 0x00000001,
                STGM_READWRITE = 0x00000002,
                STGM_SHARE_DENY_NONE = 0x00000040,
                STGM_SHARE_DENY_READ = 0x00000030,
                STGM_SHARE_DENY_WRITE = 0x00000020,
                STGM_SHARE_EXCLUSIVE = 0x00000010,
                STGM_PRIORITY = 0x00040000,
                STGM_CREATE = 0x00001000,
                STGM_CONVERT = 0x00020000,
                STGM_FAILIFTHERE = 0x00000000,
                STGM_DIRECT = 0x00000000,
                STGM_TRANSACTED = 0x00010000,
                STGM_NOSCRATCH = 0x00100000,
                STGM_NOSNAPSHOT = 0x00200000,
                STGM_SIMPLE = 0x08000000,
                STGM_DIRECT_SWMR = 0x00400000,
                STGM_DELETEONRELEASE = 0x04000000
            }
    
            [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 0)]
            internal struct _FILETIME
            {
                public uint dwLowDateTime;
                public uint dwHighDateTime;
            }
    
            [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 0, CharSet = CharSet.Unicode)]
            internal struct _WIN32_FIND_DATAW
            {
                public uint dwFileAttributes;
                public _FILETIME ftCreationTime;
                public _FILETIME ftLastAccessTime;
                public _FILETIME ftLastWriteTime;
                public uint nFileSizeHigh;
                public uint nFileSizeLow;
                public uint dwReserved0;
                public uint dwReserved1;
    
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
                public string cFileName;
    
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
                public string cAlternateFileName;
            }
    
            internal const uint SLGP_SHORTPATH = 0x01;
            internal const uint SLGP_UNCPRIORITY = 0x02;
            internal const uint SLGP_RAWPATH = 0x04;
    
            [ComImport()]
            [Guid("000214F9-0000-0000-C000-000000000046")]
            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            internal interface IShellLinkW
            {
                [PreserveSig()]
                int GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref _WIN32_FIND_DATAW pfd, uint fFlags);
    
                [PreserveSig()]
                int GetIDList(out IntPtr ppidl);
    
                [PreserveSig()]
                int SetIDList(IntPtr pidl);
    
                [PreserveSig()]
                int GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxName);
    
                [PreserveSig()]
                int SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
    
                [PreserveSig()]
                int GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
    
                [PreserveSig()]
                int SetWorkingDirectory(
                   [MarshalAs(UnmanagedType.LPWStr)] string pszDir);
    
                [PreserveSig()]
                int GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
    
                [PreserveSig()]
                int SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
    
                [PreserveSig()]
                int GetHotkey(out ushort pwHotkey);
    
                [PreserveSig()]
                int SetHotkey(ushort pwHotkey);
    
                [PreserveSig()]
                int GetShowCmd(out uint piShowCmd);
    
                [PreserveSig()]
                int SetShowCmd(uint piShowCmd);
    
                [PreserveSig()]
                int GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
    
                [PreserveSig()]
                int SetIconLocation(
                   [MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
    
                [PreserveSig()]
                int SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);
    
                [PreserveSig()]
                int Resolve(IntPtr hWnd, uint fFlags);
    
                [PreserveSig()]
                int SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
            }
    
            [ComImport()]
            [Guid("0000010B-0000-0000-C000-000000000046")]
            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            internal interface IPersistFile
            {
                [PreserveSig()]
                int GetClassID(out Guid pClassID);
    
                [PreserveSig()]
                int IsDirty();
    
                [PreserveSig()]
                int Load([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode);
    
                [PreserveSig()]
                int Save([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember);
    
                [PreserveSig()]
                int SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
    
                [PreserveSig()]
                int GetCurFile([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath);
            }
    
            [Guid("00021401-0000-0000-C000-000000000046")]
            [ClassInterface(ClassInterfaceType.None)]
            [ComImport()]
            private class CShellLink { }
    
            internal static NativeClasses.IShellLinkW CreateShellLink()
            {
                return (NativeClasses.IShellLinkW)new NativeClasses.CShellLink();
            }
        }
    
        public class Shortcut
        {
            private const int MAX_DESCRIPTION_LENGTH = 512;
            private const int MAX_PATH = 512;
    
            private NativeClasses.IShellLinkW _link;
    
            public Shortcut()
            {
                this._link = NativeClasses.CreateShellLink();
            }
    
            public Shortcut(string path)
                : this()
            {
                Marshal.ThrowExceptionForHR(this._link.SetPath(path));
            }
    
            public string Path
            {
                get
                {
                    NativeClasses._WIN32_FIND_DATAW fdata = new NativeClasses._WIN32_FIND_DATAW();
                    StringBuilder path = new StringBuilder(MAX_PATH, MAX_PATH);
                    Marshal.ThrowExceptionForHR(this._link.GetPath(path, path.MaxCapacity, ref fdata, NativeClasses.SLGP_UNCPRIORITY));
                    return path.ToString();
                }
                set
                {
                    Marshal.ThrowExceptionForHR(this._link.SetPath(value));
                }
            }
    
            public string Description
            {
                get
                {
                    StringBuilder desc = new StringBuilder(MAX_DESCRIPTION_LENGTH, MAX_DESCRIPTION_LENGTH);
                    Marshal.ThrowExceptionForHR(this._link.GetDescription(desc, desc.MaxCapacity));
                    return desc.ToString();
                }
                set
                {
                    Marshal.ThrowExceptionForHR(this._link.SetDescription(value));
                }
            }
    
            public string RelativePath
            {
                set
                {
                    Marshal.ThrowExceptionForHR(this._link.SetRelativePath(value, 0));
                }
            }
    
            public string WorkingDirectory
            {
                get
                {
                    StringBuilder dir = new StringBuilder(MAX_PATH, MAX_PATH);
                    Marshal.ThrowExceptionForHR(this._link.GetWorkingDirectory(dir, dir.MaxCapacity));
                    return dir.ToString();
                }
                set
                {
                    Marshal.ThrowExceptionForHR(this._link.SetWorkingDirectory(value));
                }
            }
    
            public string Arguments
            {
                get
                {
                    StringBuilder args = new StringBuilder(MAX_PATH, MAX_PATH);
                    Marshal.ThrowExceptionForHR(this._link.GetArguments(args, args.MaxCapacity));
                    return args.ToString();
                }
                set
                {
                    Marshal.ThrowExceptionForHR(this._link.SetArguments(value));
                }
            }
    
            public ushort HotKey
            {
                get
                {
                    ushort key = 0;
                    Marshal.ThrowExceptionForHR(this._link.GetHotkey(out key));
                    return key;
                }
                set
                {
                    Marshal.ThrowExceptionForHR(this._link.SetHotkey(value));
                }
            }
    
            public void Resolve(IntPtr hwnd, uint flags)
            {
                Marshal.ThrowExceptionForHR(this._link.Resolve(hwnd, flags));
            }
    
            public void Resolve(IWin32Window window)
            {
                this.Resolve(window.Handle, 0);
            }
    
            public void Resolve()
            {
                this.Resolve(IntPtr.Zero, (uint)NativeClasses.SLR_MODE.SLR_NO_UI);
            }
    
            private NativeClasses.IPersistFile AsPersist
            {
                get { return ((NativeClasses.IPersistFile)this._link); }
            }
    
            public void Save(string fileName)
            {
                int hres = this.AsPersist.Save(fileName, true);
                Marshal.ThrowExceptionForHR(hres);
            }
    
            public void Load(string fileName)
            {
                int hres = this.AsPersist.Load(fileName, (uint)NativeClasses.STGM_ACCESS.STGM_READ);
                Marshal.ThrowExceptionForHR(hres);
            }
        }
    }
    Json数据序列化与反序列化类定义:
    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization.Json;
    using System.IO;
    
    namespace WindowCloser
    {
        public class JsonHelper
        {
            public static string JsonSerialize<T>(T t)
            {
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
                MemoryStream ms = new MemoryStream();
                ser.WriteObject(ms, t);
                string jsonString = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return jsonString;
            }
    
            public static T JsonDeserialize<T>(string jsonString)
            {
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
                MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
                T obj = (T)ser.ReadObject(ms);
                return obj;
            }
        }
    }

    Main函数及程序的启动代码:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WindowCloser
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main(string[] args)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1(args));
            }
        }
    }
  • 相关阅读:
    git删除大文件
    正则表达式学习
    python小技巧集锦
    python的编译
    笔记本BIOS按键和启动项选择按键
    Ubuntu 不能识别U盘
    一文读懂Java 11的ZGC为何如此高效
    ELK原理与介绍
    使用uniapp之-在微信小程序内打开腾讯地图app或高德地图app
    使用Git多人协作开发时分支合并流程
  • 原文地址:https://www.cnblogs.com/nanfei/p/2608726.html
Copyright © 2020-2023  润新知