CefSharp禁止彈出新窗體,在同一視窗打開鏈接,或者在新Tab頁打開鏈接,並且支持帶type="POST" target="_blank"的鏈接

来源:https://www.cnblogs.com/s0611163/archive/2019/12/13/12034090.html
-Advertisement-
Play Games

說明:在同一視窗打開鏈接,只要稍加改造就可以實現,這裡實現的是在新Tab頁打開鏈接,並且支持帶type="POST" target="_blank"的鏈接 github和bitbucket上相關問題: 1、WPF empty POST data when using custom popup htt ...


 說明:在同一視窗打開鏈接,只要稍加改造就可以實現,這裡實現的是在新Tab頁打開鏈接,並且支持帶type="POST" target="_blank"的鏈接

 

github和bitbucket上相關問題:

1、WPF empty POST data when using custom popup    https://github.com/cefsharp/CefSharp/issues/1267

2、CefLifeSpanHandler, customized OnBeforePopup problem    https://bitbucket.org/chromiumembedded/cef/issues/1949/

 

解決(CefSharp版本75.1.143.0):

一、實現IRequestHandler介面

using CefSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates;

namespace CefSharpDemo
{
    public class RequestHandler : IRequestHandler
    {
        private ExtChromiumBrowser _browser;

        public RequestHandler(ExtChromiumBrowser browser)
        {
            _browser = browser;
        }

        public bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
        {
            return false;
        }

        public IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            if (request.Method.ToUpper() == "POST" && request.PostData != null)
            {
                if (request.PostData.Elements.Count > 0)
                {
                    _browser.PostData = new byte[request.PostData.Elements[0].Bytes.Length];
                    request.PostData.Elements[0].Bytes.CopyTo(_browser.PostData, 0);
                }
            }
            return null;
        }

        public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
        {
            return false;
        }

        public bool OnCertificateError(IWebBrowser chromiumWebBrowser, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback)
        {
            return false;
        }

