c# 在子线程然回调到主线程方法

背景

我们开发代码经常面对线程的问题,多线程性带来异步方便的同时也带来稳定性问题,所以我们需要解决掉线程问题

解决方案

1:加锁

这种方案基本是解决线程的基本方法,但要求开发者对代码非常清晰,不然很容易死锁。

2:投递回调或者事件到主线程或者同一个线程里面

基本原理尽可能在同一个线程里面,那么就没有线程竞争,这种实现方式基于主线程的队列,我们常常用主线程的消息队列,c# 貌似也是类似。只要事件队列加锁就可以了,那么加锁颗粒就非常少了,我们也可以自己创建一个线程,不停等待任务,然后处理返回数据,那么数据都在所谓的业务主线程。你可以看看很多开源代码基本这么写的,android 事件也类似。android每个线程都有一个时间循环队列,比喻我们请求网络数据后,直接投递数据到android ui的主线程就可以了,那么数据就没有竞争。

3:c#的方式

SynchronizationContext 这个每个线程都有

            sync_context.Post(new SendOrPostCallback((o) =>
            {
                //执行的代码
            }), null);

Dispatcher 这个对线所有控件都会继承这个,所以你必须要保留主要界面的 Dispatcher ,但我在开发时候,如果使用不当的话会导致界面很卡,大概是代码里面反复调用导致的问题。

c# md5 在某些电脑报错

此实现不是 Windows 平台 FIPS 验证的加密算法的一部分。我们能从网上能找到基本是这个错误,一个c# 系统API竟然会报错,然后根据网上修改APP.config关闭FIP算法是无效,不用再试了。然后修改注册表:

在window中打开功能里输入regedit,回车打开注册器。然后进入如下路径中

 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy   将enable设置为0 即可。

修改之后要重新启动电脑。

虽然上面这个可以解决问题,但用户电脑不可能要用户修改,后面通过从github找一个份MD5 实现代码来替换系统API的MD5,写这篇文章的意思,大家还是不要用c# md5,如果别人电脑开启fips就报异常,虽然这个配置默认关闭的,但可能个别用户是打开的。

c# wpf webview 屏蔽右键方法1

