From 86389d0b28307e4fdc52abdbdc9d12d994c03848 Mon Sep 17 00:00:00 2001 From: lrs2187 Date: Sat, 31 Jan 2026 23:25:10 +0800 Subject: [PATCH 1/5] =?UTF-8?q?chore:=20=E6=8E=92=E9=99=A4=20uiaccess.dll?= =?UTF-8?q?=20=E7=9A=84=20stub=20=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/generate-stubs.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/generate-stubs.ps1 b/scripts/generate-stubs.ps1 index 52c80cfb..67913827 100644 --- a/scripts/generate-stubs.ps1 +++ b/scripts/generate-stubs.ps1 @@ -3,6 +3,7 @@ $SearchPath = "./data/dlls" $DestPath = "./typings" $dlls = Get-ChildItem -Path $SearchPath -Filter "*.dll" -Recurse | + Where-Object { $_.FullName -notlike "*uiaccess.dll" } ForEach-Object { $_.FullName } Write-Host "Found $($dlls.Count) DLL files" -ForegroundColor Green From 884acb7947ae89d972e17137fdc24e278fccbdf8 Mon Sep 17 00:00:00 2001 From: lrs2187 Date: Sat, 31 Jan 2026 23:26:45 +0800 Subject: [PATCH 2/5] =?UTF-8?q?dll:=20=E5=8D=87=E7=BA=A7=20SecRandom4Ci=20?= =?UTF-8?q?=E7=9A=84=20dll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 该 dll 还未 publish,但已有回滚逻辑 --- data/dlls/SecRandom4Ci.Interface.dll | Bin 9728 -> 12288 bytes data/dlls/SecRandom4Ci.Interface.pdb | Bin 18508 -> 21240 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/data/dlls/SecRandom4Ci.Interface.dll b/data/dlls/SecRandom4Ci.Interface.dll index 89d9768c2315d78390f63e84fe8b43a88c63182e..48e8faf904ad3295e4b59148da33117002a8fb3c 100644 GIT binary patch literal 12288 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 delta 4331 zcmZWs4R93Y8GgTS_xAQS$tAgvKMmn732;d;Tnzb9L5Xp|2r3v-N{f`_5-=DONwgIx zxl8d6D^9}d_*08Uq?I3AY_#=XBbBP1(#lw*Q|&Z59Y-Bwomxw))Ao7a+Z?s-%|81+ z@9+1$``x#@$@R(QBe!01VqNhm@{T`KSvW(*h)SWbQp)3ta1G;JjFTuwWKCoWJ$BvRR=E*9&t0SDIwxmB6~HAGg67c!9k!;OhPeXjQ3>mhm+&X3|BN4=lMn70a=V?FA@#x}f!M>r5C1k=Kc$ zqt#L@A=O|*C2Mdt+YHz^@!V8_ZP`5XqtPg+7Gm^QLOyGz9zr>@AMJFsv7O!Y5O=V@ z+KbFdMb48*CPx2RUL*z}kqHiElOE!3r$ci=P_#xunHc@^y-BcfU-B@0=)1hq9L%f{Qp;)3^v>s#7+n5;r z4UqYk@B*KXWQ!i+m6wX#;7w677H(&AwVs|y6bs#{YS7zw*%YL3Px*zt z{hi=^U=gU*g%4!}a0BUIs*X?^ONy{a2&tJ8)}?G2tZyPp(0T|=5KNdXVR|C-mG$Vl zTrmM0|1epH;nPOr1D{2o2)65A__E1Cmo0iu51AI7G_Ha*CiszN*%A2`!8=9sqzd^G z4n1frw=B9`61^bUqd7I{-M~VmwrGLQ@FTT)7OA&s#)CQpebf&5g7k^?tQn+}K!=X2 z<(5M(6$5VoTJ#t7fzP3K$RT>bK5m96+dOU-(Cu`XtOT7vYKO{g4)_A-(iWLV3vq!5 z%xVD@93_Lr+*2`mangSD1~?j^Q@8sMipY zO$Pc88VtOKQrXh#92&P@!+5jFMsN--vA6oSgE_+P7M4eOWS|7!iYswf&!7g{s1~aR zdfm@BX)`YMF-{TVh*%BLZ&VjS^SYmLGGX&&sgH4r7)QixK(A=CDgeIYzZm$Ty%Mw@)_FEO?d9rf+7uYxUg9QDP`M4!@heuNd1 zY9)-CwtB4A>{A9E5_WUZ0d&Zq$A$fp4*CaRGs`$GWiu%=#q4&~r%amRu{io<(h`q7 z>Aykw=rWJ}#{azpXwsvIj81KcE=Iz9GX3@t#LJa#*VmI%=O9{tpRpK|D7kNwBL2kbl>zCLm zVLPaRu2LCfRd6qMP$lhE{7Rr`1ka9Xd>A{0qUx_=;;Smra4;V}EWrRB@F~g#T2u^l zP~?CwhiV1S5o{K06i&mMuy85RH^q8XI09-)PF zAmNdhpM}1}&s4mI#Pr+WX z_KNi>(Od^yMiFdKw-^!n0VPI^*)&M&)Le?wD`q8aqj!u-`aZpB)KCV!tZMLIKL$LL zJ_450XTWOghc#43D}d+GmB1F-1Y9QiHo8n%oc4;-UOGs3n0rOP7q0i3`z2t%_)my_Li~@2{}J&&BKjlZ|El=E zD*ltApA`Rh#s6KI#`_6zdS9HB;=7_0x64r6E<7R`Efgf25W zMAIRfVUdSLzESZs9)!<2V@&j8qMs0XLM6D^q8+bSq2_OndD1=WFdv7 zprp$NYWdIeKRy6C56%kzjtt28@KxAwvLF}Yp`@rt9$OA}N*~hMcn~eZzh@=wr2FV; zIzgY4t+G`ydKgt^k~g9MJ?1IA3wk?^=xfw|H@6_K?bpKo&w`DKy|vgF8db48c)#p- z55L7==oU58P1H(H(51MNJ6v$c>hHR~xBL9@?-T~q_`aeG4EMs4Lbs$O!+qh*eD_x+ zUE_5#Ej_+@);i@DMe5yUkzV%?kyVlGR;-q0>ZKm~HXi*%t&g66+n#-=mOfkl`HVf! zf345Gv+SJ2H7b;2<%c%QC3lMomH5I+<&l-2o4i-)07yy-hRsm&hZ!?N$z7r3T|s<2 znfamQm@1{T&Tv!^xu6W1VcY}LuR;}mDE3KOtxAeAV@j(GQI(SEs6?p50o#uvTU0P- z+M42}7)2=gs0!jeP=q}4hqdN62_9sqL$EtjY=E0oD4dG0Q*(xmsBf(8ZtCic$2K(8H^w%^7Btnzx|`yi@%k=&4J3b}sCM_9 zusb#TXYQdnod({1-ORaP;0w87;d_&$E?uFq8isM6#3%U4Qnxf(V6DMN^_p4kxzVzm z{F|F^n0o%P=J7w~|4nD-ZgqR3E!p1q*7kK@*HjZ*yL(RIqHDW4sqNzCv+Enk3mKjc z;X)tI@A&k^7q28oITIO(uN8=ly+l6T? zfXtu(J`X|tln{i2eP)4YJWqQB!2TIf2i%aLg&8yl%EfT`n1zl8u%T2C6sZrenvXBs z+5GdnKQ6KQ>o@K!&EI#Bm^pK=c^XthR(z#27%T)KKv@cch!71ZhysxS!U_a-90h^~ z5&;AbNCAWv2*)1`4-9Sx#;|Ka?A;&oHw5LzKQ*xsBPhXr3j={U%s}u!i~+KRh)5^{ z6bc|DbQjopV5t!Zh#7%|On|iqwiDP9U=xuDC=ZE*>M0OVF9i~MLy3aEQ6ixiSQNC0 zMM74LD9D=;30=XVpcWhw8fHg9^Xy1SfExu7xRFpKFAB=$MMC|2C}@Tc2_}?wjE)G| zXoJE0<3|r=YSTknI`oh=5FZ`b$pD?(wHT;X2Lp8jc@N|h5WFr15&>ck#7-9pCFx>8 z8!Tvpg;qg%0|*|72oQ51c0dI5u#lJ@1!Sd1qydd-pzC@x(0d@Cfb7wyfrRu?kSTbY za9|gG2FMGDKafy;1Vjba30_DDN(6%ZH%tv-|MDvXKlm?;*pmpN|Z~e*E8<2*C~b!NmSGEf@>@-2j3Kf@B!>?q zUx*CDeqk~U`$fnw>=*rO8Nh<`gNl7%&Hpt3dVu%;8x|+SOu#QeGNIrm%4>ss+s#cl zM}Oxciw+zR&Rq-;1T?4%=Qo_Ybh|iRj{#UXC*giXz~;%si-1WU;1>a`G{G3qPa1v} z^!g6*1?Vm$8-fCQN`XgUAWt0vC^Jy0?3UGu2udg&ZwacfG{HbeGDZSNu}&lc3zg|y z1U19BYe0Wwp9NZvdjWWtbiROc4KEuK1mMFX;Tp$XUA(Iy3b;mPS4ZyZ{#^~Bc3bZ1 z;$6Lf+BKwgihO*v>4~7*nKv}sI`KLFi>BB0A@xcXq_0j@jP$IL&e>!dUkbX zO6*}$PK9Pz5r2ESVBW)wlrtPV>d6z9ir**KxQ`HM?YtX?v^Z`d*nEg~oSbJyvUw!) zE$sEPsXbYu!#9j+RI(%cXWtiR&91*d8EEa9Lt2q)rcnwP@y#DmW7^9+I#jAGy=JqB zeAI`WSv9)DlMsO_UyzBDnVU&9n0B` z{qN+%jJobF{xnjR{u;(je7wVEpx_v+i_1b|{As#P&AI%+lP>pB?#rbpCek6(bKn!jXNv*@g>aVwEKZ zZwH+&lAQAHI4s@I-KtvZNEr57pdcN`6x05GLUD$1L2;d}XlyGAAxkQxWG6ktP!s># zHuC^GhUL#@{F|8EfXi%rwJ*rLb1qx4I-n|$;(}IKxq2L)N)!CEk$>~_D*|Ku8e)gO zek%*A=@kvLUO6nu7Ho?;)uPF~VTwaYTyP`cYO=C>wK7GPOVVeoL`7|~+;oVUymm=$ zHo0>L6!Nz{HrzBm^$~xrZW{A_w~bhasFUO~o)rhIPm$*QW%8Xy#X=ZMu<4wEhR^(q zWIi(?(x?1ZqSu?~-qNqwO(gmC@tH0sduOot!~{v8r5`A4_XI>UswoF(j#c4ngl`e7 zWUG|L)?-CPPC*X_+D6bmrbUw8wKt_U>l;fSnK0GD9n` zhI_iE7i`s49rsS0cvwbTzG=qOv%T1+h`YKRP`k9H)^x14VHxk&p!h6Ti!9iXCD3ZK+j`Ho}{0uDSGt? zOUFWgP^h8}1H%itAsMsTfq^^6C%#&Q-k-2qJ%8~+3-iJ89UV7y_RJ;kcv@H4q{v=< zetbI`Rc>2UwNg{jXjDkj-D^U3)r;=JY$u6WqPs=%zw_fx(}y;r$Yn(L0iu9qsYG^| zm35iZGY3}B&BWYet{ji`K5|q#*~__8uL-fKv+HGYjF~45$W3_R+=o8!Q|WEa(MM^# zd}RFfcn4KXwzphz+11yUrFW{VV(AtS8^sTja_{nELhaRFi>wF|JU*Il zT_7oR{|iaR#$#NE#A`KKfMl92HvCk7&ef>>^gNSx^!lY6Md7P9rnRBHov&}y)z53N zXP>V}nb*GYZt)z5TxZmKdLGkfI=)<5=Q!kGx_`43XI&GRQ*WEp&1JTYA%<&L&wI!} zMj4KU*o!a4j5j)d=fX{!spub?(PH7h=Y!?hWbH@VkLFu;98@vq56@Jnd!8cEaJ+wj zxo1TD?TJ8jL{H3jF+9EOYYBmrSWOq{lqqc6gSEI;O9LIh<_L4(v>2gOW*z*hau&ZQ z3a?XGqveu^#yD|g+Q`%pX`#diYqw{&GKW8%yS!vAy>6H9ZltCX z*Jv5gP-V?MZ!#qmN;~hwhGpsVDH`w@{n?y4)FV~KXMB0^^H&Sw`frBb%SI>ORdD-x zN5*Q(4|sXUFCQOU218>Tx-eBdm)Ur}2 ze`sij`)n(TKlD4QqwJyL0++6;>x~C$Y4HT}vH`ur8Tp<5E3vi~D)Op=9W`kAmKUN7 zW&Wd5^R+CeVz6I?mL1l46kS=-=UDfw^1Dcka&crN+578u%^iYs&8Kb+ zhs9)t&GX*4a#+OZ7x?7)1=PNOy>m&A>2YN5JsA4NY5X9q9a+)1x_6}DLF_xs_ay{7DwBfUrO6y4(0j=Cb#uArThvbu6GuyxQIR6SG zr2M#$#^QbVV|z~Zk58Sx9HZ#f_w9U}T#$+^`-|yAY}xGugHw5>h8dBqD1LrLvjglb z$$rV}wCMZc7Jly-`S)Hvem3)3)LnM=feD!pr+y|8eWC|#Jof3A>(3OFydY>!d0$iE z9KIF%mVgz$sB*G!t?-W7TgOu@6RbuIr+)0^K8;L}8-LI!*M3QdQmpKu&$itSIX zL2EQZ!K=>aDl&H%_D7vH8c?ivKWT>bSD49CEcST%t}tqAh`3txed*b|j)8sMx*9`= zElWQ4aFi2GV&$6Nq^OU%DLGjlsXrAvb@|NsHNs5I;FjyF-s>(N+5%xdmw3IyO`9u1 zT$i>2<$ii@WKfnJ?dP0!c^<}cs4lblMOx*U#DY0}s+)2AJ?-p%He~Ef391IIKFf)+ zd8Wc>o8&F{poOEq*^yPPIxawZ4^b}o^f!ueudG#5VgW@@-u3#T>s(w0{x(8V$GMl2 zKOXM78ASs8aexM{A!o3auK z?LB^!R7-d4tD0HwznfooPV(%nUMPuCK4j5JO%{*uzIRW$5bm^1erE-3fE1yH6Cu#rLIzj-g)5 zcAI||)vF!wWyNPYKu@jWO5%`A9Aqy93C+hvUure-}!?DenS7q0h@o%0r&rq0}0N*-2cjf zH1ZrMBF}-@|0xHM==;n?{j+D;m+1=4`K_3*`u&VnrZAAEnSD$8HZNN zu|sUa8XauX%_z0yh~?$Hf9dk&3-9&)>|8$ z;#)Ym^YAS{jTSLdw!G@bCc)2A&}D$zAjht$hKFOkn6@laG)e-6u2ILBGR4=+qFZ{S z@NLXAAO+aSQsBU!6gZ_?K>XaD*IR$35DTY(;BZ4~>7HIg$pF0b1_A4AFZ7epE;RTh z^{p_rJwib77KSN6Y% z#`vq4>3XnvuP9nqKSe!R(XbRaV$b~ff&rb?6P}`iTTdvWY!b|ciDF|ywysaJQTx63 zIT-ejyQDBwxbJUbe)LXu=t0pt)SwbaI9?>hPq+LP&F>Vr{{h2j(*r8GWpd6wv**eG z*76O(Ta=<>dPa*JVu;qv%K7JW2FEFiRHkDq=i zjf)345OaHkkn?2Aj0E9(`-6s~*uZXe5i-3py)G{N_2c$SfjL z9UJR6+H>4CR}amV|P8qJcp}Rt|@I*Dpp8#x_&;VP(j}MvNY~MDK1|>S~+Nnb8ksk zKI^ySFO(t8r&XWUm8kjHiTPgS3{WjArF~9g@Z2)J*tAk2UHaM&jROU>2|I%OWrg3e zac=Xzy_6^({w|F7``DMA_=h3y4e9)?iybvwcUFm;)Un^TDH~ezFhLA)VU`Y2#;Ys<0nJQa{It1dCveB+muwtZHT@q&kQrpa^$hsbiM3_ia&@#H#Y zdjI?$`tOt7%6^wGKJ+~9s4VfYwI%G=)OX(U17iZ~=nV?Js_Z4^Wu-z?q3(Iq++;x5 z#p{8`748HtpC9J_^5fdkL+an07<;d;2Po<4eb&eMBNq=GPB1d@nWWVyds^FZIezt; zUE%VZO=8qY)#M3?q{A&nwtEWQaA8vxp;XNtlk}>j8TR%@wIVCwrl>6m@D-k#@$@v8 z3}f6{W+-*ae!+^_Tk9mbzzVl*rkuo5#?8vw(j;X>okO@AH@YFT#bG1!8}@-D&0c)Y zH!r27uMtnMxd3Qao_C1-b-FnUN&KVK(~7#trgq;Qy^mByx&9PaHP)IIOz zwiOt^gJ_fX+@I-Fs{ELJVWd*4xclwnVZL+ROESt`EyHn|jHY)U33je^_1NCaC>@V{ zRk7l==+Ul*=07ps7C|U8`TjE9N3{IlHQ&j{H(S-dow$05I(>!S>g4is!&j8_`eD{D z{DZpGygi6L7v!ra8QQJ}YkC>5H7!t7`yd*$jOP=^BgE;F{V1n0tExtw-k+J$89K^c zqr9z6-+!(#Ae5p zS=;HUevT=-nx&;DEqw!q$Ln8XjXdY=yBaL75fLP1UhzNwbi%KeqEb>2Z#M-c0zs1A z6DZ{_D}O-lfILCYi6GBnqrtgzWF<*mGm-z; zZA3qGYywtGu=)h6A3$l-!D`Pz(uyXJX#Osvd{>wLX76gy6MWc+pvNGf2qapO#HV$Z z_`h`t_gf092eA4KpHw1PKnIc0pa%$nJj)2qzY!duCJ>31gDb!(B{=zq5WJu+;7^?Z zd}~4XJG4C#%>%h1!O^id5+d?Ij&Kp?@gW!x;Aeu2yoHPsM@E$+;kyhhJx(0t8-j@r z0l6U2;97(NvOCxyUM1>2Gu3L@vg`M^!hMGftTXUYR# Z;D9?221D3zGn&I@ACn$z@XWf12zSnZj_gv?k>s8(1?X>6Z>OEpiTw-c0?hQj~>I2@2?f&qt_;D8S^0*GRU0}dDj5Qu>T#q0>6ksS_{av^|wTyS6rhX6j} z;J{lx1n`9q4!q$<01NzZ3b>0~dKkb}ADnadhXtVSogjL4<># zfVc^w6vRUiPYhtdv;hj_pa5e-6yOHJ8$>*a%Z6}(1|}DZRcpu!+%tp$EZ|n4JOF?n zK!H-Tw*g8I=HCQuki@dbR|0+19v?bC3^)S*J0O&9>>eNDv+nVsezrZn67?^*2uz7O z2^X=3xZGgw|B0mn`aFBM&{*6aAL8@w@u7acJ-!mvf=NUIVhQYtDggRI;F|xLW%vB4 z#RwsawmwuOVDau&>fc3z0@Dla7}zZ~7$9tj1#PI2~@xMsSla+ zso^X-A}khXNaTQEHbeJ-02^{}NWggo&tS9@48g|9FQH>diO+0tQ(&x{48f3&XFB8IhqNIFkllmH zStueZ_GcU{4jsoy)kAgvdZ zNvK$L2==bd{26x^3qH_yv+B$U`kYC@9bwX`mXEJq*S@^%e$$# z!m-&uyN4Zb$P|3b-BZNmtgE3{j`4%9BMEoYo40FL4#j9$XyiHEk@Yo0QYJ1<(cf{N zETRnLI~Sx`5a!h8bMgJmb`6gSZ^voWfw=^w7EI=2>UnBeT~WTH&4f|Lx!zQb=0-Qv_l@*NI?gW| zkjc6$WOCE1=PGOV#X$v!0wV=m1GD9nMpW>8=CePw$44s)k66wR&x=$lop@!e7#}xG zWOsUV*5Fmo*R|D!^X+!Ni$C ztb9)kqwM^6Qb!s7&Vv->UmQ z3i%F-1~=)F;0^kSttjqAaq{zl?Zkaf<3ChdD6FSa zHcYKOq!-dNX-_V52wEu48e6Bv6uZsyXE)BhozqD;aPWqk2dTk#QEK$;{tL6`ZpT#L zmgto1WllJ%;`F6#b?{n^ziVaPO!=bF72%khSh>jbgnqwmg%AARhWo#>MN|#EL&V>k zzVTUAhs`B=oL=H-XE1Q(a`Z@tv=ujHwy^Zjfd|>E7f;RA^2s=c&pcW_9T1!*GEzp4 z98b%%|1zR1I~3Z;^>k&_VtIl1tKvnpb-X*r)9$O$iy^ZG#vL>7yhuNAmNRiTW5x7e zR_Y5Ip&pp9jVX3{U@xWA$BBgs%HsR!{Own`c?<(`HWm4!#5Iba74oRaowzL@M=2O6 zeDmCaZ8G)j35i2aLiWapB^w{BGJd(7$0e4X_JNz66Fi+lf(_f5Yy8RGrmLJ}zOBj4( zN6;T@^BbHkgY>+S^LERD&-%p6|LU~%i1M<3(R1qZx$}Bn`?_`3!u`*l5FcOkRr@*Z z{E>;M4O9e$Eq=Y7vY;DV7Iq)Kg3HUhk3D44Xhmwi*Cn#tUW;`o9}2|w$`xti!`8

