@@ -63,6 +63,8 @@ public Form1()
6363 toolTip1 . SetToolTip ( numericUpDown8 , "保存几个成功的节点,不选代表不限制,内核版本需要 v2.1.0 以上\n 如果你的并发数量超过这个参数,那么成功的结果可能会大于这个数值" ) ;
6464
6565 toolTip1 . SetToolTip ( textBox11 , "支持标准cron表达式,如:\n 0 */2 * * * 表示每2小时的整点执行\n 0 0 */2 * * 表示每2天的0点执行\n 0 0 1 * * 表示每月1日0点执行\n */30 * * * * 表示每30分钟执行一次\n \n 双击切换 使用「分钟倒计时」" ) ;
66+
67+ toolTip1 . SetToolTip ( checkBox5 , "开机启动:勾选后,程序将在Windows启动时自动运行" ) ;
6668 // 设置通知图标的上下文菜单
6769 SetupNotifyIconContextMenu ( ) ;
6870 }
@@ -178,16 +180,14 @@ private async void timer1_Tick(object sender, EventArgs e)//初始化
178180 comboBox1 . Text = "本地" ;
179181 comboBox4 . Text = "通用订阅" ;
180182 ReadConfig ( ) ;
181- /*
182- string subsCheckPath = Path.Combine(executablePath, "subs-check.exe");
183- if (File.Exists(subsCheckPath)) button1.Enabled = true;
184- else
183+
184+ if ( CheckCommandLineParameter ( "-auto" ) )
185185 {
186- Log("没有找到 subs-check.exe 文件。", true );
187- MessageBox.Show("缺少 subs-check.exe 核心文件。\n\n您可以前往 https://github.com/beck-8/subs-check/releases 自行下载!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information );
188- }
189- */
190- await CheckGitHubVersionAsync ( ) ;
186+ Log ( "检测到开机启动,准备执行任务..." ) ;
187+ button1_Click ( this , EventArgs . Empty ) ;
188+ this . Hide ( ) ;
189+ notifyIcon1 . Visible = true ;
190+ } else await CheckGitHubVersionAsync ( ) ;
191191 }
192192
193193 private async Task CheckGitHubVersionAsync ( )
@@ -253,6 +253,7 @@ private bool IsNetworkAvailable()
253253
254254 private async void ReadConfig ( ) //读取配置文件
255255 {
256+ checkBox5 . CheckedChanged -= checkBox5_CheckedChanged ; // 临时移除事件处理器,防止触发事件
256257 try
257258 {
258259 string executablePath = Path . GetDirectoryName ( System . Windows . Forms . Application . ExecutablePath ) ;
@@ -503,15 +504,19 @@ private async void ReadConfig()//读取配置文件
503504 textBox11 . Visible = true ;
504505 label2 . Visible = false ;
505506 numericUpDown2 . Visible = false ;
506- }
507+ }
507508
509+ string guiauto = 读取config字符串 ( config , "gui-auto" ) ;
510+ if ( guiauto != null && guiauto == "true" ) checkBox5 . Checked = true ;
511+ else checkBox5 . Checked = false ;
508512 }
509513 }
510514 catch ( Exception ex )
511515 {
512516 MessageBox . Show ( $ "读取配置文件时发生错误: { ex . Message } ", "错误" ,
513517 MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
514518 }
519+ checkBox5 . CheckedChanged += checkBox5_CheckedChanged ; // 重新绑定事件处理器
515520 }
516521
517522 private int ? 读取config整数 ( Dictionary < string , object > config , string fieldName )
@@ -728,6 +733,8 @@ private async Task SaveConfig(bool githubProxyCheck = true)//保存配置文件
728733 config [ "sub-urls-retry" ] = 3 ; //重试次数(获取订阅失败后重试次数)
729734 config [ "subscheck-version" ] = 当前subsCheck版本号 ; //当前subsCheck版本号
730735
736+ config [ "gui-auto" ] = checkBox5 . Checked ; //是否开机自启
737+
731738 //保存几个成功的节点,为0代表不限制
732739 if ( checkBox3 . Checked ) config [ "success-limit" ] = ( int ) numericUpDown8 . Value ;
733740 else config [ "success-limit" ] = 0 ;
@@ -1744,12 +1751,24 @@ private void Log(string message, bool isError = false)
17441751
17451752 private void 恢复窗口 ( )
17461753 {
1747- // 显示窗体
1754+ // 首先显示窗体
17481755 this . Show ( ) ;
17491756
1757+ // 强制停止当前布局逻辑
1758+ this . SuspendLayout ( ) ;
1759+
17501760 // 恢复窗口状态
17511761 this . WindowState = FormWindowState . Normal ;
17521762
1763+ // 强制重新布局
1764+ this . ResumeLayout ( true ) ; // 参数true表示立即执行布局
1765+
1766+ // 调用刷新布局的方法
1767+ this . PerformLayout ( ) ;
1768+
1769+ // 处理WindowsForms消息队列中的所有挂起消息
1770+ Application . DoEvents ( ) ;
1771+
17531772 // 激活窗口(使其获得焦点)
17541773 this . Activate ( ) ;
17551774 }
@@ -2945,5 +2964,133 @@ private void button8_Click(object sender, EventArgs e)
29452964 MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
29462965 }
29472966 }
2967+
2968+ private async void checkBox5_CheckedChanged ( object sender , EventArgs e )
2969+ {
2970+ checkBox5 . Enabled = false ;
2971+ try
2972+ {
2973+ // 获取当前应用程序的可执行文件路径
2974+ string appPath = Application . ExecutablePath ;
2975+ // 获取应用程序名称(不包含扩展名)
2976+ string appName = Path . GetFileNameWithoutExtension ( appPath ) ;
2977+ // 获取启动文件夹的路径
2978+ string startupFolderPath = Environment . GetFolderPath ( Environment . SpecialFolder . Startup ) ;
2979+ // 快捷方式文件的完整路径
2980+ string shortcutPath = Path . Combine ( startupFolderPath , $ "{ appName } .lnk") ;
2981+
2982+ if ( checkBox5 . Checked )
2983+ {
2984+ // 检查启动文件夹中是否已存在该快捷方式
2985+ if ( File . Exists ( shortcutPath ) )
2986+ {
2987+ Log ( "开机启动项已存在,无需重复创建" ) ;
2988+ }
2989+ else
2990+ {
2991+ // 创建快捷方式
2992+ CreateShortcut ( appPath , shortcutPath , "-auto" ) ;
2993+ Log ( "已成功创建开机启动项,下次电脑启动时将自动运行程序" ) ;
2994+ }
2995+ }
2996+ else
2997+ {
2998+ // 删除启动项
2999+ if ( File . Exists ( shortcutPath ) )
3000+ {
3001+ File . Delete ( shortcutPath ) ;
3002+ Log ( "已移除开机启动项,下次开机将不会自动启动" ) ;
3003+ }
3004+ }
3005+ }
3006+ catch ( Exception ex )
3007+ {
3008+ Log ( $ "设置开机启动项时出错: { ex . Message } ", true ) ;
3009+ MessageBox . Show ( $ "设置开机启动项失败: { ex . Message } ", "错误" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
3010+
3011+ // 恢复CheckBox状态,避免UI状态与实际状态不一致
3012+ checkBox5 . CheckedChanged -= checkBox5_CheckedChanged ;
3013+ checkBox5 . Checked = ! checkBox5 . Checked ;
3014+ checkBox5 . CheckedChanged += checkBox5_CheckedChanged ;
3015+ }
3016+ checkBox5 . Enabled = true ;
3017+ await SaveConfig ( false ) ;
3018+ }
3019+
3020+ /// <summary>
3021+ /// 创建指向指定路径应用程序的快捷方式
3022+ /// </summary>
3023+ /// <param name="targetPath">目标应用程序的完整路径</param>
3024+ /// <param name="shortcutPath">要创建的快捷方式的完整路径</param>
3025+ /// <param name="arguments">可选的启动参数</param>
3026+ private void CreateShortcut ( string targetPath , string shortcutPath , string arguments = "" )
3027+ {
3028+ // 使用COM接口创建快捷方式
3029+ Type t = Type . GetTypeFromProgID ( "WScript.Shell" ) ;
3030+ dynamic shell = Activator . CreateInstance ( t ) ;
3031+ var shortcut = shell . CreateShortcut ( shortcutPath ) ;
3032+
3033+ shortcut . TargetPath = targetPath ;
3034+ if ( ! string . IsNullOrEmpty ( arguments ) )
3035+ shortcut . Arguments = arguments ; // 设置启动参数
3036+
3037+ shortcut . WorkingDirectory = Path . GetDirectoryName ( targetPath ) ;
3038+ shortcut . WindowStyle = 7 ; // 最小化启动: 7, 正常启动: 1, 最大化启动: 3
3039+ shortcut . Description = "SubsCheck Win GUI自启动快捷方式" ;
3040+ shortcut . IconLocation = targetPath + ",0" ; // 使用应用程序自身的图标
3041+
3042+ // 保存快捷方式
3043+ shortcut . Save ( ) ;
3044+
3045+ // 释放COM对象
3046+ System . Runtime . InteropServices . Marshal . FinalReleaseComObject ( shortcut ) ;
3047+ System . Runtime . InteropServices . Marshal . FinalReleaseComObject ( shell ) ;
3048+ }
3049+
3050+ /// <summary>
3051+ /// 检查启动参数中是否包含指定的参数
3052+ /// </summary>
3053+ /// <param name="parameterName">要检查的参数名称,例如"-autoup"</param>
3054+ /// <returns>如果存在指定参数,则返回true;否则返回false</returns>
3055+ private bool CheckCommandLineParameter ( string parameterName )
3056+ {
3057+ // 获取命令行参数数组
3058+ string [ ] args = Environment . GetCommandLineArgs ( ) ;
3059+
3060+ // 遍历所有参数,检查是否有匹配的参数
3061+ foreach ( string arg in args )
3062+ {
3063+ // 不区分大小写比较
3064+ if ( string . Equals ( arg , parameterName , StringComparison . OrdinalIgnoreCase ) )
3065+ {
3066+ return true ;
3067+ }
3068+ }
3069+
3070+ return false ;
3071+ }
3072+
3073+ private void richTextBox1_DoubleClick ( object sender , EventArgs e )
3074+ {
3075+ // 检查是否有日志内容
3076+ if ( richTextBox1 . TextLength > 0 )
3077+ {
3078+ // 显示确认对话框,询问用户是否要清空日志
3079+ DialogResult result = MessageBox . Show (
3080+ "是否要清空当前日志?" ,
3081+ "清空日志确认" ,
3082+ MessageBoxButtons . YesNo ,
3083+ MessageBoxIcon . Question ,
3084+ MessageBoxDefaultButton . Button2 ) ; // 默认选择"否"按钮
3085+
3086+ if ( result == DialogResult . Yes )
3087+ {
3088+ // 清空richTextBox1内容
3089+ richTextBox1 . Clear ( ) ;
3090+ // 记录一条清空日志的操作信息
3091+ Log ( "日志已清空" ) ;
3092+ }
3093+ }
3094+ }
29483095 }
29493096}
0 commit comments