        public bool OnOpenUrlFromTab(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
        {
            return false;
        }

        public void OnPluginCrashed(IWebBrowser chromiumWebBrowser, IBrowser browser, string pluginPath)
        {

        }

        public bool OnQuotaRequest(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, long newSize, IRequestCallback callback)
        {
            return false;
        }

        public void OnRenderProcessTerminated(IWebBrowser chromiumWebBrowser, IBrowser browser, CefTerminationStatus status)
        {

        }

        public void OnRenderViewReady(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {

        }

        public bool OnSelectClientCertificate(IWebBrowser chromiumWebBrowser, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
        {
            return false;
        }
    }
}
View Code

二、實現ILifeSpanHandler介面

using CefSharp;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using Utils;

namespace CefSharpDemo
{
    public class CefLifeSpanHandler : CefSharp.ILifeSpanHandler
    {
        private static LimitedTaskScheduler _scheduler = new LimitedTaskScheduler(2);

        public CefLifeSpanHandler()
        {

        }

        public bool DoClose(IWebBrowser browserControl, CefSharp.IBrowser browser)
        {
            if (browser.IsDisposed || browser.IsPopup)
            {
                return false;
            }

            return true;
        }

        public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser)
        {

        }

        public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser)
        {
        }

        public bool OnBeforePopup(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {
            var chromiumWebBrowser = (ExtChromiumBrowser)browserControl;

            chromiumWebBrowser.Dispatcher.Invoke(new Action(() =>
            {
                BrowserPopupWin win = new BrowserPopupWin();
                win.ShowInTaskbar = false;
                win.Height = 0;
                win.Width = 0;
                win.Show();

                IntPtr handle = new WindowInteropHelper(win).Handle;
                windowInfo.SetAsChild(handle);

                _scheduler.Run(() =>
                {
                    WaitUtil.Wait(() => chromiumWebBrowser.PostData);

                    IRequest request = null;
                    if (chromiumWebBrowser.PostData != null)
                    {
                        request = frame.CreateRequest();
                        request.Url = targetUrl;
                        request.Method = "POST";

                        request.InitializePostData();
                        var element = request.PostData.CreatePostDataElement();
                        element.Bytes = chromiumWebBrowser.PostData;
                        request.PostData.AddElement(element);
                        chromiumWebBrowser.PostData = null;
                    }

                    chromiumWebBrowser.Dispatcher.Invoke(new Action(() =>
                    {
                        NewWindowEventArgs e = new NewWindowEventArgs(targetUrl, request);
                        chromiumWebBrowser.OnNewWindow(e);
                    }));

                    chromiumWebBrowser.Dispatcher.Invoke(new Action(() =>
                    {
                        win.Close();
                    }));
                });
            }));

            newBrowser = null;
            return false;
        }

    }
}
View Code

三、擴展ChromiumWebBrowser

using CefSharp.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CefSharpDemo
{
    public class ExtChromiumBrowser : ChromiumWebBrowser
    {
        public byte[] PostData { get; set; }

        public ExtChromiumBrowser()
            : base()
        {
            this.LifeSpanHandler = new CefLifeSpanHandler();
            this.DownloadHandler = new DownloadHandler(this);
            this.MenuHandler = new MenuHandler();
            this.KeyboardHandler = new KeyboardHandler();
            this.RequestHandler = new RequestHandler(this);
        }

        public event EventHandler<NewWindowEventArgs> StartNewWindow;

        public void OnNewWindow(NewWindowEventArgs e)
        {
            if (StartNewWindow != null)
            {
                StartNewWindow(this, e);
            }
        }

        public void ClearHandlers()
        {
            //如果不清理Handler,會導致子進程CefSharp.BrowserSubprocess.exe無法釋放
            this.LifeSpanHandler = null;
            this.DownloadHandler = null;
            this.MenuHandler = null;
            this.KeyboardHandler = null;
        }
    }
}
View Code

四、封裝ExtChromiumBrowser(BrowserCtrl控制項)

using CefSharp;
using CefSharp.Wpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Utils;

namespace CefSharpDemo
{
    /// <summary>
    /// 瀏覽器用戶控制項
    /// </summary>
    public partial class BrowserCtrl : UserControl, IDisposable
    {
        #region 外部方法
        /*
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern int CloseWindow(IntPtr hWnd);
        [DllImport("User32.dll", EntryPoint = "GetWindowText")]
        private static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);
        */
        #endregion

        #region 變數屬性事件
        private static bool _isCefInited = false;

        private static object _lockObject = new object();

        private JSObject _jsObject;

        private bool _firstLoad = true;

        /// <summary>
        /// 在此事件中設置URL(此事件已線上程中執行,此事件已對錯誤情況進行處理)
        /// </summary>
        public event EventHandler SetUrlEvent;

        /// <summary>
        /// URL
        /// </summary>
        public string Url { get; set; }

        public IRequest Request { get; set; }

        /// <summary>
        /// 瀏覽器FrameLoadEnd事件
        /// </summary>
        public event EventHandler FrameLoadEnd;

        private ExtChromiumBrowser _browser;

        public ExtChromiumBrowser Browser
        {
            get
            {
                WaitUtil.Wait(() => this._browser != null && this._browser.IsInitialized && _isCefInited);

                return this._browser;
            }
        }

        private static LimitedTaskScheduler _scheduler = new LimitedTaskScheduler(2);
        #endregion

        #region 構造函數
        public BrowserCtrl()
        {
            InitializeComponent();
            if (DesignerProperties.GetIsInDesignMode(this)) return;

            this.Loaded += BrowserCtrl_Loaded;

            lock (_lockObject)
            {
                if (!_isCefInited)
                {
                    _isCefInited = true;
                    InitCef();//初始化CefSharp
                }
            }

            _browser = new ExtChromiumBrowser();
            BindBrowser(_browser);
            grid.Children.Add(_browser);
        }
        #endregion

        #region BrowserCtrl_Loaded
        private void BrowserCtrl_Loaded(object sender, RoutedEventArgs e)
        {

        }
        #endregion

