这是示例的关于页面。
"); + Web!.CoreWebView2.Navigate(html); + } + } + catch { /* ignore */ } + } + private string BuildInjectedScript() + { + var hideScroll = _config.注入设置?.隐藏网页滚动条 == true; + var menuEnabled = _config.注入设置?.自定义右键菜单 == true; + var interceptEnabled = _config.注入设置?.拦截下载链接 == true; + + var css = hideScroll ? @"/* 隐藏所有滚动条 */ +::-webkit-scrollbar { width:0px; height:0px; background:transparent; } +html { scrollbar-width: none; } +body { -ms-overflow-style: none; } +* { scrollbar-width: none; -ms-overflow-style: none; } +*::-webkit-scrollbar { width:0px; height:0px; background:transparent; }" : string.Empty; + + var sb = new StringBuilder(); + sb.AppendLine("(() => {"); + sb.AppendLine(" function setup(){"); + sb.AppendLine(" try {"); + + if (!string.IsNullOrEmpty(css)) + { + sb.AppendLine(" try { var style=document.createElement('style'); style.textContent=`" + css.Replace("`", "\\`") + "`; (document.head||document.documentElement).appendChild(style); } catch(e){ console.warn('样式注入失败', e);} "); + } + + if (menuEnabled) + { + sb.AppendLine(@" try { + const oldMenu = document.getElementById('custom-context-menu'); if (oldMenu) oldMenu.remove(); + const m = document.createElement('div'); + m.id = 'custom-context-menu'; + m.style.cssText = 'position:fixed;background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);padding:8px 0;z-index:10000;display:none;min-width:120px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px'; + function item(t,fn){ const b=document.createElement('button'); b.textContent=t; b.style.cssText='padding:8px 16px;cursor:pointer;border:none;background:none;width:100%;text-align:left;font-size:14px;color:#333'; b.onmouseenter=()=>b.style.background='#f0f0f0'; b.onmouseleave=()=>b.style.background='transparent'; b.onclick=()=>{ fn(); hide(); }; return b; } + function hide(){ m.style.display='none'; } + function show(x,y){ m.style.left=x+'px'; m.style.top=y+'px'; m.style.display='block'; const r=m.getBoundingClientRect(); if(r.right>innerWidth) m.style.left=(x-r.width)+'px'; if(r.bottom>innerHeight) m.style.top=(y-r.height)+'px'; } + m.appendChild(item('← 返回', ()=>history.back())); + m.appendChild(item('🔄 刷新', ()=>location.reload())); + m.appendChild(item('ℹ️ 关于', ()=>{ try{ if(window.chrome&&window.chrome.webview){ window.chrome.webview.postMessage({type:'show_about'}); } }catch(_){ } })); + (document.body||document.documentElement).appendChild(m); + document.addEventListener('click', hide, {passive:true}); + document.addEventListener('scroll', hide, {passive:true}); + addEventListener('resize', hide, {passive:true}); + document.addEventListener('contextmenu', function(e){ e.preventDefault(); show(e.clientX,e.clientY); }, false); + } catch(e) { console.warn('右键菜单设置失败', e); } + "); + } + + if (interceptEnabled) + { + sb.AppendLine(@" try { + function isDownloadLink(a){ if(!a||!a.href) return false; if(a.hasAttribute('download')) return true; const u=(a.href||'').toLowerCase(); const exts=['.txt','.pdf','.doc','.docx','.xls','.xlsx','.ppt','.pptx','.zip','.rar','.7z','.tar','.gz','.jpg','.jpeg','.png','.gif','.bmp','.svg','.webp','.mp3','.wav','.ogg','.mp4','.avi','.mov','.wmv','.json','.xml','.csv','.md','.log']; for(const e of exts){ if(u.includes(e)) return true; } if(u.startsWith('data:')||u.startsWith('blob:')) return true; const kws=['download','export','save','下载','导出','保存']; const t=(a.textContent||'').toLowerCase(); const ti=(a.title||'').toLowerCase(); return kws.some(k=>t.includes(k)||ti.includes(k)); } + async function toBase64FromBlob(b){ const ab=await b.arrayBuffer(); const bytes=new Uint8Array(ab); let bin=''; const size=0x8000; for(let i=0;i这是用于演示的关于页面,展示从应用内打开本地 HTML 的能力。
+本应用由 WPF + WebView2 构建,支持:
+$?*~tR|E&Fk)gb3)zpWJ$
z;2uF 3*5si#`|VM#w?j
z%-R&jlBGmO7k!2EEh^}RqvGZTBmAD+Dbj%kxU9T9#Iru$vp(FaB3w29WUC m#3pMDV0-DulPUwq0ReTq2@2&
zlWEn0+SJ5j?kU?eu)`H{b}K`Ao8Z*0jP=_71aZz?E99sH=g9p#ilS_1lfJ6qWOZ8H
z&95Xzm5+Otftqs&n7KgTBI(sl(|5^5GDO*U5~LtqyW=+SD@k8A;=f*|9>v%#ah5nA
z&3zoIk`3KojNFv9)DmyFb3dBTw+6%}^yZu~VHEFPJAFO~k>j%Wu~L?s{8}Qln_qN5
z%J#sU4B{#S8d~`is!tXZwsPGm_vr1;tAE*-`n+F-YSC&r{JQmK>VcN6uoj@M48W?`
zu>J^pW5H*k#@JiWq=P#|U0_2=jTcNQIyNy%bMFjbO4`q6F&K#r-~#PGAVXkj3Y0Kl
zm~uxrajBP(vE|R@nWJ}tP_9JLglUT5u3a4kMEHlw$3GP4Hsp_`7-9e=0xs_E
z(9lyxu+E~C7(2JLRAhLpFoZu}=RS%P5>$UC?$qw6!jq&-LVQAln3(kywr&X6o=k=s
zZ@Q&U=UkbUetK0!#UKiW`UP0DsHIx^pz41znB)oSur{xFOk^guE`PvA8@lEBOP!rH
zjrI4%#l?MaYjctKf^WBZI$&V+tS)2cP9!SkEaE%IgUl1W7oH$`D%DHSNW@UbBU#mS
z@!nTfym2@YJ8nzX*yQ<@7q$vQS2w@xo~OMls%V^esilTuP-MVC6qGY}R&R*()>ir7
zD=X&K)~8`v=G`vTm4I}}9aFxhlB#MOZNnd$&GiIbSXN>}^Yh!!*`OFZAO$
zRHl8HJ_(AzH!NhTaq)rAe$%({CkPn_;Ff~3O|{L+%Y0(kBzPexrs{b6;rDWVq(?vfz5i=j`h@v
zNgc?+3l^Mx*X|B};2>kyKwl$8<4>BkiIL%Ny@)Doge#neID|4`?qfOsz4TLKRWm3G
zt`ri
02|1|*P{TjS$a<m+y28`H6$-Y3Rvgh1iI-FaS>XfR_MX2?Z=;XowCD
zU8r)kZ{GHIx2eFq!>Fxo$v{G*6`4GxS)hhV*C$YG8EqwcQB5S=V8M@cs^VF`ouW#{
zkUS-
D%_yNbmhr>d7K#Iv
zuBJSzY*n5jT03vP(J|Anl!Q%<8w>BgV2fgMrW$;@M6W<`_ud@6BX3!=JGO=|cJQ(H
zWyT_zJmgyFZ(;dunji_Ny)MgLP5t-YzXuoaVI_fh3_~0eAW**bxUKfPJ74UyEl7tA
z)EkyJ&n_|K)a_vQ|Nh(BOUQbd63@hH!hm4D(Bis
zTIet3n2PaySF4&(^R+~~24jx$hx}B(Ve2$*S*GvpO0#>)(H!bcfAP8EpUPRzO1zr5
z)W|=)3J`PCqUWpYIhxx+3m*MmZUbHx(})`T-17QbSCTMYVop8kVNObYOy{Qs+LKgX
zbCSv#!##m<-DD;ZxX+%J?tFecXld
Qj}CVL#Gm_!6mksUw$@=%;Pn_
zNa<@igD=qy!e6{KAS`y#T)2OtOaavoD0@eUdv+x#l4?AxWXB{rm;FhdTP;+fI&YsJ
zfDr#n4Tx)h)Yy_4EqEMtGQz7Sq{^uydEOavjxl{6(TOS=Vo%E};UNzvNQ)_uY}(ig
z5KCB3<2+@;m|(-7fYIh)>R;CkT~6{D)}eZ=BhbRBp!Nx>yj9)YZ9#-Csth$h
uqAuSKHM3~2DlLjym^K?)@23kM|Y`RnHl
z6jVv?oV%^~9UvEu5+9PwoIbm8qeUqdHgN&Kpd9oF>?&?Z)?2kuJ5}EUymR9Z>wrLb
zix@2Pom3@W`{Sp@b3(&f47EQgn2V|`8r|xR7uVOx`&Yi86IJ0lhV`sT!;(P_H&@sE
zG!+_MymwUiwb+u07wX^K4gTau%XJpqj_VZ63b*>jADzGR6Bz^JM|f{;j%WeD`9vB!Z_
zL;GHT1bFnkNl7n#T_#OBXD_fYEP1lDTH4tuiCu`1sK4x_=RJU_p^Zf~QFZNt1z;Co
z8I6d(VGdCwvK*Amb>~OI?!rj~^0Xxydz+I$YZ55@PZ=CtC~DkM``D#?^H6~St1(Xx
zV%h)|2a+H=2~4Y}XV}Ju6WD)@6P6nWF6T5RS7WEF=sICn_bQI4UE0fzjB^<{RYL!!
z0#Ab