当前位置: 首页 > news >正文

.NET的键盘Hook管理类,用于禁用键盘输入和切换

一、MyHook帮助类

 此类需要编写指定屏蔽的按键,灵活性差。

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.Win32;namespace MyHookClass
{/// <summary>/// 类一/// </summary>public class MyHook{//消息函数的委托public delegate int HookProc(int nCode, int wParam, IntPtr lParam);static int hHook = 0;public const int WH_KEYBOARD_LL = 13;//底层键盘钩子static HookProc KeyBoardHookProcedure;//按键信息结构[StructLayout(LayoutKind.Sequential)]public class KeyBoardHookStruct{public int vkCode;public int scanCode;public int flags;public int time;public int dwExtraInfo;}//安装钩子[DllImport("user32.dll")]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);//卸载钩子[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook);//下一个钩挂的函数[DllImport("user32.dll")]public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);//返回当前线程 ID[DllImport("kernel32.dll")]public static extern int GetCurrentThreadId();//得到模块的句柄[DllImport("kernel32.dll")]public static extern IntPtr GetModuleHandle(string name);//安装钩子public static void InsertHook(){if (hHook == 0){KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);hHook = SetWindowsHookEx(WH_KEYBOARD_LL,KeyBoardHookProcedure,GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);if (hHook == 0){UnHook();throw new Exception("设置Hook失败!");}else{RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);if (key == null)//如果该项不存在的话,则创建该项key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");key.SetValue("DisableTaskMgr", 1, RegistryValueKind.DWord);//key.SetValue("DisableLockWorkstation", 1, RegistryValueKind.DWord);key.Close();}}}//卸载钩子public static void UnHook(){bool retKeyboard = true;if (hHook != 0){retKeyboard = UnhookWindowsHookEx(hHook);hHook = 0;}//if (!retKeyboard) throw new Exception("卸载Hook失败!");RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);if (key != null){key.DeleteValue("DisableTaskMgr", false);//key.DeleteValue("DisableLockWorkstation", false);key.Close();}}//按键消息的处理函数public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam){if (nCode >= 0){KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));//添加自己的判断语句,如果符合要求的按键,就 return 1; //没有判断直接 return 1;那么就屏蔽所有按键除了ctrl+alt+del//屏蔽Ctrl+Escif (kbh.vkCode == (int)Keys.Delete && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt)      //截获Ctrl+Alt+Delete{PubLibrary.WriteErrLog("1.拦截信息:Ctrl+Alt+Delete");return 1;}if (kbh.vkCode == (int)Keys.Escape){PubLibrary.WriteErrLog("2.拦截信息:Escape");return 1;}if (kbh.vkCode == 91) // 截获左win(开始菜单键) {PubLibrary.WriteErrLog("3.拦截信息:截获左win");return 1;}if (kbh.vkCode == 92)// 截获右win {PubLibrary.WriteErrLog("4.拦截信息:截获右win");return 1;}//if (kbh.vkCode == (int)Keys.L)//{//    PubLibrary.WriteErrLog("5.拦截信息:L");//    return 1;//}if (kbh.vkCode == (int)Keys.Alt){PubLibrary.WriteErrLog("6.拦截信息:Alt");return 1;}if ((int)Control.ModifierKeys == (int)Keys.Alt) //截获alt{PubLibrary.WriteErrLog("7.拦截信息:Alt");return 1;}if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control) //截获Ctrl+Esc {PubLibrary.WriteErrLog("8.拦截信息:Ctrl+Esc");return 1;}if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt) //截获Alt+Esc {PubLibrary.WriteErrLog("9.拦截信息:Alt+Esc");return 1;}if (kbh.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+f4 {PubLibrary.WriteErrLog("10.拦截信息:F4+Alt");return 1;}if (kbh.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+tab{PubLibrary.WriteErrLog("10.拦截信息:alt+tab");return 1;}if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift) //截获Ctrl+Shift+Esc{PubLibrary.WriteErrLog("11.拦截信息:Ctrl+Shift+Esc");return 1;}if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+空格 {PubLibrary.WriteErrLog("12.拦截信息:alt+空格");return 1;}if (kbh.vkCode == 241) //截获F1 {PubLibrary.WriteErrLog("13.拦截信息:F1");return 1;}if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)      //截获Ctrl+Alt+Delete {PubLibrary.WriteErrLog("14.拦截信息:Ctrl+Alt+Delete");return 1;}if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift) //截获Ctrl+Shift {PubLibrary.WriteErrLog("15.拦截信息:Ctrl+Shift");return 1;}if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) //截获Ctrl+Alt+空格 {PubLibrary.WriteErrLog("16.拦截信息:Ctrl+Alt+空格");return 1;}}return CallNextHookEx(hHook, nCode, wParam, lParam);}}
}