        #region SetMapCtrl
        /// <summary>
        /// 設置Map控制項介面,用於C#和JS互操作
        /// </summary>
        public void SetMapCtrl(IMapCtrl mapCtrl)
        {
            _jsObject.MapCtrl = mapCtrl;
        }
        #endregion

        #region Dispose 釋放資源
        /// <summary>
        /// 釋放資源
        /// </summary>
        public void Dispose()
        {
            //如果有彈出視窗則先釋放它
            //foreach (UIElement item in grid.Children)
            //{
            //    if (item is BrowserContainer)
            //    {
            //        (item as BrowserContainer).ClearResource();
            //    }
            //}

            _browser.ClearHandlers();
            if (_browser != null && !_browser.IsDisposed)
            {
                _browser.Dispose();
            }
        }
        #endregion

        #region Load
        public void Load(string url)
        {
            if (!string.IsNullOrWhiteSpace(url))
            {
                loadingWait.Visibility = Visibility.Visible;
                Url = url;
                _scheduler.Run(() =>
                {
                    #region Wait
                    WaitUtil.Wait(() =>
                    {
                        if (this._browser == null) return false;
                        if (!this._browser.IsInitialized) return false;
                        if (!_isCefInited) return false;
                        bool isBrowserInitialized = false;
                        this.Dispatcher.Invoke(() =>
                        {
                            isBrowserInitialized = this._browser.IsBrowserInitialized;
                        });
                        if (!isBrowserInitialized) return false;
                        return true;
                    });
                    #endregion

                    _browser.Load(Url);
                });
            }
        }
        #endregion

        #region LoadUrl
        private void LoadUrl()
        {
            if (_firstLoad)
            {
                _firstLoad = false;

                _scheduler.Run(() =>
                {
                    #region Wait
                    WaitUtil.Wait(() =>
                    {
                        if (this._browser == null) return false;
                        if (!this._browser.IsInitialized) return false;
                        if (!_isCefInited) return false;
                        bool isBrowserInitialized = false;
                        this.Dispatcher.Invoke(() =>
                        {
                            isBrowserInitialized = this._browser.IsBrowserInitialized;
                        });
                        if (!isBrowserInitialized) return false;
                        return true;
                    });
                    #endregion

                    if (Url == null && SetUrlEvent != null)
                    {
                        try
                        {
                            SetUrlEvent(this, null);
                        }
                        catch (Exception ex)
                        {
                            LogUtil.Error(ex, "BrowserCtrl LoadUrl error 獲取URL失敗");
                        }
                    }
                    else
                    {
                        this.Dispatcher.Invoke(new Action(() =>
                        {
                            loadingWait.Visibility = Visibility.Collapsed;
                        }));
                    }

                    if (Url != null)
                    {
                        try
                        {
                            if (Request == null)
                            {
                                _browser.Load(Url);
                            }
                            else
                            {
                                _browser.Load(Url);
                                _browser.GetMainFrame().LoadRequest(Request);
                                Request = null;
                            }
                        }
                        catch (Exception ex)
                        {
                            LogUtil.Error(ex, "BrowserCtrl LoadUrl error Load URL失敗");
                        }
                    }
                    else
                    {
                        this.Dispatcher.Invoke(new Action(() =>
                        {
                            loadingWait.Visibility = Visibility.Collapsed;
                        }));
                    }
                });
            }
        }
        #endregion