代码(直接copy)

 public class WebBrowserHostUIHandler : Native.IDocHostUIHandler
    {
        private const uint E_NOTIMPL = 0x80004001;
        private const uint S_OK = 0;
        private const uint S_FALSE = 1;

        public WebBrowserHostUIHandler(WebBrowser browser)
        {
            if (browser == null)
                throw new ArgumentNullException("browser");

            Browser = browser;
            browser.LoadCompleted += OnLoadCompleted;
            browser.Navigated += OnNavigated;
            IsWebBrowserContextMenuEnabled = true;
            Flags |= HostUIFlags.ENABLE_REDIRECT_NOTIFICATION;
        }

        public WebBrowser Browser { get; private set; }
        public HostUIFlags Flags { get; set; }
        public bool IsWebBrowserContextMenuEnabled { get; set; }
        public bool ScriptErrorsSuppressed { get; set; }

        private void OnNavigated(object sender, NavigationEventArgs e)
        {
            SetSilent(Browser, ScriptErrorsSuppressed);
        }

        private void OnLoadCompleted(object sender, NavigationEventArgs e)
        {
            Native.ICustomDoc doc = Browser.Document as Native.ICustomDoc;
            if (doc != null)
            {
                doc.SetUIHandler(this);
            }
        }

        uint Native.IDocHostUIHandler.ShowContextMenu(int dwID, Native.POINT pt, object pcmdtReserved, object pdispReserved)
        {
            return IsWebBrowserContextMenuEnabled ? S_FALSE : S_OK;
        }

        uint Native.IDocHostUIHandler.GetHostInfo(ref Native.DOCHOSTUIINFO info)
        {
            info.dwFlags = (int)Flags;
            info.dwDoubleClick = 0;
            return S_OK;
        }

        uint Native.IDocHostUIHandler.ShowUI(int dwID, object activeObject, object commandTarget, object frame, object doc)
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.HideUI()
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.UpdateUI()
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.EnableModeless(bool fEnable)
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.OnDocWindowActivate(bool fActivate)
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.OnFrameWindowActivate(bool fActivate)
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.ResizeBorder(Native.COMRECT rect, object doc, bool fFrameWindow)
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.TranslateAccelerator(ref System.Windows.Forms.Message msg, ref Guid group, int nCmdID)
        {
            return S_FALSE;
        }

        uint Native.IDocHostUIHandler.GetOptionKeyPath(string[] pbstrKey, int dw)
        {
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.GetDropTarget(object pDropTarget, out object ppDropTarget)
        {
            ppDropTarget = null;
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.GetExternal(out object ppDispatch)
        {
            ppDispatch = Browser.ObjectForScripting;
            return S_OK;
        }

        uint Native.IDocHostUIHandler.TranslateUrl(int dwTranslate, string strURLIn, out string pstrURLOut)
        {
            pstrURLOut = null;
            return E_NOTIMPL;
        }

        uint Native.IDocHostUIHandler.FilterDataObject(IDataObject pDO, out IDataObject ppDORet)
        {
            ppDORet = null;
            return E_NOTIMPL;
        }

        public static void SetSilent(WebBrowser browser, bool silent)
        {
            Native.IOleServiceProvider sp = browser.Document as Native.IOleServiceProvider;
            if (sp != null)
            {
                Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
                Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");

                object webBrowser;
                sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
                if (webBrowser != null)
                {
                    webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
                }
            }
        }
    }

    internal static class Native
    {
        [ComImport, Guid("BD3F23C0-D43E-11CF-893B-00AA00BDCE1A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IDocHostUIHandler
        {
            [PreserveSig]
            uint ShowContextMenu(int dwID, POINT pt, [MarshalAs(UnmanagedType.Interface)] object pcmdtReserved, [MarshalAs(UnmanagedType.Interface)] object pdispReserved);

            [PreserveSig]
            uint GetHostInfo(ref DOCHOSTUIINFO info);

            [PreserveSig]
            uint ShowUI(int dwID, [MarshalAs(UnmanagedType.Interface)] object activeObject, [MarshalAs(UnmanagedType.Interface)] object commandTarget, [MarshalAs(UnmanagedType.Interface)] object frame, [MarshalAs(UnmanagedType.Interface)] object doc);

            [PreserveSig]
            uint HideUI();

            [PreserveSig]
            uint UpdateUI();

            [PreserveSig]
            uint EnableModeless(bool fEnable);

            [PreserveSig]
            uint OnDocWindowActivate(bool fActivate);

            [PreserveSig]
            uint OnFrameWindowActivate(bool fActivate);

            [PreserveSig]
            uint ResizeBorder(COMRECT rect, [MarshalAs(UnmanagedType.Interface)] object doc, bool fFrameWindow);

            [PreserveSig]
            uint TranslateAccelerator(ref System.Windows.Forms.Message msg, ref Guid group, int nCmdID);

            [PreserveSig]
            uint GetOptionKeyPath([Out, MarshalAs(UnmanagedType.LPArray)] string[] pbstrKey, int dw);

            [PreserveSig]
            uint GetDropTarget([In, MarshalAs(UnmanagedType.Interface)] object pDropTarget, [MarshalAs(UnmanagedType.Interface)] out object ppDropTarget);

            [PreserveSig]
            uint GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);

            [PreserveSig]
            uint TranslateUrl(int dwTranslate, [MarshalAs(UnmanagedType.LPWStr)] string strURLIn, [MarshalAs(UnmanagedType.LPWStr)] out string pstrURLOut);

            [PreserveSig]
            uint FilterDataObject(IDataObject pDO, out IDataObject ppDORet);
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct DOCHOSTUIINFO
        {
            public int cbSize;
            public int dwFlags;
            public int dwDoubleClick;
            public IntPtr dwReserved1;
            public IntPtr dwReserved2;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct COMRECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal class POINT
        {
            public int x;
            public int y;
        }

        [ComImport, Guid("3050F3F0-98B5-11CF-BB82-00AA00BDCE0B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface ICustomDoc
        {
            [PreserveSig]
            int SetUIHandler(IDocHostUIHandler pUIHandler);
        }

        [ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IOleServiceProvider
        {
            [PreserveSig]
            uint QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
        }
    }

    [Flags]
    public enum HostUIFlags
    {
        DIALOG = 0x00000001,
        DISABLE_HELP_MENU = 0x00000002,
        NO3DBORDER = 0x00000004,
        SCROLL_NO = 0x00000008,
        DISABLE_SCRIPT_INACTIVE = 0x00000010,
        OPENNEWWIN = 0x00000020,
        DISABLE_OFFSCREEN = 0x00000040,
        FLAT_SCROLLBAR = 0x00000080,
        DIV_BLOCKDEFAULT = 0x00000100,
        ACTIVATE_CLIENTHIT_ONLY = 0x00000200,
        OVERRIDEBEHAVIORFACTORY = 0x00000400,
        CODEPAGELINKEDFONTS = 0x00000800,
        URL_ENCODING_DISABLE_UTF8 = 0x00001000,
        URL_ENCODING_ENABLE_UTF8 = 0x00002000,
        ENABLE_FORMS_AUTOCOMPLETE = 0x00004000,
        ENABLE_INPLACE_NAVIGATION = 0x00010000,
        IME_ENABLE_RECONVERSION = 0x00020000,
        THEME = 0x00040000,
        NOTHEME = 0x00080000,
        NOPICS = 0x00100000,
        NO3DOUTERBORDER = 0x00200000,
        DISABLE_EDIT_NS_FIXUP = 0x00400000,
        LOCAL_MACHINE_ACCESS_CHECK = 0x00800000,
        DISABLE_UNTRUSTEDPROTOCOL = 0x01000000,
        HOST_NAVIGATES = 0x02000000,
        ENABLE_REDIRECT_NOTIFICATION = 0x04000000,
        USE_WINDOWLESS_SELECTCONTROL = 0x08000000,
        USE_WINDOWED_SELECTCONTROL = 0x10000000,
        ENABLE_ACTIVEX_INACTIVATE_MODE = 0x20000000,
        DPI_AWARE = 0x40000000
    }

怎么使用?

private WebBrowserHostUIHandler _wbHandler;

_wbHandler = new WebBrowserHostUIHandler(WebViewControl);

WebViewControl就是对应的WebView类名,c++ 也有类似方法。其实不用太关心代码细节,这个都是com接口,微软有一些文档介绍,我记得以前我用c++找到过,写过类似的代码,这份代码是从老外那里直接复制,这样子就不需要用winform webview了。后面我会介绍用js的方法屏蔽右键

c#基于webview开发模块

背景

我们开发内容经常会变动,界面模块经常会增加功能,这个时候就可以考虑用webview来开发,比喻常见音乐播放器,QQ音乐,酷狗音乐,网易云音乐等等 PC端开发都是基于webview开发的,你用类似查看窗口工具,就可以看到他们的窗口类名,要么就是基于ie weview控件的,要么基于chrome webview控件。

c# 使用webview

直接添加webview控件即可,控件宽度和高度就看你需求了,自己稍微研究一下就可以了。

webview调用c#代码

我们肯定会用到js 调用c#代码,主要通过window.external 来访问c#方法,后面我在这块代码补充起来,现在写博客是在MAC,没法帖代码

可能遇到问题

  • c#定义的给JS调用,必须是PUBLIC,否则会调用异常
  • 传递类型基本是必须基本类型,如果是对象,那么考虑用JSON代替
  • 想c#调用JS代码,这个想法是错误的,因为会涉及到网页加载事件,那么c#就必须监听页面事件,这样子把业务复杂,耦合太多,那么直接设置好函数,然后直接在JS中主动调用函数,一样可以达到效果,反而代码更加流畅,更加优美。记住一点:c#提供接口,JS来调用。

总结

记得最开始在深圳上班第一家公司是做在线教育,那个时候PC项目采用c++ 加 webview 来做PC端,从无到有自己摸索出来。想不到现在又用这个技术实现云插件。所以知识这个东西,只要明白本质就可以了,知道方案,用什么语音实现并重要。多看书,多积累一些知识点是不会错的。

背景:

有的时候自己开发工具会被360误杀或者误报,所以就要告诉用户退出360或者添加信任。

原理;

检测360安全卫士和360杀毒的进程名字,进行比对。

`///

/// 360是否运行
///

///
public static bool IsRun360()
{
foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
{
if (p.ProcessName.ToLower() == “360tray”)
{
return true;
}

if (p.ProcessName.ToLower() == “360sd”)
{
return true;
}
}

return false;
}`