@@ -131,7 +131,7 @@ fn main() {
131131 }
132132
133133 // 检查 QQ 路径
134- if cfg ! ( target_os = "windows" ) {
134+ let detected_qq_path = if cfg ! ( any ( target_os = "windows" , target_os = "macos" ) ) {
135135 let qq_path_arg = args. iter ( )
136136 . find ( |a| a. starts_with ( "--qq-path=" ) )
137137 . map ( |a| a. trim_start_matches ( "--qq-path=" ) . to_string ( ) ) ;
@@ -144,26 +144,39 @@ fn main() {
144144 eprintln ! ( "错误: 指定的 QQ 路径不存在: {}" , qq_path_arg. as_ref( ) . unwrap( ) ) ;
145145 }
146146
147- let qq_path = if qq_path_arg_invalid { None } else { qq_path_arg. or_else ( get_qq_path_from_registry) } ;
147+ let qq_path = if qq_path_arg_invalid {
148+ None
149+ } else {
150+ qq_path_arg. or_else ( || get_qq_path_from_registry ( & exe_dir) )
151+ } ;
148152
149153 if qq_path. is_none ( ) || !qq_path. as_ref ( ) . map ( |p| Path :: new ( p) . exists ( ) ) . unwrap_or ( false ) {
150- println ! ( "未找到 QQ,是否下载并安装?(y/n)" ) ;
151- let mut input = String :: new ( ) ;
152- if std:: io:: stdin ( ) . read_line ( & mut input) . is_ok ( ) {
153- if input. trim ( ) . eq_ignore_ascii_case ( "y" ) {
154- if !download_and_install_qq ( ) {
155- eprintln ! ( "QQ 下载安装失败" ) ;
154+ if cfg ! ( target_os = "windows" ) {
155+ println ! ( "未找到 QQ,是否下载并安装?(y/n)" ) ;
156+ let mut input = String :: new ( ) ;
157+ if std:: io:: stdin ( ) . read_line ( & mut input) . is_ok ( ) {
158+ if input. trim ( ) . eq_ignore_ascii_case ( "y" ) {
159+ if !download_and_install_qq ( ) {
160+ eprintln ! ( "QQ 下载安装失败" ) ;
161+ wait_exit ( 1 ) ;
162+ }
163+ println ! ( "QQ 安装完成,请重新运行程序" ) ;
164+ wait_exit ( 0 ) ;
165+ } else {
166+ eprintln ! ( "错误: 未找到 QQ,请安装 QQ 或使用 --qq-path 参数指定路径" ) ;
156167 wait_exit ( 1 ) ;
157168 }
158- println ! ( "QQ 安装完成,请重新运行程序" ) ;
159- wait_exit ( 0 ) ;
160- } else {
161- eprintln ! ( "错误: 未找到 QQ,请安装 QQ 或使用 --qq-path 参数指定路径" ) ;
162- wait_exit ( 1 ) ;
163169 }
170+ } else {
171+ eprintln ! ( "错误: 未找到 QQ,请安装 QQ 或使用 --qq-path 参数指定路径" ) ;
172+ eprintln ! ( "提示: 请将 QQ 安装到 /Applications/QQ.app 或放置到 bin/qq/QQ.app" ) ;
173+ wait_exit ( 1 ) ;
164174 }
165175 }
166- }
176+ qq_path
177+ } else {
178+ None
179+ } ;
167180
168181 migrate_old_files ( & exe_dir) ;
169182
@@ -214,6 +227,12 @@ fn main() {
214227 let mut cmd = Command :: new ( & pmhq_exe) ;
215228 cmd. arg ( "--port" ) . arg ( port. to_string ( ) ) ;
216229
230+ // 如果检测到 QQ 路径,传递给 pmhq
231+ if let Some ( ref qq_path) = detected_qq_path {
232+ println ! ( "检测到 QQ 路径: {}" , qq_path) ;
233+ cmd. arg ( format ! ( "--qq-path={}" , qq_path) ) ;
234+ }
235+
217236 if !args. is_empty ( ) {
218237 cmd. args ( & args) ;
219238 }
@@ -258,6 +277,26 @@ fn main() {
258277 } )
259278 . ok ( ) ;
260279
280+ // 处理 SIGHUP(终端关闭)和 SIGTERM,确保子进程被清理
281+ #[ cfg( unix) ]
282+ {
283+ use signal_hook:: consts:: { SIGHUP , SIGTERM } ;
284+ use signal_hook:: iterator:: Signals ;
285+
286+ let child_for_signal = child_arc. clone ( ) ;
287+ let mut signals = Signals :: new ( & [ SIGHUP , SIGTERM ] ) . expect ( "无法注册信号处理" ) ;
288+ thread:: spawn ( move || {
289+ for _sig in signals. forever ( ) {
290+ if let Ok ( mut guard) = child_for_signal. lock ( ) {
291+ if let Some ( ref mut c) = * guard {
292+ let _ = c. kill ( ) ;
293+ }
294+ }
295+ std:: process:: exit ( 0 ) ;
296+ }
297+ } ) ;
298+ }
299+
261300 let stdout = child. inner ( ) . stdout . take ( ) ;
262301 let stderr = child. inner ( ) . stderr . take ( ) ;
263302
@@ -485,7 +524,7 @@ fn wait_exit(code: i32) -> ! {
485524}
486525
487526#[ cfg( target_os = "windows" ) ]
488- fn get_qq_path_from_registry ( ) -> Option < String > {
527+ fn get_qq_path_from_registry ( _exe_dir : & Path ) -> Option < String > {
489528 use winreg:: enums:: * ;
490529 use winreg:: RegKey ;
491530
@@ -507,8 +546,25 @@ fn get_qq_path_from_registry() -> Option<String> {
507546 }
508547}
509548
510- #[ cfg( not( target_os = "windows" ) ) ]
511- fn get_qq_path_from_registry ( ) -> Option < String > {
549+ #[ cfg( target_os = "macos" ) ]
550+ fn get_qq_path_from_registry ( exe_dir : & Path ) -> Option < String > {
551+ // 优先检查当前目录的 bin/qq/QQ.app
552+ let local_qq = exe_dir. join ( "bin/qq/QQ.app/Contents/MacOS/QQ" ) ;
553+ if local_qq. exists ( ) {
554+ return Some ( local_qq. to_string_lossy ( ) . to_string ( ) ) ;
555+ }
556+
557+ // 其次检查系统 Applications 目录
558+ let system_qq = Path :: new ( "/Applications/QQ.app/Contents/MacOS/QQ" ) ;
559+ if system_qq. exists ( ) {
560+ return Some ( system_qq. to_string_lossy ( ) . to_string ( ) ) ;
561+ }
562+
563+ None
564+ }
565+
566+ #[ cfg( all( not( target_os = "windows" ) , not( target_os = "macos" ) ) ) ]
567+ fn get_qq_path_from_registry ( _exe_dir : & Path ) -> Option < String > {
512568 None
513569}
514570
0 commit comments