        #region BindBrowser
        private void BindBrowser(ExtChromiumBrowser browser)
        {
            _jsObject = new JSObject();
            browser.RegisterJsObject("jsObj", _jsObject, new CefSharp.BindingOptions { CamelCaseJavascriptNames = false });

            browser.IsBrowserInitializedChanged += (ss, ee) =>
            {
                LoadUrl();
            };
            browser.FrameLoadStart += (ss, ee) =>
            {
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    (ss as ExtChromiumBrowser).Focus();
                }));
            };
            browser.FrameLoadEnd += (ss, ee) =>
            {
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    loadingWait.Visibility = Visibility.Collapsed;
                }));
                if (FrameLoadEnd != null)
                {
                    FrameLoadEnd(null, null);
                }
            };
            browser.KeyDown += (ss, ee) =>
            {
                if (ee.Key == Key.F5)
                {
                    try
                    {
                        browser.Reload();
                    }
                    catch (Exception ex)
                    {
                        LogUtil.Error(ex, "ExtChromiumBrowser Reload error");
                    }
                }
            };
            browser.PreviewTextInput += (o, e) =>
            {
                foreach (var character in e.Text)
                {
                    // 把每個字元向瀏覽器組件發送一遍
                    browser.GetBrowser().GetHost().SendKeyEvent((int)WM.CHAR, (int)character, 0);
                }

                // 不讓cef自己處理
                e.Handled = true;
            };
            browser.LoadError += (s, e) =>
            {
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    loadingWait.Visibility = Visibility.Collapsed;
                }));
            };
        }
        #endregion

        #region RegisterJsObject
        public void RegisterJsObject(string name, object objectToBind, BindingOptions options = null)
        {
            try
            {
                if (_browser != null)
                {
                    _browser.RegisterJsObject(name, objectToBind, options);
                }
            }
            catch (Exception ex)
            {
                LogUtil.Error(ex, "BrowserCtrl RegisterJsObject 錯誤");
            }
        }
        #endregion

        #region 初始化CefSharp
        public static void InitCef()
        {
            string cefsharpFolder = "CefSharp";

            var settings = new CefSettings();
            //The location where cache data will be stored on disk. If empty an in-memory cache will be used for some features and a temporary disk cache for others.
            //HTML5 databases such as localStorage will only persist across sessions if a cache path is specified. 
            settings.CachePath = cefsharpFolder + "/cache"; //設置cache目錄

            settings.MultiThreadedMessageLoop = true;
            CefSharpSettings.FocusedNodeChangedEnabled = true;
            CefSharpSettings.LegacyJavascriptBindingEnabled = true;
            CefSharpSettings.ShutdownOnExit = true;
            CefSharpSettings.SubprocessExitIfParentProcessClosed = true;

            string logDir = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + "/log/";
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }

            settings.BrowserSubprocessPath = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + "/CefSharp.BrowserSubprocess.exe";
            settings.LogFile = logDir + DateTime.Now.ToString("yyyyMMdd") + ".log";
            settings.LocalesDirPath = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + "/locales";
            settings.CefCommandLineArgs.Add("disable-gpu", "1");
            settings.CefCommandLineArgs.Add("enable-media-stream", "1");

            if (!Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: new BrowserProcessHandler()))
            {
                throw new Exception("Unable to Initialize Cef");
            }
        }
        #endregion

    }
}
View Code

五、MainWindow測試代碼

using CefSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Utils;

namespace CefSharpDemo
{
    /// <summary>
    /// CefSharp Demo 窗體
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            tabControl.AddTabItemEvent += tabControl_AddTabItemEvent;
            Application.Current.MainWindow = this;
        }

        private void tabControl_AddTabItemEvent(object sender, EventArgs e)
        {
            //CreateTabItem("https://www.cnblogs.com/");
            CreateTabItem("file:///D:/_程式/CefSharpDemo/post.html");
        }

        /// <summary>
        /// 新增Tab頁
        /// </summary>
        private void CreateTabItem(string url = null, IRequest request = null)
        {
            TabItem tabItem = new TabItem();
            tabItem.Header = "新標簽頁";
            BrowserDemoCtrl ctrl = new BrowserDemoCtrl();
            ctrl.browserCtrl.Browser.StartNewWindow += (s, e) =>
            {
                CreateTabItem(e.TargetUrl, e.Request);
            };
            ctrl.browserCtrl.SetUrlEvent += (s, e) =>
            {
                ctrl.browserCtrl.Url = url;
                ctrl.browserCtrl.Request = request;
            };
            tabItem.Content = ctrl;
            tabControl.Items.Add(tabItem);
            tabControl.SelectedItem = tabItem;
            ScrollViewer scrollViewer = tabControl.Template.FindName("scrollViewer", tabControl) as ScrollViewer;
            scrollViewer.ScrollToRightEnd();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            tabControl.CloseAllTabItem(); //關閉窗體清理資源

            //程式退出時刪除cache
            CefSharp.Cef.Shutdown();
            string cachePath = AppDomain.CurrentDomain.BaseDirectory + "CefSharp\\cache";
            if (Directory.Exists(cachePath))
            {
                foreach (string path in Directory.GetDirectories(cachePath))
                {
                    Directory.Delete(path, true);
                }
                foreach (string file in Directory.GetFiles(cachePath))
                {
                    if (!file.ToLower().Contains("cookies"))
                    {
                        File.Delete(file);
                    }
                }
            }
        }
    }
}
View Code

 六、測試html代碼post.html

