
前一阵子在现场调试一套基于WinCC的上位机系统画面里放了一个在线趋势控件结果一运行就弹“许可证缺失”按钮全灰没法操作。当时第一反应是授权没装好可查了一圈西门子授权管理器授权明明都在后来才意识到问题出在WinCC ActiveX控件本身的许可证注册而不是软件授权。顺着注册表和系统兼容性两条线查下去才把问题彻底按死。这篇东西不是教科书式的原理讲解是我实际排查这个故障时走过的完整链路包括注册表键值定位、权限修复、64位系统下的重定向问题以及系统兼容性层面的坑。如果你也在WinCC画面里被ActiveX控件“许可证缺失”折磨或者正在做上位机部署和运维按我这套思路走一遍大概率能省下两三天时间。1. 故障现象盘点许可证缺失报错在哪些场景最容易冒出来1.1 控件类型与报错窗口的两种典型形态先搞清楚对手是谁。WinCC里常见的ActiveX控件包括在线趋势控件WinCC OnlineTrendControl、报警控件WinCC AlarmControl、用户归档控件WinCC UserArchiveControl、函数趋势控件WinCC FunctionTrendControl以及大量第三方或者自制的ActiveX控件。它们的共同点就是运行时需要从系统注册表读取许可证信息读不到就罢工。报错形态大概分两种设计态报错在Graphics Designer里往画面拖控件时直接弹出对话框说控件的许可证缺失或者许可证无效这个控件根本放不到画面上。运行态报错画面组态时一切正常但项目激活运行后控件区域出现红叉、灰块或者弹一个“无法创建ActiveX控件”之类的错误。这两种形态的排查方向不一样。设计态报错大概率是控件的许可证键值没写入注册表或者被清理工具干掉了。运行态报错则更复杂有可能是权限不够、DLL注册状态异常、甚至兼容性设置把控件实例化给拦了。我这次遇到的问题就属于第二种而且它是“时好时坏”的开机第一次跑正常运行一阵子再激活画面就报缺失。1.2 哪些误操作会直接触发“许可证缺失”结合我自己和身边同事踩过的坑下面这些操作都很容易把ActiveX控件许可证弄丢使用各种“垃圾清理大师”清理注册表ActiveX控件的License键经常被当成无效条目清掉。把WinCC项目从一台机器拷贝到另一台机器项目文件能拷过去但控件DLL、OCX和对应注册表信息不会跟着走。从32位系统往64位系统迁移或者反过来涉及注册表重定向问题许可证键在另一个视图下面程序读不到。杀毒软件查杀或隔离控件文件控件的DLL都没了自然谈不上许可证。长期用普通用户权限运行WinCC许可证键值明明存在但当前用户没有读取权限程序就当成“缺失”。某些远程桌面或终端服务会话中ActiveX控件被会话隔离也会出现类似提示。你可能会问产品授权Net/License Key都正常为什么ActiveX控件还说缺许可证这里的关键就是“许可证”这个词在不同层面的含义不一样。产品授权的License Key管的是软件能不能运行而ActiveX控件要的许可是控件自身的许可信息存在注册表里跟软件授权没有一一对应关系。你就算把授权装得再全注册表里的控件许可证没了照样报错。2. 许可证信息到底存在哪里注册表相关机制拆解2.1 ActiveX许可证机制与WinCC控件注册表键值分布ActiveX控件本质是COM组件当一个控件被设置为“Licensed”时它必须在注册表里保存一条许可记录。操作系统或者应用程序创建控件实例时会读取这条记录验证是否有效。有效才允许创建否则就返回“许可证缺失”。这条许可记录通常放在注册表的Licenses键下面。打开注册表编辑器一般能看到的路径类似HKEY_CLASSES_ROOT\Licenses在这个键下面每一个子键的键名就是控件的CLSIDClass ID全局唯一类标识符键值是一串编码后的许可证字符串。除了这里许可证相关的信息有时也会出现在HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Licenses以及HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Licenses等位置不同操作系统、不同产品版本分布差异很大。WinCC在安装ActiveX控件时安装程序会调用控件的自注册逻辑把CLSID、TypeLib、License等条目写入注册表。正常情况下这一系列动作是自动完成的。但如果安装过程被中断或者安装时被安全软件拦截控件注册到一半CLSID有了License键没有后面使用时就报缺失。明白了这个机制你就能理解为什么有时候修复安装都没用repair会把文件重新拷一遍但如果它认为文件完整无损就不一定会重新写入License键。这就是为什么遇到这种情况时注册表层面的人工检查和修复往往是更直接的突破口。2.2 注册表权限不足导致的“伪缺失”还有一种更隐蔽的情况键值明明在但程序就是读不到。这种“伪缺失”多半是注册表权限问题。Windows注册表的每个键都有自己的ACL访问控制列表不是所有用户都能读写所有键。有些ActiveX控件在安装时许可证键只给了Administrator和SYSTEM完全控制权普通Users组只有读取权甚至没有读取权。如果你的WinCC是以服务方式运行服务账户可能压根不在ACL里那在运行时创建控件就会失败。我之前就栽在权限上注册表编辑器里打开Licenses键清清楚楚能看到许可证字符串但用普通域账户登录运行WinCC就是报缺失。后来用Process Monitor一抓发现控件进程对那个键的RegOpenKey操作被拒绝Access Denied问题一下就明朗了。所以排查许可证问题别只在“有没有键值”这个层面上纠结还要看当前进程能不能访问到那个键。尤其那些在服务器上以服务方式跑WinCC的情况服务账户一般比管理员账户权限更受限更容易踩到权限坑。2.3 排查前必须做的注册表备份和快照在动手修改注册表之前我强烈建议先做两件事备份和监控。这不是走走形式而是让你在改坏之后能原样滚回去。先做注册表备份。如果只是打算动Licenses相关分支可以在regedit里选中Licenses键右键导出保存为.reg文件。如果你拿不准要动哪些键干脆在“文件”菜单里导出整个注册表或者直接创建一个系统还原点。Windows系统还原点在修改系统配置之前创建即使注册表改出问题也能还原回去。再做监控。Process Monitor这个工具是Sysinternals套件里的能实时看进程对注册表、文件系统的每一项访问。排查ActiveX许可证问题时建议添加两条过滤规则进程名设为控件的主进程比如WinCC激活后是S7-OCX相关的进程或者BfsSvr、Scd_ocx等路径包含“Licenses”。然后重新激活画面让报错复现一次Process Monitor会完整记录下进程到底访问了哪些键、哪一步被拒绝、哪一步返回了NotFound。有了这个日志排查效率提升十倍。3. 注册表修复实操从备份、定位到导入分步走3.1 手工备份注册表与导出键值两种安全路径真正的修复阶段最稳妥的操作方式不是自己瞎写注册表而是从另一台正常工作的机器上导出键值再导入到故障机器。这样能保证键值内容的正确性。这里有两个前提条件正常机器和故障机器必须装相同版本的WinCC和相同的Update Patch最好操作系统位数也一致。两台机器的Windows版本和语言最好也一致避免系统级CLSID差异。操作路径很简单在正常机器上打开regedit定位到HKEY_CLASSES_ROOT\Licenses选中整个Licenses键右键导出。导出范围选择“所选分支”保存为.reg文件。因为这个分支里可能包含很多软件产品的许可证不只是WinCC的所以导出范围最小可控。但注意HKEY_CLASSES_ROOT整体内容可能比较大导出时如果遇到权限不足的键会被跳过。所以导出完成后建议把文件大小和内容检查一下。如果只是想单独导出一个控件对应的键也可以在OLE/COM Object Viewer里先查出控件的CLSID再定位到对应的Licenses\CLSID键去导出。这个过程更精准适合只处理单个控件的情况。到了故障机器上不要急着双击导入。先把导出的.reg文件内容用记事本打开看一眼确认文件里的注册表路径和预期一致里面没有明显异常内容。然后有两种导入方式图形界面regedit - 文件 - 导入选择这个.reg文件。命令行以管理员身份打开CMD或PowerShell执行reg import 路径\文件名.reg。我习惯用命令行因为能看到明确的返回信息。如果导入成功命令行会提示“操作成功完成”。如果因为权限问题打不开某些键这里也会报错方便你进一步处理。3.2 修复许可证的三种典型操作修复、导入、赋权导入.reg文件只能解决“键值不存在”的问题。如果键值存在但权限不够或者键值内容不完整还要分情况处理。第一直接修复安装。如果你手里有WinCC安装介质可以尝试在控制面板里选择WinCC对应的条目点“更改/修复”执行修复安装。修复安装会重新注册所有系统组件和ActiveX控件也能把缺失的License键重新写进去。但这个操作前面说了不一定百分之百有效因为它主要检查文件完整性而License键的写入依赖安装流程里的注册步骤某些情况下会被跳过。第二手动导入键值。这个方法针对性强适合从正常机器导出License键再导入的情况。导入之后最好重启一下机器确保系统重新读取注册表。第三给键值赋权。如果当前用户对某个Licenses子键没有读取权限可以在regedit里右键该键 - 权限 - 添加当前用户或者对应的服务账户并勾选读取权限。这里还有一个技巧WinCC如果是以服务方式运行服务账户通常是“LocalSystem”而LocalSystem一般在键权限列表里已经存在如果被单独拒绝需要显式勾选允许读取。找到对应的账户把“拒绝”勾去掉或者重新配置权限。赋权操作要谨慎不要给Everyone完全控制权只给读取权就够了。ActiveX许可证读取不需要写权限运行期间一般也不写入给完全控制反而引入了安全风险。3.3 注册表重定向64位系统下32位控件注册表的坑很多WinCC控件是32位组件即使WinCC软件本身看起来是64位安装内部也有很多32位DLL。在64位Windows上32位程序访问注册表时系统会自动做重定向把HKLM\SOFTWARE下的访问映射到HKLM\SOFTWARE\WOW6432Node这个视图里。这就导致一个很常见的坑你在64位注册表编辑器里看到的Licenses键不等于32位程序看到的Licenses键。排查时需要分两路看64位视图HKEY_CLASSES_ROOT\Licenses和HKEY_LOCAL_MACHINE\SOFTWARE\Licenses32位视图HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Licenses你用regedit64位版本看的是64位视图想看32位视图可以运行C:\Windows\SysWOW64\regedit.exe这个版本打开的注册表编辑器会见WOW6432Node下的内容。网上很多教程没说这一步只教你打开注册表编辑器去看Licenses结果很多用户找了半天找不到32位控件的许可证键。所以当正常机器导出的.reg文件里路径是[HKEY_CLASSES_ROOT\Licenses\xxx]导入到64位系统时regedit默认会写入64位视图。如果控件是32位的它去读的是32位视图那你导了等于白导。解决办法是先确认控件位数使用SysWOW64版本的regedit导入或者手动把.reg文件里的路径改成HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Licenses\xxx再导入。3.4 修复后的验证方法修复完别急着关窗口验证是必须的。最简单的验证是打开WinCC的Graphics Designer新建一个画面把之前报错的控件拖进来看是否正常创建。如果设计态正常再激活运行跑一遍。还有一个更底层一点的方法用OLE/COM Object Vieweroleview.exe检查控件。这个工具在Windows SDK里能找到打开后在“Object Classes”里找到“Grouped by CLSID”搜索对应的CLSID双击查看控件属性。如果界面上显示“Licensed”说明许可证信息已经被系统识别了。如果显示“Not Licensed”那说明许可证还是没到位继续排查。另外用Process Monitor再抓一遍也是好办法。这次可以看到进程对Licenses键的访问结果不再是ACCESS DENIED或NAME NOT FOUND而是SUCCESS那就基本稳了。4. 系统兼容性调优问题往往不在注册表而在运行环境4.1 兼容性设置的四步检查清单注册表层面全部正常许可证键也存在权限也给了控件还是报缺失这时候十有八九是系统兼容性问题。WinCC的ActiveX控件本质上还是COM组件Windows操作系统为了安全考虑对COM组件的实例化有各种限制尤其在高版本Windows上跑老版本的WinCC更容易撞上。可以按下面四步逐一检查第一步右键WinCC图形设计器的运行程序通常是GraphicsDesigner.exe或者在WinCC项目的启动程序进入“属性 - 兼容性”勾选“以兼容模式运行这个程序”下拉框里选Windows 7。WinCC 7.x时代的主要开发系统还是Windows 7在Windows 10或Server 2016/2019上运行老项目时兼容模式能解决不少莫名奇妙的ActiveX问题。第二步勾选“以管理员身份运行此程序”。WinCC的很多操作需要管理员权限ActiveX控件的许可证读取也需要访问注册表敏感区域。如果没有管理员权限系统可能会用权限隔离的策略直接拦截。第三步关闭用户账户控制UAC。如果你为了让系统更安全UAC一直拉到最高COM组件的实例化也会被影响。这个不一定要全关但可以尝试把UAC滑块拉到第二档默认档或者重启后再试。如果问题依旧在“更改用户账户控制设置”里拉到最低重启。第四步不要动数据执行保护DEP。有的老教程会教你把WinCC相关程序加入DEP例外列表但在实际项目中例外列表不一定生效甚至会导致系统不稳定。我建议只要确认系统DEP是默认模式仅对必要系统程序启用就可以了不需要额外排除。4.2 运行库与系统组件缺失的补充安装ActiveX控件在创建前还会先加载一堆运行库。WinCC自带的控件依赖VC运行库、MFC库、ATL库、.NET Framework。很多精简版Windows系统把这些组件精简掉了或者安装顺序不对导致版本冲突。维修现场最容易遇到的情况是系统里只有一个新版的VC 2015-2022运行库缺了老版本VC 2005/2008/2010。WinCC的老控件是在老编译器环境下构建的运行时会去找它对应的运行库版本。找不到就报错报错内容往往也是模糊的有些甚至直接说“许可证缺失”让人摸不着头脑。解决办法很简单把Visual C运行库的合集装上2005、2008、2010、2013、2015-2022都装一遍x86和x64都装。反正这些运行库可以共存没有冲突。同理.NET Framework 3.5包括2.0和3.0也要确保启用WinCC很多控件的托管代码依赖于.NET Framework 3.5。如果系统是Windows Server版还需要检查是否安装了“桌面体验”功能。Server Core模式下没有完整的图形界面组件ActiveX控件大概率无法正常运行。这个在控制面板的服务器管理器中可以确认。4.3 远程桌面/终端服务会话中的ActiveX控件特例还有一种常见场景调试人员不在现场用远程桌面连到服务器上操作WinCC。这种环境下ActiveX控件报许可证缺失的频率明显高于本地控制台。原因有两方面一是终端服务会话的注册表视图和本地会话不完全一致某些COM组件在终端会话中被隔离控件的许可证查询会失败。类似的情况在连接远程桌面服务时也会碰到比如系统提示无法加载远程桌面的ActiveX控件要求确保rdclientax.dll在路径中——那是远程桌面客户端自己的控件问题但背后机制是一样的ActiveX控件在非交互式会话中创建时对注册表和系统状态的访问都会受限。二是并发会话的中断多个会话同时尝试创建同一个ActiveX控件时许可证又没有做并发控制可能相互踩踏后创建的就拿不到许可证。遇到这种情况如果系统允许建议在远程桌面会话里不做控件密集型操作优先在本地控制台或者虚拟桌面里运行WinCC画面。如果必须远程可以在组策略里设置“允许在终端服务会话中实例化ActiveX桌面控件”或者给运行WinCC的用户开通“允许通过终端服务登录”的高级权限。但稳妥起见还是本地运行优先。5. 一次实战案例复盘与日常维护建议5.1 案例Win10 x64上WinCC控件“时好时坏”的完整排查链路结合前面讲的我复盘一个实际案例。背景是一台Windows 10 Pro 64位工作站安装WinCC V7.4 SP2画面里用了WinCC OnlineTrendControl。现象是系统刚重启后第一次激活画面没问题关掉画面再打开趋势控件就变成红叉日志里报“许可证缺失”。重启又正常过一会儿又不行非常随机。排查链路第一步看西门子授权管理器所有授权都在软件授权层面排除。第二步打开Process Monitor在报错复现的瞬间抓取进程对注册表的访问。过滤条件路径包含License。结果发现控件进程第一次创建时访问的Licenses键是HKLM\SOFTWARE\WOW6432Node\Licenses\xxxx返回SUCCESS。第二次再创建时访问同一个键返回KEY_NOT_FOUND。这就奇怪了键在第二次却找不到。于是我在regedit里用SysWOW64版本打开32位视图找到这个键发现键值还在但权限列表里有一项“该用户已被显式拒绝读取”。为什么会这样后来查了系统日志发现是这台机器装了安全软件定时扫描时把某些注册表键的ACL给改了加了拒绝条目。第三步手动编辑权限把所有“拒绝”条目去掉为当前用户和管理员组勾选完全控制至少读取。改完后再激活画面恢复正常。第四步为了防再犯我干脆把安全软件对WinCC安装目录和注册表Licenses键的扫描排除了。之后观察三周没有再出现同样问题。这个案例典型在于它既不是真缺许可证也不是注册表键值被清空而是权限被安全软件篡改造成“时好时坏”的假象。如果一开始就去重装系统或者重装WinCC时间成本高问题还不一定解决。Process Monitor 注册表权限检查半小时定位问题。5.2 日常维护中防止许可证隐患的四个习惯排查故障只是解决问题真正省事的是让问题根本不发生。我自己在项目交付和运维中总结了几个习惯效果不错。第一不用系统清理工具清理注册表。WinCC这类组态软件对注册表依赖非常重市面上九成清理工具识别不了ActiveX许可证信息很容易误删。宁可机器稍微乱一点也不要去“优化”注册表。第二项目交付时除了交付项目文件还要附一份“运行环境清单”写明WinCC版本、SP、补丁号、操作系统版本、必要的运行库列表。这样万一现场出问题可以按清单核对环境而不是到处摸索。第三定期备份注册表里的Licenses分支和CLSID分支。不用频繁每次做完系统变更、打补丁、安装新控件之前导出一次保存到本地备份目录。一旦出问题直接导入旧键值就能回来。第四部署标准镜像。如果你们公司有多台相同配置的上位机建议做一台基准机把WinCC、控件、运行库全部装好测试没有问题后做成系统镜像。后续机器全部刷镜像部署能规避大量因为手动安装顺序不对导致的许可证问题。5.3 如果所有修复都无效时的“终极大法”讲了这么多常规手段总有那么几次所有检查都做了键值存在权限正常运行库齐全兼容性也设置了控件还是报缺失。这时候我的终极大法就是干净卸载后重装WinCC。但这里有个前提干净卸载不是控制面板里点一下“卸载”就完事。WinCC涉及多个组件包括WinCC本身、SQL Server、SIMATIC NET、消息运行时等卸载顺序不对会留下一堆注册表残骸。理想顺序是先把WinCC项目做完整备份然后在控制面板中把WinCC相关的所有组件按依赖顺序逐一卸载通常是从上层应用开始到底层运行时和SQL Server结束。卸载完后重启再用注册表清理工具或者手搜把和WinCC、Siemens相关的残留键删掉。这块工作量不小所以前面才说“终极大法”。如果时间实在紧张还有一种办法是从正常机器上做一次完整系统克隆直接替换故障机的系统盘。这种方法在工业现场有时更高效但要注意替换后Windows激活状态、主机名、IP地址都要重新设置不能乱来。最后说句实在话ActiveX“许可证缺失”这个报错百分之七八十都藏在注册表和系统环境里真正需要重装的少之又少。遇到这种问题不要急着去怀疑授权先把Process Monitor打开看看控件加载时到底读了哪些键被谁拒绝了往往比手动翻注册表更高效。这套排查思路不仅对WinCC有效对其他工业组态软件里的ActiveX控件故障一样通用。