二、KeyboardHookLib帮助类

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Microsoft.Win32;namespace VendorSoftwareReleaseLW.Class
{/// <summary>/// 键盘Hook管理类/// </summary>public class KeyboardHookLib{private const int WH_KEYBOARD_LL = 13; //键盘//键盘处理事件委托 ,当捕获键盘输入时调用定义该委托的方法.private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);//客户端键盘处理事件public delegate void ProcessKeyHandle(HookStruct param, out bool handle);//接收SetWindowsHookEx返回值private static int _hHookValue = 0;//勾子程序处理事件private HookHandle _KeyBoardHookProcedure;//Hook结构[StructLayout(LayoutKind.Sequential)]public class HookStruct{public int vkCode;public int scanCode;public int flags;public int time;public int dwExtraInfo;}//设置钩子[DllImport("user32.dll")]private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);//取消钩子[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]private static extern bool UnhookWindowsHookEx(int idHook);//调用下一个钩子[DllImport("user32.dll")]private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);//获取当前线程ID[DllImport("kernel32.dll")]private static extern int GetCurrentThreadId();//Gets the main module for the associated process.[DllImport("kernel32.dll")]private static extern IntPtr GetModuleHandle(string name);private IntPtr _hookWindowPtr = IntPtr.Zero;//构造器public KeyboardHookLib() { }//外部调用的键盘处理事件private static ProcessKeyHandle _clientMethod = null;/// <summary>/// 安装勾子/// </summary>/// <param name="hookProcess">外部调用的键盘处理事件</param>public void InstallHook(ProcessKeyHandle clientMethod){_clientMethod = clientMethod;// 安装键盘钩子if (_hHookValue == 0){_KeyBoardHookProcedure = new HookHandle(OnHookProc);_hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);//************************************ //键盘线程钩子 //SetWindowsHookEx( 2,KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId()); //GetCurrentThreadId()为要监视的线程ID,你完全可以自己写个方法获取QQ的线程哦 //键盘全局钩子,需要引用空间(using System.Reflection;) //SetWindowsHookEx( 13,KeyboardHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0); // //关于SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函数将钩子加入到钩子链表中,说明一下四个参数: //idHook 钩子类型,即确定钩子监听何种消息,上面的代码中设为2,即监听键盘消息并且是线程钩子,如果是全局钩子监听键盘消息应设为13, //线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14。 // //lpfn 钩子子程的地址指针。如果dwThreadId参数为0 或是一个由别的进程创建的线程的标识,lpfn必须指向DLL中的钩子子程。 除此以外,lpfn可 //以指向当前进程的一段钩子子程代码。钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。 // //hInstance应用程序实例的句柄。标识包含lpfn所指的子程的DLL。如果threadId 标识当前进程创建的一个线程,而且子程代码位于当前 //进程,hInstance必须为NULL。可以很简单的设定其为本应用程序的实例句柄。 // //threadedId 与安装的钩子子程相关联的线程的标识符。如果为0,钩子子程与所有的线程关联,即为全局钩子。 //************************************ _hHookValue = SetWindowsHookEx(WH_KEYBOARD_LL,_KeyBoardHookProcedure,_hookWindowPtr,0);//如果设置钩子失败.if (_hHookValue == 0){UninstallHook();}else{RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);if (key == null)//如果该项不存在的话,则创建该项key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");key.SetValue("DisableTaskMgr", 1, RegistryValueKind.DWord);//key.SetValue("DisableLockWorkstation", 1, RegistryValueKind.DWord);key.Close();}}}//取消钩子事件public void UninstallHook(){if (_hHookValue != 0){bool ret = UnhookWindowsHookEx(_hHookValue);if (ret) _hHookValue = 0;}RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);if (key != null){key.DeleteValue("DisableTaskMgr", false);//key.DeleteValue("DisableLockWorkstation", false);key.Close();}}//钩子事件内部调用,调用_clientMethod方法转发到客户端应用。private static int OnHookProc(int nCode, int wParam, IntPtr lParam){if (nCode >= 0){//转换结构HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));if (_clientMethod != null){bool handle = false;//调用客户提供的事件处理程序。_clientMethod(hookStruct, out handle);if (handle) return 1; //1:表示拦截键盘,return 退出}}return CallNextHookEx(_hHookValue, nCode, wParam, lParam);}}
}