<!DOCTYPE html>
<html>
<head>
    <title>CefSharpDemo</title>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style type="text/css">
    </style>

    <script type="text/javascript">
    </script>
</head>
<body>
    <!--enctype="multipart/form-data"-->
    <form method="post" action="http://localhost:1209/netcms/" target="_blank">
        <span>name:</	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 比如我們需要ASP.NET Core 中需要通過PDF來進行某些簡單的報表開發,隨著這並不難,但還是會手忙腳亂的去搜索一些資料,那麼恭喜您,這篇帖子會幫助到您,我們就不會再去浪費一些寶貴的時間。 在本文中我們將要使用DinkToPDF來處理我們在.NET Core Web 程式中進行構建PDF文檔! ...
  • EulerOS其實出來有一段時間了,一直在關註,單是僅僅也只是停留在觀望的階段,目前還沒有接入的打算;正好看到園子里的兄弟分享了華為雲免費試用的活動後,難捺激動的心情,我馬上去申請試用了一臺伺服器。 ...
  • 如果要在程式中使用DbContext,則需要先在Nuget中安裝Microsoft.EntityFrameworkCore.SqlServer ...
  • 原文:https://blogs.msdn.microsoft.com/mazhou/2017/12/12/c-7-series-part-7-ref-returns/ 背景 有兩種方法可以將一個值傳遞給一個方法: 例如,FCL(.NET Framework Class Library)中的Arra ...
  • 引用類庫 1.Install-Package Microsoft.Extensions.Caching.Memory MemoryCacheOptions 緩存配置 1.ExpirationScanFrequency 獲取或設置對過期項的連續掃描之間的最短時間間隔 2.SizeLimit 緩存是沒有 ...
  • 對於地圖坐標偏移,以leaflet為例,有如下解決辦法 方法1、修改leaflet源碼,解決地圖坐標偏移問題 方法2、將點位真實的經緯度經過偏移演算法,添加到加密的地圖上 方法3、直接對離線地圖瓦片進行糾偏 方法1需要修改源碼 方法2有缺陷,地圖依然是偏移的,如果把地圖經緯度顯示出來,經緯度也是不對的 ...
  • 9月份的時候,微軟宣佈正式發佈C 8.0,作為.NET Core 3.0發行版的一部分。C 8.0的新特性之一就是預設介面實現。在本文中,我們將一起來聊聊預設介面實現。 作者:依樂祝 原文鏈接:https://www.cnblogs.com/yilezhu/p/12034584.html 提前說下: ...
  • 前言 公司項目需要做個畫線縮放,我司稱之為瞳距縮放,簡而言之就是:2張圖,從第一張圖畫一條線,再從第二個圖畫一條線,第二條線以第一條為基準,延長到一致的長度,並同比縮放圖片;文字太枯燥,請先實例圖 例子1:以皮卡丘為例,我要把路飛的拳頭縮放到皮卡丘頭那麼大 例子2:以皮卡丘的基準,縮小路飛,與其身高 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...