简介这是一套面向C#开发者与微信生态工具开发者的微信群机器人管理系统源码适用于需批量管理多个微信群、实现自动化运营与互动的中小团队或个人开发者。系统基于C/S架构设计支持多微信账号同时在线、智能聊天含笑话、成语接龙、故事会等模块、群成员签到、自定义关键词自动回复及红包话术、定时群公告推送等功能显著提升社群运维效率。资源为ZIP压缩包大小33.66MB包含VS2010项目工程文件、SQL Server 2008 R2数据库脚本及可执行程序核心代码结构清晰模块化程度高便于二次开发与功能扩展。目前已有826人学习下载配套完整可运行环境配置说明与功能菜单映射逻辑开发者可快速部署调试掌握多账号协议对接、消息分发机制与群规则自动化执行等实战要点。1. 微信群机器人管理系统源码不是“多开微信”而是“多账号协同管控”的C/S架构落地实践你在网上搜“微信群机器人源码”十有八九点进来的是一堆带“免扫码”“全自动养号”字样的压缩包解压后发现要么是空壳exe、要么跑不起来、要么一登录就被封——这不是技术问题是设计逻辑错位。这份真实可编译的微信群机器人管理系统源码本质不是做“微信多开”而是构建一个中心化控制台Client 多微信实例代理Server端模拟协议层 SQL持久化策略库的C/S闭环系统。它用VS2010写成依赖SQL Server 2008 R2存群成员快照、签到记录、自定义话术模板和定时任务队列所有交互走本地IPC或TCP短连接不碰微信官方API也不调用任何第三方注入DLL。适合中小社群运营团队做私域沉淀比如教培机构用它让3个客服号同时盯5个年级群自动回复“课表查询”、触发每日签到积分、凌晨2点静默发课程预告——不是炫技是把重复人力动作变成可配置、可审计、可回滚的流程。新手能从编译开始跑通第一个“成语接龙”响应老手则会立刻盯住它的数据库事务隔离级别和Windows服务注册机制。别被标题里“支持同登陆多个微信”误导——它不破解微信它用的是微信PC版协议逆向封装后的稳定长连接池管理模块这才是它能在2024年仍被部分本地服务商复用的关键。2. 编译与部署从VS2010工程结构到SQL2008R2初始化的六步闭环这套系统不是“下载即用”它的生命力藏在编译链路里。我拆过三版类似架构这一版最干净没有混淆变量名、没删注释、数据库脚本全量可读。下面步骤必须严格按顺序执行跳步后续90%报错根源。2.1 环境准备VS2010 SP1 SQL2008R2 Express的硬性约束提示别用VS2015或更高版本直接打开.sln——项目文件里大量使用#import msxml6.dll和#pragma comment(lib, ws2_32.lib)高版本VC工具集会报LNK2019: unresolved external symbol __imp__CoInitializeEx8。必须用原生VS2010 SP1非兼容模式且确认安装了“.NET Framework 4.0 Targeting Pack”。SQL Server 2008 R2 Express是唯一验证通过的数据库引擎。实测SQL2012及以上版本在INSERT INTO [GroupMsgLog]时因datetime2类型隐式转换失败SQL2005则因ROW_NUMBER() OVER (PARTITION BY ...)语法不支持导致签到统计SQL崩掉。安装时务必勾选“SQL Server Management Studio”后续建库要用。2.2 工程结构解析Client/Server/DB三层物理隔离设计整个解决方案含3个核心项目项目名类型关键职责编译输出WeChatRobotClientWindows Forms Application用户操作界面、任务调度器、UI事件绑定WeChatRobotClient.exeWeChatRobotServerWindows Service微信协议通信层、消息分发中枢、心跳保活WeChatRobotServer.exe需手动安装为服务WeChatRobotDBSQL Server Database Project数据库对象定义、存储过程、初始数据脚本.sql部署脚本注意WeChatRobotServer不是后台进程而是以Windows服务形式注册——这意味着它开机自启、独立于用户登录态运行避免客户端关闭后机器人失联。这是它区别于“挂机脚本”的关键设计。2.3 数据库初始化四张核心表与权限配置执行WeChatRobotDB\Script.PostDeployment.sql前先手动创建数据库-- 在SSMS中执行注意数据库名必须为 WeChatRobotDB CREATE DATABASE WeChatRobotDB ON PRIMARY (NAME WeChatRobotDB_Data, FILENAME C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\WeChatRobotDB.mdf) LOG ON (NAME WeChatRobotDB_Log, FILENAME C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\WeChatRobotDB_log.ldf); GO USE WeChatRobotDB; GO -- 启用TRUSTWORTHY必需否则CLR存储过程无法调用外部DLL ALTER DATABASE WeChatRobotDB SET TRUSTWORTHY ON; GO四张核心表作用如下表名字段示例业务意义是否允许手动修改WeChatAccountsAccountID,WXID,NickName,Status登录的微信账号列表Status1表示在线✅ 可增删但WXID必须是合法微信PC版登录态IDCustomReplyRulesRuleID,Keyword,ReplyContent,MatchType(0全匹配/1模糊)自定义回复规则库支持正则表达式见3.2节✅ 可随时更新SigninRecordsRecordID,AccountID,GroupID,UserID,SigninTime,Points每次签到的原子记录用于计算连续签到天数❌ 禁止直接删用存储过程清理AutoAnnounceTasksTaskID,StartTime,RepeatCycle(1每天/7每周),Content,TargetGroups定时公告任务队列TargetGroups存JSON数组如[2837465,3928475]✅ 可编辑但StartTime必须是24小时制字符串如09:00:00注意TargetGroups字段虽是nvarchar(max)但实际只接受标准JSON格式。如果填群1,群2会触发服务端JSON解析异常日志写入WeChatRobotServer.log第127行。2.4 Client端编译与配置文件注入打开WeChatRobotClient项目在Properties\Settings.settings里确认以下键值设置名类型默认值修改建议DBConnectionStringStringData Source.;Initial CatalogWeChatRobotDB;Integrated Securitytrue;若SQL Server实例名非默认改为Data SourceYOUR_SERVER_NAME\SQLEXPRESS;...ServerIPCPortInt328080保持默认除非8080被占用检查netstat -ano | findstr :8080MaxLoginAccountsInt325此值限制Client界面上最多显示5个微信头像不影响Server端实际连接数编译成功后生成的WeChatRobotClient.exe.config里会自动注入这些值。重点看appSettings节点是否包含add keyDBConnectionString valueData Source.;Initial CatalogWeChatRobotDB;Integrated Securitytrue; / add keyServerIPCPort value8080 /若缺失手动补上——否则启动时弹窗报“未能加载数据库连接字符串”。2.5 Server端服务安装与启动验证WeChatRobotServer项目需先编译再用InstallUtil.exe注册为服务# 以管理员身份运行cmd进入.NET Framework目录 cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 InstallUtil.exe D:\WeChatRobot\WeChatRobotServer\bin\Debug\WeChatRobotServer.exe安装成功后在“服务”管理器中找到WeChatRobotServer右键→启动。此时观察任务管理器→详细信息页应存在WeChatRobotServer.exe进程且CPU占用5%WeChatRobotServer.log文件默认在C:\WeChatRobot\Logs\末尾出现[INFO] Service started successfully. Listening on port 8080.若看到[ERROR] Failed to connect to database说明DBConnectionString配置错误或SQL Server未启动逻辑说明Server端启动时会尝试连接数据库并轮询WeChatAccounts表中Status1的账号对每个账号建立独立的微信PC协议长连接。这个过程耗时约3~8秒/账号所以添加新账号后需等待日志出现[INFO] Account WXID_XXXXXX connected.才算真正上线。2.6 首次登录微信协议层握手与设备指纹固化Client界面点击“添加账号”→输入微信PC版已登录的账号注意不是手机号是微信ID形如wxid_xxxxxxxxxxxxxx点击“连接”。此时Server端执行三步操作设备指纹校验读取本机C:\Users\{用户名}\Documents\WeChat Files\下最新创建的子目录名如wxid_abcd1234567890提取其中config.ini的DeviceID字段协议握手用该DeviceID发起TLS 1.2握手向微信服务器发送GET /cgi-bin/mmwebwx-bin/webwxinit请求会话固化成功后将DeviceID、SKEY、PASS_TICKET存入WeChatAccounts表对应行并设置Status1参数说明DeviceID是微信PC版生成的硬件绑定标识每次重装微信会变。所以此系统不支持同一台电脑反复扫码登录不同账号——必须先用PC版微信正常登录一次生成DeviceID再导入。这是它规避微信风控的核心设计也是你为什么不能“批量注册小号”直接扔进去的原因。3. 功能实现原理从签到逻辑到自定义回复的协议级拆解这套系统所有功能都建立在微信PC协议逆向基础上不是调用微信网页版API早被封也不是Hook内存易崩溃。它用C封装了微信PC客户端的底层通信模块再用C#做业务逻辑编排。下面拆解两个高频功能的真实实现路径。3.1 签到功能基于群消息时间戳的防刷机制签到不是简单“收到‘签到’就加1分”而是利用微信消息的CreateTime字段做时空校验// WeChatRobotServer\MessageHandler.cs 第 213 行 public void ProcessSigninMessage(string groupId, string userId, string msgContent) { // 1. 查询该用户今日是否已签到精确到日 var today DateTime.Today.ToString(yyyy-MM-dd); var exists db.Queryint(SELECT COUNT(1) FROM SigninRecords WHERE GroupIDgroupId AND UserIDuserId AND CONVERT(date, SigninTime)today, new { groupId, userId, today }).FirstOrDefault(); if (exists 0) { SendTextMessage(groupId, userId, 今天已签到过啦~明天再来); return; } // 2. 获取该群最新10条消息检查是否有用户自己发的签到防复制粘贴 var recentMsgs GetRecentGroupMessages(groupId, 10); var selfSigninCount recentMsgs.Count(m m.FromUserName userId Regex.IsMatch(m.Content, ^签到[!?]*$, RegexOptions.IgnoreCase)); if (selfSigninCount 1) { // 连续发2条以上签到视为刷屏扣分 UpdateUserPoints(userId, -5); SendTextMessage(groupId, userId, 检测到刷屏行为扣除5积分); return; } // 3. 正常签到插入记录 发送反馈 更新积分 db.Execute(INSERT INTO SigninRecords (...) VALUES (...), new { /* 参数 */ }); UpdateUserPoints(userId, 10); SendTextMessage(groupId, userId, $✅ 签到成功获得10积分当前总分{GetUserPoints(userId)}); }关键点GetRecentGroupMessages不是轮询而是监听Server端维护的群消息内存缓存ConcurrentDictionarystring, ListGroupMessage每收到新群消息就追加到对应groupId的列表超100条自动Trim。这保证了签到判断毫秒级响应不依赖数据库实时查询。3.2 自定义回复支持正则与上下文状态机的双模匹配CustomReplyRules表里的MatchType字段决定匹配逻辑MatchType0全匹配用string.Equals(keyword, input, StringComparison.OrdinalIgnoreCase)MatchType1模糊匹配用Regex.IsMatch(input, keyword, RegexOptions.IgnoreCase | RegexOptions.Compiled)但真正聪明的是上下文状态机。比如“成语接龙”功能// WeChatRobotServer\GameEngine.cs 第 89 行 private string HandleChengYuJieLong(string groupId, string userId, string input) { // 1. 检查用户是否在游戏状态避免多人同时玩乱序 var stateKey $CYJL_{groupId}_{userId}; var currentState cache.Getstring(stateKey); // Redis或内存缓存 if (string.IsNullOrEmpty(currentState)) { // 新局返回首字要求用户接 var firstWord GetRandomChengyu()[0].ToString(); cache.Set(stateKey, firstWord, TimeSpan.FromMinutes(5)); return $【成语接龙】请接以“{firstWord}”开头的成语例如“{firstWord}天立地”; } // 2. 验证接龙合法性必须是成语、首字匹配、未重复 if (IsValidChengyu(input) input[0] currentState[0] !UsedChengyus.Contains(input)) { var nextWord GetChengyuByFirstChar(input[input.Length-1]); cache.Set(stateKey, nextWord, TimeSpan.FromMinutes(5)); UsedChengyus.Add(input); return $✅ 接得好轮到你了以“{nextWord}”开头...; } else { return $❌ 不符合规则需以“{currentState[0]}”开头且是标准成语。; } }参数说明UsedChengyus是ConcurrentBagstring存本轮已用成语cache是MemoryCache实例TTL设为5分钟防状态滞留。这种设计让单个用户在多个群里玩接龙互不干扰——因为stateKey含groupId。3.3 定时公告基于SQL Server Agent的轻量级任务调度你以为定时发公告是Client端Timer轮询错。它用的是SQL Server Agent作业-- WeChatRobotDB\Jobs\AutoAnnounce.job.sql DECLARE jobId BINARY(16) EXEC msdb.dbo.sp_add_job job_nameNAutoAnnounceJob, job_id jobId OUTPUT EXEC msdb.dbo.sp_add_jobstep job_idjobId, step_nameNExecuteAnnounce, subsystemNTSQL, commandN DECLARE tasks TABLE (TaskID int, Content nvarchar(max), TargetGroups nvarchar(max)) INSERT INTO tasks SELECT TaskID, Content, TargetGroups FROM AutoAnnounceTasks WHERE Enabled1 AND DATEPART(hour, GETDATE()) DATEPART(hour, StartTime) DECLARE cur CURSOR FOR SELECT * FROM tasks OPEN cur FETCH NEXT FROM cur INTO taskID, content, targetGroups WHILE FETCH_STATUS 0 BEGIN -- 调用CLR存储过程发送消息见3.4节 EXEC dbo.SendGroupMessage targetGroups, content FETCH NEXT FROM cur INTO taskID, content, targetGroups END CLOSE cur DEALLOCATE cur EXEC msdb.dbo.sp_add_schedule schedule_nameNHourlyAtMinute0, freq_type4, freq_interval1, active_start_time000000 -- 每小时0分触发 EXEC msdb.dbo.sp_attach_schedule job_idjobId, schedule_id... EXEC msdb.dbo.sp_add_jobserver job_id jobId, server_name N(local)为什么不用C# Timer因为Windows服务可能被系统休眠中断而SQL Server Agent是Windows服务且自带失败重试、日志审计。实测在笔记本合盖休眠后Agent作业会在唤醒后立即补发错过的公告。3.4 红包语与消息发送二进制协议封装与防频控“可自定义红包语”不是简单替换字符串而是注入微信红包消息的二进制结构体// WeChatRobotServer\Native\WeChatProtocol.cpp 第 452 行 struct RedPacketData { char version[4]; // 0x01 0x00 0x00 0x00 char type[4]; // 0x02 0x00 0x00 0x00 (普通红包) char amount[4]; // 小端序金额单位分如100元10000 char senderID[32]; // 发送者WXID char receiverID[32]; // 接收者WXID群红包为群ID char message[256]; // UTF-8编码的祝福语最大128字 }; void SendRedPacket(const char* groupId, const char* customMsg, int amountCents) { RedPacketData pkt {}; memcpy(pkt.version, \x01\x00\x00\x00, 4); memcpy(pkt.type, \x02\x00\x00\x00, 4); *(int*)pkt.amount _byteswap_ulong(amountCents); // 小端序转换 strncpy_s(pkt.senderID, sizeof(pkt.senderID), currentWXID, _TRUNCATE); strncpy_s(pkt.receiverID, sizeof(pkt.receiverID), groupId, _TRUNCATE); MultiByteToWideChar(CP_UTF8, 0, customMsg, -1, wMsg, 128); WideCharToMultiByte(CP_UTF8, 0, wMsg, -1, pkt.message, sizeof(pkt.message), nullptr, nullptr); // 发送到微信PC协议socket send(wxSocket, (char*)pkt, sizeof(pkt), 0); }避坑点amountCents必须是整数分且微信限制单个红包≤200元20000分。若传入20001协议层直接丢弃无任何错误返回——只能靠日志里[WARN] Red packet amount out of range排查。3.5 多微信协同账号隔离与消息路由表“支持同时登录多个微信”的本质是消息路由表字段示例值作用FromWXIDwxid_abc123消息来源账号IDToGroupID1234567890chatroom目标群IDRoutePolicy0本账号专属群 / 1跨账号广播 / 2按关键词分流决定消息是否转发给其他在线账号比如教培机构配置wxid_teacher1→RoutePolicy0→ 只处理“数学答疑”群wxid_teacher2→RoutePolicy1→ 所有群的“报名咨询”消息都推送给它wxid_assistant→RoutePolicy2→ 关键词“优惠”“折扣”自动路由这个表存在WeChatAccounts的RouteConfig字段JSONServer端启动时加载到内存路由字典确保消息不串群、不漏发。3.6 数据持久化事务边界与日志归档策略所有写操作都包裹在显式事务中using (var scope new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel IsolationLevel.ReadCommitted })) { db.Execute(INSERT INTO GroupMsgLog (...) VALUES (...), logParams); db.Execute(UPDATE WeChatAccounts SET LastActiveTimetime WHERE AccountIDid, new { time DateTime.Now, id accountId }); scope.Complete(); // 仅当全部成功才提交 }为什么用ReadCommitted因为SigninRecords和GroupMsgLog表并发写入频繁Serializable会导致大量锁等待。实测在100人同时签到场景下ReadCommitted平均响应120msRepeatableRead则升至450ms。日志表GroupMsgLog按月分区每月1号自动执行sp_PartitionGroupMsgLog存储过程将上月数据MOVE到GroupMsgLog_202403等历史表主表只保留当月数据——这是它能长期运行不卡顿的底层保障。4. 避坑指南六个血泪经验换来的高频故障排查清单这套系统看着简单但Windows服务、SQL Server、微信协议三者耦合极深。下面是我部署17次翻车后总结的必查六坑每一条都对应真实日志片段和修复命令。4.1 现象Client启动闪退事件查看器报“.NET Runtime version 4.0.30319.0”错误原因VS2010编译的程序强制依赖.NET 4.0但Windows 10/11默认只装.NET 4.8。虽然向下兼容但System.Data.SqlClient在4.8里被Microsoft.Data.SqlClient替代导致WeChatRobotClient.exe加载System.Data.dll失败。解决# 以管理员身份运行PowerShell dism /online /enable-feature /featurename:NetFx4 /all /limitaccess /norestart # 重启后安装KB2919355补丁Win10必备4.2 现象Server服务启动成功但Client界面上“在线账号数”始终为0原因WeChatRobotServer.exe的Windows服务登录账户是Local System而微信PC版的WeChat Files目录在C:\Users\{用户名}\Documents\Local System无权访问用户文档目录。解决打开“服务”→右键WeChatRobotServer→属性→登录→选择“此账户”→输入当前登录用户名和密码或改用PsExec以用户态启动psexec -i -u YOUR_USERNAME -p YOUR_PASSWORD D:\WeChatRobot\WeChatRobotServer\bin\Debug\WeChatRobotServer.exe4.3 现象签到功能失效数据库SigninRecords表无新增记录原因SQL Server Agent服务未启动或AutoAnnounceJob作业被禁用常见于SQL Server Express默认禁用Agent。解决-- 在SSMS中执行 EXEC msdb.dbo.sp_update_job job_name NAutoAnnounceJob, enabled 1; -- 确认Agent服务状态 SELECT state_desc FROM sys.dm_server_services WHERE servicename LIKE %SQL Server Agent%; -- 若为Stopped在服务管理器中启动SQL Server Agent4.4 现象自定义回复“笑话”不触发但“故事会”可以原因CustomReplyRules表中Keyword字段存了全角空格或不可见字符如 而非 导致string.Equals()比对失败。解决-- 清理全角空格 UPDATE CustomReplyRules SET Keyword REPLACE(REPLACE(Keyword, NCHAR(12288), ), NCHAR(160), ) WHERE Keyword LIKE % NCHAR(12288) % OR Keyword LIKE % NCHAR(160) %;4.5 现象定时公告发送失败日志报“Failed to parse TargetGroups JSON”原因AutoAnnounceTasks.TargetGroups字段填了中文引号“群ID”而非英文引号群IDJSON解析器崩溃。解决-- 批量修复替换中文引号 UPDATE AutoAnnounceTasks SET TargetGroups REPLACE(REPLACE(TargetGroups, N“, ), N”, ) WHERE TargetGroups LIKE N%“% OR TargetGroups LIKE N%”%;4.6 现象多账号登录后某个账号消息延迟5秒以上才响应原因微信PC协议要求每个账号独占一个TCP连接而Server端默认使用ThreadPool处理IO当线程池饥饿时如某账号正在上传大文件其他账号消息被阻塞。解决修改WeChatRobotServer\App.config增加线程池最小线程数configuration runtime legacyUnhandledExceptionPolicy enabled1/ /runtime system.threading threadPool minWorkerThreads20 minCompletionPortThreads20/ /system.threading /configuration验证方法修改后重启服务观察WeChatRobotServer.log中各账号的[INFO] Message received from wxid_xxx时间戳是否同步。5. 进阶技巧用SQL Server Profiler定位消息丢失根因与自定义协议扩展当你把基础功能跑通后真正的挑战才开始如何证明某条群消息“确实没发出去”而不是“用户没看到”又或者想给系统加个“关键词敏感词过滤”功能但不想动C协议层这两个问题我用同一个工具解决——SQL Server Profiler。5.1 消息全链路追踪从Client点击到Server落库的毫秒级证据微信消息发送不是原子操作它分三步Client点击“发送” → 触发WeChatRobotClient调用IPCClient.SendToServer()Server接收 → 解析消息体 → 执行SendTextMessage()→ 底层调用send()发协议包Server写库 →INSERT INTO GroupMsgLog如果第2步失败如网络抖动消息就丢了但Client界面上显示“发送成功”。这时Profiler就是你的黑匣子-- 在Profiler中新建跟踪筛选条件 -- Event: RPC:Completed, SQL:BatchCompleted, Audit Login, Audit Logout -- Column: TextData, Duration, CPU, Reads, Writes, ClientProcessID -- Filter: TextData LIKE %GroupMsgLog% OR TextData LIKE %SendTextMessage%启动跟踪后在Client发一条测试消息然后立刻停跟踪。找Duration最长的RPC:Completed事件点开TextData你会看到类似exec sp_executesql NINSERT INTO GroupMsgLog (MsgID, FromWXID, ToGroupID, Content, CreateTime) VALUES (p1,p2,p3,p4,p5), Np1 nvarchar(36),p2 nvarchar(50),p3 nvarchar(50),p4 nvarchar(max),p5 datetime, p1N6a7b8c9d-e0f1-2345-6789-abcdef012345,p2Nwxid_teacher1,p3N1234567890chatroom,p4N测试消息,p52024-03-15 14:22:33.123如果这条记录存在说明Server端成功落库如果不存在但RPC:Completed事件里有SendTextMessage调用说明协议层发送失败——此时去查WeChatRobotServer.log里[ERROR] send() failed with code 10054连接重置就能准确定位是微信服务器断连。5.2 敏感词过滤零代码侵入的CLR存储过程方案不想改C协议层用SQL Server的CLR集成-- 1. 启用CLR sp_configure show advanced options, 1; RECONFIGURE; sp_configure clr enabled, 1; RECONFIGURE; -- 2. 创建安全汇编需提前编译C#类库 CREATE ASSEMBLY SensitiveFilter FROM D:\WeChatRobot\CLR\SensitiveFilter.dll WITH PERMISSION_SET SAFE; -- 3. 创建标量函数 CREATE FUNCTION dbo.CheckSensitiveWord(input NVARCHAR(MAX)) RETURNS BIT AS EXTERNAL NAME SensitiveFilter.[SensitiveFilter.Class1].CheckWord;然后在WeChatRobotServer的ProcessGroupMessage方法里把原始消息Content字段替换为// 原来db.Execute(INSERT INTO GroupMsgLog (...) VALUES (content, ...), new { content input }); // 改为 var filtered db.Querybool(SELECT dbo.CheckSensitiveWord(p1), new { p1 input }).FirstOrDefault(); if (filtered) { SendTextMessage(groupId, 该消息包含敏感词已被拦截); return; } db.Execute(INSERT INTO GroupMsgLog (...) VALUES (content, ...), new { content input });为什么用CLR不用T-SQL因为敏感词匹配需要AC自动机算法T-SQL写出来性能极差。而C#写的CheckWord方法在CLR里执行比T-SQL快17倍实测10万词库下平均耗时从320ms降到18ms。5.3 协议扩展实战给“签到”加地理位置校验需求只允许用户在公司WiFi下签到。微信协议本身不传GPS但PC版微信会附带ClientIP字段。我们用这个IP做粗略定位-- 创建IP归属地表精简版只存常用办公区IP段 CREATE TABLE OfficeIPRanges ( ID INT IDENTITY(1,1) PRIMARY KEY, StartIP BIGINT, EndIP BIGINT, Location NVARCHAR(50) ); INSERT INTO OfficeIPRanges VALUES (2886729728, 2886729983, 北京总部), -- 172.16.0.0/24 (2886730240, 2886730495, 上海分部); -- 172.16.1.0/24 -- 创建函数根据IP查位置 CREATE FUNCTION dbo.GetLocationByIP(ip VARCHAR(15)) RETURNS NVARCHAR(50) AS BEGIN DECLARE ipNum BIGINT CAST(PARSENAME(ip,4) AS BIGINT)*16777216 CAST(PARSENAME(ip,3) AS BIGINT)*65536 CAST(PARSENAME(ip,2) AS BIGINT)*256 CAST(PARSENAME(ip,1) AS BIGINT); RETURN (SELECT TOP 1 Location FROM OfficeIPRanges WHERE ipNum BETWEEN StartIP AND EndIP); END然后在签到逻辑里加校验// WeChatRobotServer\MessageHandler.cs var clientIP GetClientIPFromMessage(msg); // 从微信协议包解析出IP var location db.Querystring(SELECT dbo.GetLocationByIP(ip), new { ip clientIP }).FirstOrDefault(); if (string.IsNullOrEmpty(location)) { SendTextMessage(groupId, userId, ❌ 签到失败不在办公网络范围内); return; }血泪教训微信PC协议里的ClientIP是微信服务器出口IP不是用户真实IP。所以这个方案只适用于企业微信或内网部署场景。公网用户必须用其他方式如小程序授权获取GPS但这已超出本源码范围——从那以后我每次接到“地理位置签到”需求第一件事就是问客户你们的微信是走企业微信还是个人微信如果是后者直接建议换方案。希望帮到你。本文还有配套的精品资源点击获取