三、在WinForm中的使用

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using MyHookClass;
using KeyboardHookLibClass;namespace TestForm
{public partial class LoginForm : Form{DateTime _dtNow;[DllImport("user32.dll")]private static extern IntPtr GetForegroundWindow();[DllImport("user32.dll")]private static extern bool SetForegroundWindow(IntPtr hWnd);[DllImport("user32.dll")]private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.dll")]public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);[DllImport("user32.dll")]public static extern bool IsWindowVisible(IntPtr hWnd);//勾子管理类private KeyboardHookLib _keyboardHook = null;public delegate void ForegroundWin();private void LoginForm_Load(object sender, EventArgs e){SetHook();Thread threadForeground = new Thread(ShowWindowAsync);//threadForeground.IsBackground = true;threadForeground.Start();}private void txt_KeyDown(object sender, KeyEventArgs e){_dtNow = DateTime.Now;}private void txt_KeyUp(object sender, KeyEventArgs e){if (e.KeyCode != Keys.Enter){DateTime dtTemp = DateTime.Now;TimeSpan ts = dtTemp.Subtract(_dtNow);if (ts.Milliseconds > 65){//setTool("错误:禁止手工输入!", "N");txt.Text = "";//清空}}}private void txtID_KeyPress(object sender, KeyPressEventArgs e){if (e.KeyChar == 13){//做些操作ClearHook();}}public static void SetWindowPos(IntPtr hWnd){//0x0010为不激活窗口,这个比较关键SetWindowPos(hWnd, -1, 0, 0, 0, 0, 0x0001 | 0x0002 | 0x0010);// 0x001 | 0x002 | 0x0010| 0x040}private void ShowWindowAsync(){while (true){//高版本的这里可以直接使用Action,更简化一些//ForegroundWin d = new ForegroundWin(action);//this.Invoke(d);Action a = new Action(() => { action(); });Thread.Sleep(100);//这个时间间隔,用户基本感觉不出有切换窗体}}void action(){IntPtr hWnd = this.Handle;if (hWnd != IntPtr.Zero || GetForegroundWindow() != hWnd){//选中当前的句柄窗口SetWindowPos(hWnd);//SendKeys.SendWait(" ");}}private void ClearHook() {//取消勾子if (_keyboardHook != null) _keyboardHook.UninstallHook();//MyHook.UnHook();//ProcessMgr.ResumeWinlogon();}private void SetHook() {//安装勾子_keyboardHook = new KeyboardHookLib();_keyboardHook.InstallHook(this.OnKeyPress);//MyHook.InsertHook();//ProcessMgr.SuspendWinlogon();}/// <summary>/// 客户端键盘捕捉事件./// </summary>/// <param name="hookStruct">由Hook程序发送的按键信息</param>/// <param name="handle">是否拦截</param>public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle){handle = false; //预设不拦截任何键if (hookStruct.vkCode == 91) // 截获左win(开始菜单键){handle = true;}if (hookStruct.vkCode == 92)// 截获右win{handle = true;}if ((int)Control.ModifierKeys == (int)Keys.Alt) //截获alt{handle = true;}//截获Ctrl+Escif (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control){handle = true;}//截获alt+f4if (hookStruct.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt){handle = true;}//截获alt+tabif (hookStruct.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt){handle = true;}//截获alt+tabif (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt){handle = true;}//截获F1if (hookStruct.vkCode == (int)Keys.F1){handle = true;}//截获Ctrl+Alt+Deleteif ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete){handle = true;}//如果键A~Zif (hookStruct.vkCode >= (int)Keys.A && hookStruct.vkCode <= (int)Keys.Z){//挡掉B键if (hookStruct.vkCode == (int)Keys.B)hookStruct.vkCode = (int)Keys.None; //设键为0handle = true;}Keys key = (Keys)hookStruct.vkCode;PubLibrary.WriteErrLog("你按下:" + (key == Keys.None ? "" : key.ToString()));}}
}

四、其他类

using System;
using System.Runtime.InteropServices;namespace ShareToolClass
{public class ShareTool : IDisposable{[DllImport("advapi32.dll", SetLastError = true)]static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,int dwLogonType, int dwLogonProvider, ref IntPtr phToken);// closes open handes returned by LogonUser       [DllImport("kernel32.dll", CharSet = CharSet.Auto)]extern static bool CloseHandle(IntPtr handle);[DllImport("Advapi32.DLL")]static extern bool ImpersonateLoggedOnUser(IntPtr hToken);[DllImport("Advapi32.DLL")]static extern bool RevertToSelf();const int LOGON32_PROVIDER_DEFAULT = 0;const int LOGON32_LOGON_NEWCREDENTIALS = 9;const int LOGON32_LOGON_INTERACTIVE = 2;private bool disposed;public ShareTool(string username, string password, string ip){// initialize tokens       IntPtr pExistingTokenHandle = new IntPtr(0);IntPtr pDuplicateTokenHandle = new IntPtr(0);try{// get handle to token       bool bImpersonated = LogonUser(username, ip, password,LOGON32_LOGON_NEWCREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);if (bImpersonated){if (!ImpersonateLoggedOnUser(pExistingTokenHandle)){int nErrorCode = Marshal.GetLastWin32Error();throw new Exception("ImpersonateLoggedOnUser error;Code=" + nErrorCode);}}else{int nErrorCode = Marshal.GetLastWin32Error();throw new Exception("LogonUser error;Code=" + nErrorCode);}}finally{// close handle(s)       if (pExistingTokenHandle != IntPtr.Zero)CloseHandle(pExistingTokenHandle);if (pDuplicateTokenHandle != IntPtr.Zero)CloseHandle(pDuplicateTokenHandle);}}protected virtual void Dispose(bool disposing){if (!disposed){RevertToSelf();disposed = true;}}public void Dispose(){Dispose(true);}}
}
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;namespace ProcessMgrClass
{class ProcessMgr{/// <summary>/// The process-specific access rights./// </summary>[Flags]public enum ProcessAccess : uint{/// <summary>/// Required to terminate a process using TerminateProcess./// </summary>Terminate = 0x1,/// <summary>/// Required to create a thread./// </summary>CreateThread = 0x2,/// <summary>/// Undocumented./// </summary>SetSessionId = 0x4,/// <summary>/// Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory)./// </summary>VmOperation = 0x8,/// <summary>/// Required to read memory in a process using ReadProcessMemory./// </summary>VmRead = 0x10,/// <summary>/// Required to write to memory in a process using WriteProcessMemory./// </summary>VmWrite = 0x20,/// <summary>/// Required to duplicate a handle using DuplicateHandle./// </summary>DupHandle = 0x40,/// <summary>/// Required to create a process./// </summary>CreateProcess = 0x80,/// <summary>/// Required to set memory limits using SetProcessWorkingSetSize./// </summary>SetQuota = 0x100,/// <summary>/// Required to set certain information about a process, such as its priority class (see SetPriorityClass)./// </summary>SetInformation = 0x200,/// <summary>/// Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob)./// </summary>QueryInformation = 0x400,/// <summary>/// Undocumented./// </summary>SetPort = 0x800,/// <summary>/// Required to suspend or resume a process./// </summary>SuspendResume = 0x800,/// <summary>/// Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION./// </summary>QueryLimitedInformation = 0x1000,/// <summary>/// Required to wait for the process to terminate using the wait functions./// </summary>Synchronize = 0x100000}[DllImport("ntdll.dll")]private static extern uint NtResumeProcess([In] IntPtr processHandle);[DllImport("ntdll.dll")]private static extern uint NtSuspendProcess([In] IntPtr processHandle);[DllImport("kernel32.dll", SetLastError = true)]private static extern IntPtr OpenProcess(ProcessAccess desiredAccess,bool inheritHandle,int processId);[DllImport("kernel32.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]private static extern bool CloseHandle([In] IntPtr handle);public static void SuspendProcess(int processId){IntPtr hProc = IntPtr.Zero;try{// Gets the handle to the ProcesshProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);if (hProc != IntPtr.Zero)NtSuspendProcess(hProc);}finally{// Don't forget to close handle you created.if (hProc != IntPtr.Zero)CloseHandle(hProc);}}public static void ResumeProcess(int processId){IntPtr hProc = IntPtr.Zero;try{// Gets the handle to the ProcesshProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);if (hProc != IntPtr.Zero)NtResumeProcess(hProc);}finally{// Don't forget to close handle you created.if (hProc != IntPtr.Zero)CloseHandle(hProc);}}public static void SuspendWinlogon(){Process[] processes = Process.GetProcesses();foreach (Process process in processes){if (process.ProcessName == "winlogon"){SuspendProcess(process.Id);}}}public static void ResumeWinlogon(){Process[] processes = Process.GetProcesses();foreach (Process process in processes){Console.WriteLine(process.ProcessName);if (process.ProcessName == "winlogon"){ResumeProcess(process.Id);}}}}
}

相关文章:

.NET的键盘Hook管理类,用于禁用键盘输入和切换

一、MyHook帮助类 此类需要编写指定屏蔽的按键&#xff0c;灵活性差。 using System; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using Microsoft.Win32;namespace MyHookClass {/// <summary>/// 类一/// </su…...

Anaconda Jupyter

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言An…...

Unity中Shader的前向渲染路径ForwardRenderingPath

文章目录 前言一、前向渲染路径的特点二、渲染方式1、逐像素(效果最好)2、逐顶点(效果次之)3、SH球谐(效果最差) 三、Unity中对灯光设置 后&#xff0c;自动选择对应的渲染方式1、ForwardBase仅用于一个逐像素的平行灯&#xff0c;以及所有的逐顶点与SH2、ForwardAdd用于其他所…...

简历项目优化关键方法论-START

START方法论是非常著名的面试法则&#xff0c;经常被面试官使用的工具 Situation:情况、事情、项目需求是在什么情况下发生Task:任务&#xff0c;你负责的做的是什么Action:动作&#xff0c;针对这样的情况分析&#xff0c;你采用了什么行动方式Result:结果&#xff0c;在这样…...

TensorFlow学习1:使用官方模型进行图片分类

前言 人工智能以后会越来越发达&#xff0c;趁着现在简单学习一下。机器学习框架有很多&#xff0c;这里觉得学习谷歌的 TensorFlow&#xff0c;谷歌的技术还是很有保证的&#xff0c;另外TensorFlow 的中文文档真的很友好。 文档&#xff1a; https://tensorflow.google.cn/…...

C++ 并发编程实战 第八章 设计并发代码 一

目录 8.1 在线程间切分任务 8.1.1 先在线程间切分数据&#xff0c;再开始处理 8.1.2 以递归方式划分数据 8.1.3 依据工作类别划分任务 借多线程分离关注点需防范两大风险 在线程间按流程划分任务 8.2 影响并发性能的因素 8.2.1 处理器的数量 8.2.2 数据竞争和缓存兵乓…...

设计模式8、装饰者模式 Decorator

解释说明&#xff1a;动态地给一个对象增加一些额外的职责。就扩展功能而言&#xff0c;装饰模式提供了一种比使用子类更加灵活的替代方案 抽象构件&#xff08;Component&#xff09;&#xff1a;定义一个抽象接口以规范准备收附加责任的对象 具体构件&#xff08;ConcreteCom…...

抖音开放平台第三方代小程序开发,一整套流程

大家好&#xff0c;我是小悟 抖音小程序第三方平台开发着力于解决抖音生态体系内的小程序管理问题&#xff0c;一套模板&#xff0c;随处部署。能尽可能地减少服务商的开发成本&#xff0c;服务商只用开发一套小程序代码作为模板就可以快速批量的孵化出大量的商家小程序。 第…...

Flutter笔记:滚动之-无限滚动与动态加载的实现(GetX简单状态管理版)

Flutter笔记 无限滚动与动态加载的实现&#xff08;GeX简单状态管理版&#xff09; 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq…...

前端架构师之02_ES6_高级

1 类和继承 1.1 class类 JavaScript 语言中&#xff0c;生成实例对象的传统方法是通过构造函数。 // ES5 创建对象 // 创建一个类&#xff0c;用户名 密码 function User(name,pass){// 添加属性this.name name;this.pass pass; } // 用 原型 添加方法 User.prototype.sho…...

VScode多文件编译/调试配置

之前都是在Visual Studio写C/C&#xff0c;最近想换到VScode&#xff0c;折腾半天把launch.json和tasks.json配好了&#xff08;虽然不懂为什么&#xff0c;但确实能用了&#xff09;&#xff0c;在此做个记录。 参考资料&#xff1a;1&#xff0c;2&#xff0c;3 环境&#…...

K折交叉验证——cross_val_score函数使用说明

在机器学习中&#xff0c;许多算法中多个超参数&#xff0c;超参数的取值不同会导致结果差异很大&#xff0c;如何确定最优的超参数&#xff1f;此时就需要进行交叉验证的方法&#xff0c;sklearn给我们提供了相应的cross_val_score函数&#xff0c;可对数据集进行交叉验证划分…...

2023.09.30使用golang1.18编译Hel10-Web/Databasetools的windows版

#Go 1.21新增的 log/slog 完美解决了以上问题&#xff0c;并且带来了很多其他很实用的特性。 本次编译不使用log/slog 包 su - echo $GOPATH ;echo $GOROOT; cd /tmp; busybox wget --no-check-certificate https://go.dev/dl/go1.18.linux-amd64.tar.gz;\ which tar&&am…...

React简介

react作为前端主流框架之一&#xff0c;因其语法接近原生JavaScript语法而广受欢迎。其生态丰富&#xff0c;常用的就有react-router、react-redux等插件&#xff0c;还有与其匹配的UI组件库antd。而且其还有用于移动端开发的react-native库&#xff0c;因此&#xff0c;react值…...

链表经典面试题(一)

面试题 1.反转链表的题目2.反转链表的图文分析3.反转链表的代码实现 1.反转链表的题目 2.反转链表的图文分析 我们在实现反转链表的时候,是将后面的元素变前面&#xff0c;前面的元素变后面&#xff0c;那么我们是否可以理解为&#xff0c;用头插法的思想来完成反转链表呢&…...

体验亚马逊的 CodeWhisperer 感觉

CodeWhisperer 是亚马逊推出的辅助编程工具&#xff0c;在程序员写代码时&#xff0c;它能根据其内容生成多种代码建议。 CodeWhisperer 目前已支持近10几种语言&#xff0c;我是用 java 语言&#xff0c;用的开发工具是 idea&#xff0c;说一下我用的情况。 亚马逊云科技开发…...

6、行内元素和块元素

6、行内元素和块元素 一、块元素 无论内容多少&#xff0c;该元素独占一行 如p标签、标题标签&#xff08;h1-h6…&#xff09; 二、行内元素 内容撑开宽度、左右都是行内元素的可以排在一行 一些元素如果能够摆放在一行都可以用行内元素&#xff0c;但是如果需要换行就需…...

LeetCode 面试题 08.01. 三步问题

文章目录 一、题目二、Java 题解 一、题目 三步问题。有个小孩正在上楼梯&#xff0c;楼梯有n阶台阶&#xff0c;小孩一次可以上1阶、2阶或3阶。实现一种方法&#xff0c;计算小孩有多少种上楼梯的方式。结果可能很大&#xff0c;你需要对结果模1000000007。 示例1: 输入&…...

[CSCCTF 2019 Qual]FlaskLight 过滤 url_for globals 绕过globals过滤

目录 subprocess.Popen FILE warnings.catch_warnings site._Printer 这题很明显就是 SSTI了 源代码 我们试试看 {{7*7}} 然后我们就开始吧 原本我的想法是直接{{url_for.__globals__}} 但是回显是直接500 猜测过滤 我们正常来吧 {{"".__class__}} 查看当前…...

1分钟快速实现Redis数据对比

在上篇「Redis高效、安全的不停机数据迁移方案」的文章中&#xff0c;介绍了NineData在Redis迁移场景下的性能和优势。因为数据在主备、多云和多区域环境之间的迁移流动&#xff0c;难免会产生数据一致性的问题&#xff0c;而结构与数据不一致往往是导致故障的原因之一。所以&a…...

ASUS华硕天选4笔记本电脑FX507VV原厂Windows11系统

下载链接&#xff1a;https://pan.baidu.com/s/1W9tedHI3iFjaHju5eLkQ6g?pwd8dl2 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、华硕电脑管家、奥创控制中心等预装程序 由于时间关系,绝大部分资料没有上传&#xff0c;不是想要的型号&#xff0c;请联系客服获取。...

Vue3配置路由

文章目录 一、创建index.js二、main.js的配置三、在App.vue中引入 一、创建index.js 在src文件夹中创建router文件夹&#xff0c;并在其中创建index.js文件 //引入路由对象 import { createRouter,createWebHistory } from vue-router import PufMac from "../views/puf…...

力扣 -- 97. 交错字符串

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:bool isInterleave(string s1, string s2, string s3) {int ms1.size();int ns2.size();//先判断s1的长度s2的长度是否等于s3的长度&#xff0c;如果不等&#xff0c;则s1和s2不可能拼接成s3if(mn!s3.size…...

【剑指Offer】4.二维数组中的查找

题目 在一个二维数组array中&#xff08;每个一维数组的长度相同&#xff09;&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该…...

独立按键控制LED亮灭、独立按键控制LED状态、独立按键控制LED显示二进制、独立按键控制LED移位——“51单片机”

各位CSDN的uu们你们好呀&#xff0c;今天依旧是小雅兰的51单片机的内容&#xff0c;内容主要是&#xff1a;独立按键控制LED亮灭、独立按键控制LED状态、独立按键控制LED显示二进制、独立按键控制LED移位&#xff0c;下面&#xff0c;让我们进入51单片机的世界吧&#xff01;&a…...

chrome extensions mv3通过content scripts注入/获取原网站的window数据

开发插件的都知道插件的content scripts和top window只共享Dom不共享window和其他数据&#xff0c;如果想拿挂载在window的数据还有点难度&#xff0c;下面会通过事件的方式传递cs和top window之间的数据写一个例子 代码 manifest.json 这里只搞了2个js&#xff0c;content.…...

震坤行API接口聚合解析,实现根据ID取商品详情

震坤行是一个工业品服务平台&#xff0c;提供了API接口供开发者使用。要根据ID获取商品详情&#xff0c;您需要使用震坤行API接口并进行相应的请求。 以下是使用震坤行API接口根据ID获取商品详情的示例代码&#xff08;使用Python编写&#xff09;&#xff1a; import reques…...

mencpy和strcpy的区别?

今天刷题时遇到了这个问题&#xff0c;记录一下。 strcpy比较简单&#xff0c;就是拷贝字符串&#xff0c;遇到\0时结束拷贝。 memcpy用来做内存拷贝&#xff0c;可以拷贝任何数据类型的对象并指定拷贝数据的长度&#xff1a;char a[100],b[50]; memcpy(b, a, sizeof(b)); 总结…...

机器人过程自动化(RPA)入门 8. 异常处理、调试和日志记录

有时,自动化程序可能无法执行。为了处理此类情况,我们使用异常处理活动。在本章中,我们将从UiPath中可用的各种类型的异常处理方法、您可能遇到的异常以及如何处理它们开始。我们还将学习日志记录。本章涉及的一个重要主题是调试,以检查工作流是否正常工作,并更正任何错误…...

tomcat总结笔记

文章目录 Tomcat1、什么是tomcat?2、rpm安装jre环境3、源码安装jdk环境4、安装tomcat --源码安装5、相关目录文件webappsTomcat 配置文件目录介绍&#xff08;conf&#xff09;tomcat的相关管理命令在$prefix/bin目录下 实战1、&#xff1a;配置nginx动静分离实战2、配置基于t…...

怎样推广自己做的网站/链接怎么做

1.显示语法规范 show ( [ speed, [easing], [fn]]) hide ( [ speed, [easing], [fn]]) toggle ( [ speed, [easing], [fn]]) 显示参数 (1)参数都可以省略&#xff0c;无动画直接显示。 (2) speed:三种预定速度之一 的字符串( "slow" &#xff0c;"normal" …...

还有哪些媲美wordpress框架/百度推广入口登录

前言 昨天XY讲课&#xff01;讲到这题&#xff01;还是IOI的题&#xff01;不过据说00年的时候DP还不流行。 题面 http://poj.org/problem?id1160 分析 1 中位数 首先我们考虑&#xff0c;若有x1 < x2 < ... < xn&#xff0c;则当∑abs(x - xi)最小时&#xff0c;x为…...

分析企业网站建设流程/微博今日热搜榜

先说说localStorage与sessionStorage的差别 sessionStorage是存储浏览器的暂时性的数据&#xff0c;当关闭浏览器下次再打开的时候就不能拿到之前存储的缓存了 localStorage是存储浏览器的永久数据&#xff0c;只要不去自己清除数据&#xff0c;你下次打开时依然可以拿到浏览器…...

樟木头的建网站公司/网域名查询地址

内容简介 树莓派单板机(Raspberry Pi Single Computer)是一种极了不起的产品&#xff0c;用户可以以非常低的成本获得一个Linux环境并带GPIO硬件扩展的迷你计算机系统。新一代树莓派4B还提供了良好的工业物联网和AIoT支持。树莓派单板机拥有完整的生态链&#xff0c;软硬件资源…...

国外直播做游戏视频网站有哪些/软文发稿网

大致思路&#xff1a; 题意大概就是&#xff1a;一个环上N个站点&#xff0c;每个站点可以加油gas[i]&#xff0c;每个站点到其下一个站点要消耗cost[i]&#xff0c;问你能否找到一个起点能够走过环上所有点&#xff08;终点起点&#xff09; 思路就是&#xff0c;可以理解到…...

山东淄博网站建设/培训班该如何建站

Http Module概述暂时先不考虑我们自己实现Http Module的情况。在.Net中&#xff0c;Http Module 是实现了IHttpModule接口的程序集。IHttpModule 接口本身并没有什么好大写特写的&#xff0c;由它的名字可以看出&#xff0c;它不过是一个普普通通的接口而已。实际上&#xff0c…...