VB}QafzE?Rp&6oz^bnP zcU2>t?Rf>CJM~r02rLdXUbdg>X`aWg^BzPhA}-~#h^vQ_`&U*qr`G#!xwhS~xQ`QP z(NJGNkd?kFkPYB_YpCTqo3a3@e<4?Iq{k6exVFG+|#iMcw@hL;~x7m19Ww_5~iqmF; z?wTptbfc?OMEefdb(EPPju9VXJZ8k*6%<$!y(dO~U>{I$m#+*MjquwaGI@47C3-L* zuBk9FXFd$2 z<6C-(&Ki!cLbT7X4BSRvp_=Xp+)pJ8Bx`+fT(c|a5J0SS-kZJ8#yAwUXn1nS?0YP>CZBae!N!pAKJ+FG7;&v z5P9eGV|X5h?W(=1`OLFVjDRbMt}N5utB1RLFxJWakR2%8u3A`eyX?fqu6}5 z@^|qLw=&UOd+uu6$k>rWuE~?7)>b4F;!y+Ho$GGjXs1XGP9#(5Y({x(o+f+FgR{(h z6^ES4>$qPod{4+!)=S8;W+U4AjEcmK>MAZCSn2LRN{n-@r?`<7niuar+h1B{SI!)Iy5gzvwsN9Yv;Ay`{f8Zd$Ik6*}qml ze$S_Wn*P!v_!@R$VbYh;%fLR@Df_}P-0)e-nFMb0GXRei}e zorAMuwx5UU@Z-gQJf^PKUTvtURYucVM(r1`%&h9}^l7Zt+`ILF*N@#vJ5izBH`g(X zl=@h!|Dq8^#h8I(m49HAn4~p3mF9wOsOUeMsbw5$&O7X@%SW(g@8=<#R;!wPEA~6% zx-c~4Znn(FBD2rWa=9{kW4J%5L}n~i`A0W>bVOAM05;2RB)`DqjH?+-IuTC~q{Y;& zS$lkzdGp#jc~&sbXN-d~9^5*(;O_N?{=;IhiY<&nuXJiFsk_VGAkLlj8Jja2ztQ6E ze?~zkw}kr|ZKyLKSGdxAfZ+Mdl|C&bj9K=4lppar&VgQO$NsFQjIUJzKRkB1VqJdB zsadq#hVPbJsAEen#d~g;b)fxO&7iz0N9P;j5%#vERYJ=1$VnF@?x9}LF^h<=TTItm zD6#z>3hxacRSil@%XWn3@ie$I^*H$^sP~MJo+t(z$P$^ngFdx4MLUGluV3}1)DCQU zpYT5Z>12uo%T9&Td{F6I7#o&h%~@SisvkCZrE~SgyDb`p`=`*-t4V77cdJW5A5$=-3*;zvguuusziGzKkxKHI3(_1%G+y%b3`Yd>7D@^JIp_VU!NHmuZo zDr!b;Te#P6`lR)_+#B^-7|Igvw7jNP=w(6qaNN}03t97)kBWo}#M@Zpk8Acx$TpZn zatMz;M%k@Ysc#hoF6iXe6n^pwi3=n*%>~nkLHgIqFEq7xufQk-{Eab`7PifO_45jbOabkLqz;?dFZC#iI)5SR*8Tv`Pg^!K+q)m55`v@t$ztZ!?~*pz0M;FkrjBe66bngfWf zM**Ou?aErJjO8Uey=Sm?K<_0amLRbS3VkL>@IZpFJGf+baP97}l3iK7$1dNsZ=%54 z9RNhJvuRQJtS(UgTVN=99wd4pG0y^y4d!9vfi9nHfHMc15a0#}Z(}g{1*i+djuQlx zCpQ-l5P?Er0UkJbwF+ke=Y%27K@2Ve4!WzyHcNw)*tioANf07Y_K+}IyJ6f8|Hm+# zRygoQ1o+xOQDUJW0#J~c-$AG_Yu*24YX+Opa^1N8<2ca4KFlJ#GbVx sHFp^ Date: Sat, 31 Jan 2026 23:27:46 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20C#=20IPC=20?= =?UTF-8?q?=E5=92=8C=E6=8F=90=E9=86=92=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/IPC_URL/csharp_ipc_handler.py | 127 ++++++++++++------ .../notification/notification_service.py | 1 + 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/app/common/IPC_URL/csharp_ipc_handler.py b/app/common/IPC_URL/csharp_ipc_handler.py index 31dea418..4e5abf64 100644 --- a/app/common/IPC_URL/csharp_ipc_handler.py +++ b/app/common/IPC_URL/csharp_ipc_handler.py @@ -23,15 +23,16 @@ clr.AddReference("ClassIsland.Shared.IPC") clr.AddReference("SecRandom4Ci.Interface") - from System import Action, DateTime + from System import Action, DateTime, Version from ClassIsland.Shared.Enums import TimeState from ClassIsland.Shared.IPC import IpcClient, IpcRoutedNotifyIds from ClassIsland.Shared.IPC.Abstractions.Services import IPublicLessonsService from dotnetCampus.Ipc.CompilerServices.GeneratedProxies import ( GeneratedIpcFactory, ) + from SecRandom4Ci.Interface.Enums import ResultType + from SecRandom4Ci.Interface.Models import CallResult, NotificationData, Student from SecRandom4Ci.Interface.Services import ISecRandomService - from SecRandom4Ci.Interface.Models import CallResult, Student CSHARP_AVAILABLE = True except Exception as e: @@ -68,7 +69,7 @@ def __init__(self): self.loop: Optional[asyncio.AbstractEventLoop] = None self.is_running = False self.is_connected = False - self._disconnect_logged = False # 跟踪是否已记录断连日志 + self._no_plugin_logged = False self._last_on_class_left_log_time = 0 # 上次记录距离上课时间的时间 self._last_known_subject_name: Optional[str] = None @@ -120,6 +121,7 @@ def send_notification( draw_count=1, settings=None, settings_group=None, + is_animating=False ) -> bool: """发送提醒""" if not self.is_running: @@ -134,17 +136,60 @@ def send_notification( display_duration = 5 logger.debug( - f"发送通知到 ClassIsland: 班级={class_name}, 选中学生={selected_students}, 抽取数量={draw_count}, 显示时长={display_duration}" + f"发送通知到 ClassIsland: 班级={class_name}, 选中学生={selected_students}, 抽取数量={draw_count}, 显示时长={display_duration}, 设置组={settings_group}, 是否动画={is_animating}" ) randomService = GeneratedIpcFactory.CreateIpcProxy[ISecRandomService]( self.ipc_client.Provider, self.ipc_client.PeerProxy ) - result = self.convert_to_call_result( - class_name, selected_students, draw_count, display_duration - ) - randomService.NotifyResult(result) + try: + plugin_version = randomService.GetPluginVersion() + except: + plugin_version = Version.Parse("0.0.0.0") + + logger.debug(f"插件版本为 {plugin_version}") + if plugin_version < Version.Parse("1.2.0.0"): + logger.warning("检测到旧版插件 (小于 1.2.0.0),请尽快升级!") + + result = CallResult() + result.ClassName = class_name + result.DrawCount = draw_count + result.DisplayDuration = display_duration + for student in selected_students: + cs_student = Student() + cs_student.StudentId = student[0] + cs_student.StudentName = student[1] + cs_student.Exists = student[2] + result.SelectedStudents.Add(cs_student) + randomService.NotifyResult(result) + + return True + + if "roll_call" in settings_group: + notification_type = [ResultType.PartialRollCall, ResultType.FinishedRollCall][not is_animating] + elif "quick_draw" in settings_group: + notification_type = [ResultType.PartialQuickDraw, ResultType.FinishedQuickDraw][not is_animating] + elif "lottery" in settings_group: + notification_type = [ResultType.PartialLottery, ResultType.FinishedLottery][not is_animating] + else: + notification_type = ResultType.Unknown + + logger.debug(f"通知类型: {notification_type}") + + data = NotificationData() + data.ResultType = notification_type + data.ClassName = class_name + data.DrawCount = draw_count + data.DisplayDuration = display_duration + for student in selected_students: + cs_student = Student() + cs_student.StudentId = student[0] + cs_student.StudentName = student[1] + cs_student.Exists = student[2] + data.Items.Add(cs_student) + + randomService.ShowNotification(data) return True def is_breaking(self) -> bool: @@ -307,22 +352,6 @@ def get_elapsed_since_previous_time_point_end_seconds(self) -> int: except Exception: return 0 - @staticmethod - def convert_to_call_result( - class_name: str, selected_students, draw_count: int, display_duration=5.0 - ) -> CallResult: - result = CallResult() - result.ClassName = class_name - result.DrawCount = draw_count - result.DisplayDuration = display_duration - for student in selected_students: - cs_student = Student() - cs_student.StudentId = student[0] - cs_student.StudentName = student[1] - cs_student.Exists = student[2] - result.SelectedStudents.Add(cs_student) - return result - def _on_class_test(self): lessonSc = GeneratedIpcFactory.CreateIpcProxy[IPublicLessonsService]( self.ipc_client.Provider, self.ipc_client.PeerProxy @@ -353,22 +382,28 @@ async def client(): task = self.ipc_client.Connect() await self.loop.run_in_executor(None, lambda: task.Wait()) self.is_connected = True + logger.debug("C# IPC 连接成功!") while self.is_running: await asyncio.sleep(1) - if not self._check_alive(): - if not self._disconnect_logged: + # logger.debug(f"stat: plugin({self._check_plugin_alive()}) ci({self._check_ci_alive()})") + if not self._check_plugin_alive(): + if not self._check_ci_alive(): logger.debug("C# IPC 断连!重连...") - self._disconnect_logged = True - self.is_connected = False - - task = self.ipc_client.Connect() - await self.loop.run_in_executor( - None, lambda task=task: task.Wait() - ) - self.is_connected = True - self._disconnect_logged = False + self.is_connected = False + + task = self.ipc_client.Connect() + await self.loop.run_in_executor( + None, lambda task=task: task.Wait() + ) + self.is_connected = True + logger.debug("C# IPC 连接成功!") + elif not self._no_plugin_logged: + logger.debug("未安装 SecRandom-Ci 插件。") + self._no_plugin_logged = True + else: + self._no_plugin_logged = False self.ipc_client = None self.is_connected = False @@ -386,8 +421,19 @@ async def client(): self.loop.close() self.loop = None - def _check_alive(self) -> bool: - """客户端是否正常连接""" + def _check_ci_alive(self) -> bool: + """ClassIsland 是否正常连接""" + try: + lessonsService = GeneratedIpcFactory.CreateIpcProxy[IPublicLessonsService]( + self.ipc_client.Provider, self.ipc_client.PeerProxy + ) + return lessonsService.IsTimerRunning + except Exception as e: + logger.debug(e) + return False + + def _check_plugin_alive(self) -> bool: + """SecRandom-Ci 插件是否正常连接""" try: randomService = GeneratedIpcFactory.CreateIpcProxy[ISecRandomService]( self.ipc_client.Provider, self.ipc_client.PeerProxy @@ -444,6 +490,7 @@ def send_notification( draw_count=1, settings=None, settings_group=None, + is_animating=False ) -> bool: """发送提醒""" return False @@ -484,12 +531,6 @@ def get_previous_class_info(self) -> dict: def get_elapsed_since_previous_time_point_end_seconds(self) -> int: return 0 - @staticmethod - def convert_to_call_result( - class_name: str, selected_students, draw_count: int, display_duration=5.0 - ) -> object: - return object - def _on_class_test(self): pass diff --git a/app/common/notification/notification_service.py b/app/common/notification/notification_service.py index 2c493ed5..93c616f0 100644 --- a/app/common/notification/notification_service.py +++ b/app/common/notification/notification_service.py @@ -1031,6 +1031,7 @@ def _normalize_text(value): draw_count, settings, settings_group, + is_animating ) if status: logger.info("成功发送通知到ClassIsland,结果未知") From 821c9ba3bce0cb411a8fc0721bdc316e17014ee8 Mon Sep 17 00:00:00 2001 From: lrs2187 Date: Sun, 1 Feb 2026 00:06:57 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E6=8F=90=E9=86=92=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=AE=89=E8=A3=85=20SecRandom-Ci=20=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG/v2.3.0-beta.2/CHANGELOG.md | 2 +- app/Language/modules/notification_settings.py | 72 +++++++++++++++++ app/common/IPC_URL/csharp_ipc_handler.py | 19 +++-- .../lottery_notification_settings.py | 81 ++++++++++++++----- .../quick_draw_notification_settings.py | 81 ++++++++++++++----- .../roll_call_notification_settings.py | 81 ++++++++++++++----- 6 files changed, 273 insertions(+), 63 deletions(-) diff --git a/CHANGELOG/v2.3.0-beta.2/CHANGELOG.md b/CHANGELOG/v2.3.0-beta.2/CHANGELOG.md index 59903e0d..ff58596c 100644 --- a/CHANGELOG/v2.3.0-beta.2/CHANGELOG.md +++ b/CHANGELOG/v2.3.0-beta.2/CHANGELOG.md @@ -8,7 +8,7 @@ v2.3 - Shiroko (砂狼白子) beta 2 ## 💡 功能优化 -- 无 +- 优化 **ClassIsland 联动**,现在可以传递通知类型,并提醒用户安装插件。 ## 🐛 修复问题 diff --git a/app/Language/modules/notification_settings.py b/app/Language/modules/notification_settings.py index a1f8f308..a8ebe750 100644 --- a/app/Language/modules/notification_settings.py +++ b/app/Language/modules/notification_settings.py @@ -129,6 +129,14 @@ "title": "ClassIsland通知服务", "content": "请确保已安装.NET 8运行时,并在ClassIsland中安装SecRandom-Ci插件", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland通知服务", + "content": "检测到未安装插件,请在ClassIsland中安装SecRandom-Ci插件", + }, + "classisland_configured_successfully": { + "title": "ClassIsland通知服务", + "content": "检测到ClassIsland和SecRandom-Ci插件正常运行,欢迎使用", + }, }, "EN_US": { "title": { @@ -219,6 +227,14 @@ "title": "ClassIsland Notification Service", "content": "Please ensure .NET 8 runtime is installed and SecRandom-Ci plugin is installed in ClassIsland", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland Notification Service", + "content": "Plugin not detected, please install SecRandom-Ci plugin in ClassIsland", + }, + "classisland_configured_successfully": { + "title": "ClassIsland Notification Service", + "content": "Detected ClassIsland and SecRandom-Ci plugin running properly, welcome to use", + }, }, "JA_JP": { "title": { @@ -313,6 +329,14 @@ "title": "ClassIsland通知サービス", "content": ".NET 8ランタイムがインストールされ、ClassIslandにSecRandom-Ciプラグインがインストールされていることを確認してください", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland通知サービス", + "content": "プラグインがインストールされていないことを検出しました、ClassIslandにSecRandom-Ciプラグインをインストールしてください", + }, + "classisland_configured_successfully": { + "title": "ClassIsland通知サービス", + "content": "ClassIslandとSecRandom-Ciプラグインが正常に動作していることを検出しました、ご利用いただきありがとうございます", + }, }, } @@ -388,6 +412,14 @@ "title": "ClassIsland通知服务", "content": "请确保已安装.NET 8运行时,并在ClassIsland中安装SecRandom-Ci插件", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland通知服务", + "content": "检测到未安装插件,请在ClassIsland中安装SecRandom-Ci插件", + }, + "classisland_configured_successfully": { + "title": "ClassIsland通知服务", + "content": "检测到ClassIsland和SecRandom-Ci插件正常运行,欢迎使用", + }, }, "EN_US": { "title": { @@ -462,6 +494,14 @@ "title": "ClassIsland Notification Service", "content": "Please ensure .NET 8 runtime is installed and SecRandom-Ci plugin is installed in ClassIsland", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland Notification Service", + "content": "Plugin not detected, please install SecRandom-Ci plugin in ClassIsland", + }, + "classisland_configured_successfully": { + "title": "ClassIsland Notification Service", + "content": "Detected ClassIsland and SecRandom-Ci plugin running properly, welcome to use", + }, }, "JA_JP": { "title": { @@ -537,6 +577,14 @@ "title": "ClassIsland通知サービス", "content": ".NET 8ランタイムがインストールされ、ClassIslandにSecRandom-Ciプラグインがインストールされていることを確認してください", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland通知サービス", + "content": "プラグインがインストールされていないことを検出しました、ClassIslandにSecRandom-Ciプラグインをインストールしてください", + }, + "classisland_configured_successfully": { + "title": "ClassIsland通知サービス", + "content": "ClassIslandとSecRandom-Ciプラグインが正常に動作していることを検出しました、ご利用いただきありがとうございます", + }, }, } @@ -630,6 +678,14 @@ "title": "ClassIsland通知服务", "content": "请确保已安装.NET 8运行时,并在ClassIsland中安装SecRandom-Ci插件", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland通知服务", + "content": "检测到未安装插件,请在ClassIsland中安装SecRandom-Ci插件", + }, + "classisland_configured_successfully": { + "title": "ClassIsland通知服务", + "content": "检测到ClassIsland和SecRandom-Ci插件正常运行,欢迎使用", + }, }, "EN_US": { "title": { @@ -716,6 +772,14 @@ "title": "ClassIsland Notification Service", "content": "Please ensure .NET 8 runtime is installed and SecRandom-Ci plugin is installed in ClassIsland", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland Notification Service", + "content": "Plugin not detected, please install SecRandom-Ci plugin in ClassIsland", + }, + "classisland_configured_successfully": { + "title": "ClassIsland Notification Service", + "content": "Detected ClassIsland and SecRandom-Ci plugin running properly, welcome to use", + }, }, "JA_JP": { "title": { @@ -805,5 +869,13 @@ "title": "ClassIsland通知サービス", "content": ".NET 8ランタイムがインストールされ、ClassIslandにSecRandom-Ciプラグインがインストールされていることを確認してください", }, + "classisland_plugin_notification_hint": { + "title": "ClassIsland通知サービス", + "content": "プラグインがインストールされていないことを検出しました、ClassIslandにSecRandom-Ciプラグインをインストールしてください", + }, + "classisland_configured_successfully": { + "title": "ClassIsland通知サービス", + "content": "ClassIslandとSecRandom-Ciプラグインが正常に動作していることを検出しました、ご利用いただきありがとうございます", + }, }, } diff --git a/app/common/IPC_URL/csharp_ipc_handler.py b/app/common/IPC_URL/csharp_ipc_handler.py index 4e5abf64..363d4da2 100644 --- a/app/common/IPC_URL/csharp_ipc_handler.py +++ b/app/common/IPC_URL/csharp_ipc_handler.py @@ -3,6 +3,7 @@ import threading from typing import Optional from loguru import logger +from PySide6.QtCore import QObject, Signal from app.tools.path_utils import get_data_path @@ -42,7 +43,7 @@ if CSHARP_AVAILABLE: - class CSharpIPCHandler: + class CSharpIPCHandler(QObject): """C# dotnetCampus.Ipc 处理器,用于连接 ClassIsland 实例""" _instance: Optional["CSharpIPCHandler"] = None @@ -388,8 +389,8 @@ async def client(): await asyncio.sleep(1) # logger.debug(f"stat: plugin({self._check_plugin_alive()}) ci({self._check_ci_alive()})") - if not self._check_plugin_alive(): - if not self._check_ci_alive(): + if not self.check_plugin_alive(): + if not self.check_ci_alive(): logger.debug("C# IPC 断连!重连...") self.is_connected = False @@ -421,7 +422,7 @@ async def client(): self.loop.close() self.loop = None - def _check_ci_alive(self) -> bool: + def check_ci_alive(self) -> bool: """ClassIsland 是否正常连接""" try: lessonsService = GeneratedIpcFactory.CreateIpcProxy[IPublicLessonsService]( @@ -432,7 +433,7 @@ def _check_ci_alive(self) -> bool: logger.debug(e) return False - def _check_plugin_alive(self) -> bool: + def check_plugin_alive(self) -> bool: """SecRandom-Ci 插件是否正常连接""" try: randomService = GeneratedIpcFactory.CreateIpcProxy[ISecRandomService]( @@ -537,3 +538,11 @@ def _on_class_test(self): def _run_client(self): """运行 C# IPC 客户端""" pass + + def check_ci_alive(self) -> bool: + """ClassIsland 是否正常连接""" + return False + + def check_plugin_alive(self) -> bool: + """SecRandom-Ci 插件是否正常连接""" + return False diff --git a/app/view/settings/notification_settings/lottery_notification_settings.py b/app/view/settings/notification_settings/lottery_notification_settings.py index 06ebdd18..c62f3ab4 100644 --- a/app/view/settings/notification_settings/lottery_notification_settings.py +++ b/app/view/settings/notification_settings/lottery_notification_settings.py @@ -8,6 +8,7 @@ from PySide6.QtNetwork import * from qfluentwidgets import * +from app.common.IPC_URL.csharp_ipc_handler import CSharpIPCHandler from app.tools.variable import * from app.tools.path_utils import * from app.tools.personalised import * @@ -213,25 +214,67 @@ def _on_notification_service_type_changed(self, index): index, ) if index == 1 or index == 2: - hint_title = get_any_position_value_async( - "lottery_notification_settings", - "classisland_notification_hint", - "title", - ) - hint_content = get_any_position_value_async( - "lottery_notification_settings", - "classisland_notification_hint", - "content", - ) - InfoBar.success( - title=hint_title, - content=hint_content, - orient=Qt.Horizontal, - isClosable=True, - position=InfoBarPosition.TOP, - duration=5000, - parent=self, - ) + service = CSharpIPCHandler.instance() + if not service.check_ci_alive(): + hint_title = get_any_position_value_async( + "lottery_notification_settings", + "classisland_notification_hint", + "title", + ) + hint_content = get_any_position_value_async( + "lottery_notification_settings", + "classisland_notification_hint", + "content", + ) + InfoBar.success( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) + elif not service.check_plugin_alive(): + hint_title = get_any_position_value_async( + "lottery_notification_settings", + "classisland_plugin_notification_hint", + "title", + ) + hint_content = get_any_position_value_async( + "lottery_notification_settings", + "classisland_plugin_notification_hint", + "content", + ) + InfoBar.warning( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) + else: + hint_title = get_any_position_value_async( + "lottery_notification_settings", + "classisland_configured_successfully", + "title", + ) + hint_content = get_any_position_value_async( + "lottery_notification_settings", + "classisland_configured_successfully", + "content", + ) + InfoBar.success( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) class floating_window_settings(GroupHeaderCardWidget): diff --git a/app/view/settings/notification_settings/quick_draw_notification_settings.py b/app/view/settings/notification_settings/quick_draw_notification_settings.py index d0f5f581..00bc7dd9 100644 --- a/app/view/settings/notification_settings/quick_draw_notification_settings.py +++ b/app/view/settings/notification_settings/quick_draw_notification_settings.py @@ -8,6 +8,7 @@ from PySide6.QtNetwork import * from qfluentwidgets import * +from app.common.IPC_URL.csharp_ipc_handler import CSharpIPCHandler from app.tools.variable import * from app.tools.path_utils import * from app.tools.personalised import * @@ -113,25 +114,67 @@ def _on_notification_service_type_changed(self, index): index, ) if index == 1 or index == 2: - hint_title = get_any_position_value_async( - "quick_draw_notification_settings", - "classisland_notification_hint", - "title", - ) - hint_content = get_any_position_value_async( - "quick_draw_notification_settings", - "classisland_notification_hint", - "content", - ) - InfoBar.success( - title=hint_title, - content=hint_content, - orient=Qt.Horizontal, - isClosable=True, - position=InfoBarPosition.TOP, - duration=5000, - parent=self, - ) + service = CSharpIPCHandler.instance() + if not service.check_ci_alive(): + hint_title = get_any_position_value_async( + "quick_draw_notification_settings", + "classisland_notification_hint", + "title", + ) + hint_content = get_any_position_value_async( + "quick_draw_notification_settings", + "classisland_notification_hint", + "content", + ) + InfoBar.success( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) + elif not service.check_plugin_alive(): + hint_title = get_any_position_value_async( + "quick_draw_notification_settings", + "classisland_plugin_notification_hint", + "title", + ) + hint_content = get_any_position_value_async( + "quick_draw_notification_settings", + "classisland_plugin_notification_hint", + "content", + ) + InfoBar.warning( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) + else: + hint_title = get_any_position_value_async( + "quick_draw_notification_settings", + "classisland_configured_successfully", + "title", + ) + hint_content = get_any_position_value_async( + "quick_draw_notification_settings", + "classisland_configured_successfully", + "content", + ) + InfoBar.success( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) class floating_window_settings(GroupHeaderCardWidget): diff --git a/app/view/settings/notification_settings/roll_call_notification_settings.py b/app/view/settings/notification_settings/roll_call_notification_settings.py index 02a9a38d..ce60bf2b 100644 --- a/app/view/settings/notification_settings/roll_call_notification_settings.py +++ b/app/view/settings/notification_settings/roll_call_notification_settings.py @@ -8,6 +8,7 @@ from PySide6.QtNetwork import * from qfluentwidgets import * +from app.common.IPC_URL.csharp_ipc_handler import CSharpIPCHandler from app.tools.variable import * from app.tools.path_utils import * from app.tools.personalised import * @@ -219,25 +220,67 @@ def _on_notification_service_type_changed(self, index): index, ) if index == 1 or index == 2: - hint_title = get_any_position_value_async( - "roll_call_notification_settings", - "classisland_notification_hint", - "title", - ) - hint_content = get_any_position_value_async( - "roll_call_notification_settings", - "classisland_notification_hint", - "content", - ) - InfoBar.success( - title=hint_title, - content=hint_content, - orient=Qt.Horizontal, - isClosable=True, - position=InfoBarPosition.TOP, - duration=5000, - parent=self, - ) + service = CSharpIPCHandler.instance() + if not service.check_ci_alive(): + hint_title = get_any_position_value_async( + "roll_call_notification_settings", + "classisland_notification_hint", + "title", + ) + hint_content = get_any_position_value_async( + "roll_call_notification_settings", + "classisland_notification_hint", + "content", + ) + InfoBar.success( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) + elif not service.check_plugin_alive(): + hint_title = get_any_position_value_async( + "roll_call_notification_settings", + "classisland_plugin_notification_hint", + "title", + ) + hint_content = get_any_position_value_async( + "roll_call_notification_settings", + "classisland_plugin_notification_hint", + "content", + ) + InfoBar.warning( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) + else: + hint_title = get_any_position_value_async( + "roll_call_notification_settings", + "classisland_configured_successfully", + "title", + ) + hint_content = get_any_position_value_async( + "roll_call_notification_settings", + "classisland_configured_successfully", + "content", + ) + InfoBar.success( + title=hint_title, + content=hint_content, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.TOP, + duration=5000, + parent=self, + ) class floating_window_settings(GroupHeaderCardWidget): From 69884fb3fafd3ea55f0ded56e754df16dfaa12b7 Mon Sep 17 00:00:00 2001 From: lrs2187 Date: Sun, 1 Feb 2026 00:31:02 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E8=BF=90=E8=A1=8C=20pre-commit=20?= =?UTF-8?q?=E9=92=A9=E5=AD=90=EF=BC=8C=E8=A7=A3=E5=86=B3=20codefactor?= =?UTF-8?q?=EF=BC=8C=E5=B9=B2=E6=8E=89=20seer=20=E6=8F=90=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/IPC_URL/csharp_ipc_handler.py | 40 +++++++++++++++--------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/app/common/IPC_URL/csharp_ipc_handler.py b/app/common/IPC_URL/csharp_ipc_handler.py index 363d4da2..7bd9260a 100644 --- a/app/common/IPC_URL/csharp_ipc_handler.py +++ b/app/common/IPC_URL/csharp_ipc_handler.py @@ -3,7 +3,6 @@ import threading from typing import Optional from loguru import logger -from PySide6.QtCore import QObject, Signal from app.tools.path_utils import get_data_path @@ -43,7 +42,7 @@ if CSHARP_AVAILABLE: - class CSharpIPCHandler(QObject): + class CSharpIPCHandler: """C# dotnetCampus.Ipc 处理器,用于连接 ClassIsland 实例""" _instance: Optional["CSharpIPCHandler"] = None @@ -122,7 +121,7 @@ def send_notification( draw_count=1, settings=None, settings_group=None, - is_animating=False + is_animating=False, ) -> bool: """发送提醒""" if not self.is_running: @@ -146,8 +145,8 @@ def send_notification( try: plugin_version = randomService.GetPluginVersion() - except: - plugin_version = Version.Parse("0.0.0.0") + except Exception as e: + plugin_version = Version.Parse("0.0.0.1") logger.debug(f"插件版本为 {plugin_version}") if plugin_version < Version.Parse("1.2.0.0"): @@ -167,15 +166,26 @@ def send_notification( return True - if "roll_call" in settings_group: - notification_type = [ResultType.PartialRollCall, ResultType.FinishedRollCall][not is_animating] + if settings_group is None: + notification_type = ResultType.Unknown + elif "roll_call" in settings_group: + notification_type = [ + ResultType.PartialRollCall, + ResultType.FinishedRollCall, + ][not is_animating] elif "quick_draw" in settings_group: - notification_type = [ResultType.PartialQuickDraw, ResultType.FinishedQuickDraw][not is_animating] + notification_type = [ + ResultType.PartialQuickDraw, + ResultType.FinishedQuickDraw, + ][not is_animating] elif "lottery" in settings_group: - notification_type = [ResultType.PartialLottery, ResultType.FinishedLottery][not is_animating] + notification_type = [ + ResultType.PartialLottery, + ResultType.FinishedLottery, + ][not is_animating] else: notification_type = ResultType.Unknown - + logger.debug(f"通知类型: {notification_type}") data = NotificationData() @@ -189,7 +199,7 @@ def send_notification( cs_student.StudentName = student[1] cs_student.Exists = student[2] data.Items.Add(cs_student) - + randomService.ShowNotification(data) return True @@ -425,9 +435,9 @@ async def client(): def check_ci_alive(self) -> bool: """ClassIsland 是否正常连接""" try: - lessonsService = GeneratedIpcFactory.CreateIpcProxy[IPublicLessonsService]( - self.ipc_client.Provider, self.ipc_client.PeerProxy - ) + lessonsService = GeneratedIpcFactory.CreateIpcProxy[ + IPublicLessonsService + ](self.ipc_client.Provider, self.ipc_client.PeerProxy) return lessonsService.IsTimerRunning except Exception as e: logger.debug(e) @@ -491,7 +501,7 @@ def send_notification( draw_count=1, settings=None, settings_group=None, - is_animating=False + is_animating=False, ) -> bool: """发送提醒""" return False