- 桌面应用
- 开发工具
【免费下载链接】XmlNotepad
XML Notepad provides a simple intuitive User Interface for browsing and editing XML documents.
XML Notepad 通过 Google Analytics 收集匿名使用数据(启动次数、各功能使用次数),用于帮助开发团队判断哪些功能值得优先增强。本文基于官方文档 analytics.md 与仓库源码,完整讲解其采集了哪些数据、首次启动授权对话框的触发逻辑,以及用户和企业管理员分别如何可靠地禁用该功能,读完后你可以掌握从个人设置到批量部署的全部控制手段。
收集哪些数据、用于什么目的
官方文档明确说明,为了了解哪些功能对用户最重要,XML Notepad 会记录匿名使用数据,具体包括两类:
- 应用被使用的次数(启动次数);
- 每个功能被使用的次数(Options、XSLT、Search 等)。
数据通过 Google Analytics 收集,且仅与 XML Notepad 开发团队成员共享,用途是"为未来的功能增强排定优先级"。这里强调的"匿名"体现在:事件上报只携带一个随机会话标识ClientId(一个 GUID 字符串)和固定的 Measurement ID,不携带任何文档内容或文件路径。这一点可以从 AppAnalytics.cs 的实现得到印证:
private const string HostName = "microsoft.github.io"; private const string TrackingId = "G-130J0SE94H"; private async void SendMeasurement(string path, string title) { try { var a = new Analytics() { ApiSecret = ApiKey, MeasurementId = TrackingId, ClientId = _clientId }; a.Events.Add(new PageMeasurement() { Path = "https://" + HostName + path, Title = title }); await HttpProtocol.PostMeasurements(a); } catch { // Ignore. } }从源码看有两个值得注意的工程细节:
- 每条事件都是一个
PageMeasurement,Path 形如https://microsoft.github.io/App/Launch,Title 为功能名(Launch、Options、Search、XsltView等); - 上报是
async void且捕获所有异常后直接忽略——即使网络不可用或上报失败,也不会影响应用正常运行,更不会产生任何 UI 提示。
此外,AppAnalytics构造函数中有一道硬性开关:_enabled = enabled && !string.IsNullOrEmpty(ApiKey)。这里的ApiKey并非写死在仓库里,而是由 Model.csproj 在构建时通过 MSBuild 从构建变量XMLNOTEPAD_ANALYTICSKEY生成到ApiKey.cs中。从源码结构看,如果发布构建未注入该密钥,ApiKey为空,分析功能会在代码层面直接失效。
哪些操作会被统计:事件埋点全览
AppAnalytics共暴露 7 个记录方法,每个方法内部都有一个"本次会话只记录一次"的去重标志(_formOptions、_formSearch、_xsltView等布尔字段),因此同一功能在一次会话中反复打开只会计一次:
| 方法 | 上报事件 Path | 说明 |
|---|---|---|
RecordAppLaunched() | /App/Launch | 应用启动 |
RecordFormOptions() | /App/FormOptions | 打开 Options 对话框 |
RecordFormSchemas() | /App/FormSchemas | 打开 Schemas 对话框 |
RecordFormSearch() | /App/FormSearch | 打开 Search 对话框 |
RecordCsvImport() | /App/CsvImport | 使用 CSV 导入 |
RecordXsltView() | /App/XsltView | 使用 XSLT 视图 |
RecordStatistics() | /App/Stats | 查看统计信息 |
这些埋点的实际调用位置全部集中在 FormMain.cs 中:RecordXsltView()在 XSLT 视图切换处(第 896 行附近),RecordCsvImport()在 CSV 导入流程(第 1184 行附近),RecordFormSearch()、RecordFormOptions()、RecordFormSchemas()、RecordStatistics()分别位于第 2286、2374、2633、2929 行附近。所有调用点都直接操作_analytics实例,而该实例是否真正启用,则由下面两节的授权机制决定。
首次启动授权:从源码看触发条件
文档描述的行为是:首次在某台电脑安装并启动 XML Notepad 时,会弹出授权对话框;若点击No,偏好会被写入 XML Notepad 设置文件,且对话框不会再出现。该行为对应 FormMain.cs 中FormMain构造函数末尾调用的CheckAnalytics():
private void CheckAnalytics() { if ((string)this.Settings["AnalyticsClientId"] == "" && AllowAnalytics && this.Settings.GetBoolean("AllowAnalytics", true)) { // have not yet asked for permission! this.Settings["AnalyticsClientId"] = Guid.NewGuid().ToString(); FormAnalytics fa = new FormAnalytics(); var rc = fa.ShowDialog(); if (rc == DialogResult.Yes) { this.Settings["AllowAnalytics"] = true; } else { this.Settings["AllowAnalytics"] = false; } } _analytics = new AppAnalytics((string)this.Settings["AnalyticsClientId"], (bool)this.Settings["AllowAnalytics"] && this.AllowAnalytics); _analytics.RecordAppLaunched(); }三个触发条件必须同时成立:
- 设置文件中
AnalyticsClientId为空字符串(尚未询问过); - 实例属性
FormMain.AllowAnalytics为true(由环境变量决定,见下一节); - 设置项
AllowAnalytics为true(默认值为true,见GetBoolean("AllowAnalytics", true))。
触发后会先生成一个随机 GUID 写入AnalyticsClientId,再模态显示 FormAnalytics 对话框。该对话框提供Yes(DialogResult.Yes)与拒绝按钮(DialogResult.No),并带有一个指向帮助页面的链接。用户的选择随即写入设置文件的AllowAnalytics项——这就是文档所说"点击No后偏好被写入设置文件、对话框不再出现"的实现:下一次启动时第一个条件(AnalyticsClientId为空)已经不成立。
最终AppAnalytics的启用状态是双重与运算:(bool)this.Settings["AllowAnalytics"] && this.AllowAnalytics,即用户选择与环境变量必须同时放行。
用户级禁用:Allow analytics 选项
文档给出的用户级操作路径是:在 Options 对话框 中切换Allow analytics选项,可随时启用或禁用分析功能。源码中有两处配套实现:
- 选项属性:FormOptions.cs 第 652 行附近定义了
UserSettings.AllowAnalytics属性([LocDisplayName("AllowAnalytics")],描述文本见AllowAnalyticsDescription),用户在 Options 对话框的 PropertyGrid 中看到的正是它; - 实时生效:FormMain.cs 在设置变更通知中监听该项,无需重启即可切换:
case "AllowAnalytics": if (this._analytics != null) { this._analytics.SetEnabled(this._settings.GetBoolean("AllowAnalytics", false)); } break;AppAnalytics.SetEnabled()同样会再次校验ApiKey非空,因此即使把该项设为True,在密钥缺失的构建上分析仍不会启用。
企业级禁用:环境变量与模板设置文件
对于企业批量分发或预安装定制场景,文档提供了两条管理员通道,源码均可一一印证。
通道一:系统环境变量
在最终用户机器上系统级设置:
set XML_NOTEPAD_DISABLE_ANALYTICS=1Program.cs 在Main入口立即读取该变量:
form.AllowAnalytics = Environment.GetEnvironmentVariable("XML_NOTEPAD_DISABLE_ANALYTICS") != "1";当值为1时,FormMain.AllowAnalytics为false,带来两层效果:首次启动的授权对话框根本不会弹出(CheckAnalytics的第二个条件不成立),且即使设置文件里AllowAnalytics为True,AppAnalytics的最终启用状态也是false。WPF 版本的入口 App.xaml.cs 也做了同样的检查,并直接把设置项写入为False。
通道二:模板设置文件隐藏并禁用选项
文档进一步说明,可以在默认 XmlNotepad.settings 文件中将AnalyticsClientId设为disabled,从而让 Analytics 选项从 Options 对话框中消失:
<Settings> <AnalyticsClientId>disabled</AnalyticsClientId> <AllowAnalytics>False</AllowAnalytics> </Settings>配套源码有两处:
- 选项隐藏:FormOptions.cs 在绑定 PropertyGrid 时检查该值,若
AnalyticsClientId等于字符串disabled,则把AllowAnalytics加入隐藏属性列表,用户无法再在界面上改回:
List<string> hiddenProperties = new List<string>(); if (this._settings.GetString("AnalyticsClientId") == "disabled") { hiddenProperties.Add("AllowAnalytics"); }- 模板分发:SettingsLoader.cs 在用户首次启动且本地不存在任何设置文件时,会加载程序目录下的
XmlNotepad.template.settings模板并复制为 Roaming 位置的新用户设置。因此管理员把上面这段内容放进模板文件随安装包分发(模板文件见 XmlNotepad.template.settings,安装程序 Product.wxs 会将其部署到安装目录),即可保证"用户在启动 XML Notepad 后无法启用分析"——这同时满足了CheckAnalytics第一个条件(AnalyticsClientId非空,对话框不弹)和选项隐藏两个目标。
三条通道的作用范围对比:
| 手段 | 是否弹授权框 | 用户可否自行改回 | 生效位置 |
|---|---|---|---|
环境变量XML_NOTEPAD_DISABLE_ANALYTICS=1 | 否 | 不可(代码强制覆盖) | 系统/用户环境 |
AnalyticsClientId设为disabled+AllowAnalytics=False | 否 | 不可(选项被隐藏) | 模板/设置文件 |
用户在对话框点No或关闭Allow analytics | 已问过,不再弹 | 可以(随时可打开) | 用户设置文件 |
官方公开的历史使用数据
作为"抢先一瞥",文档公布了 2022 年 7 月的使用地区分布图,说明其活跃的用户社区是团队持续打磨产品的动力之一:
文档还给出了 2021 年 8 月至 2022 年 8 月的原始统计(该数据为文档撰写时的历史快照,供理解量级参考,非实时数据):
| Action | Counts | Description |
|---|---|---|
| /App/Launch | 1,082,553 | Times app was launched |
| /App/XsltView | 140,703 | Times XSLT view was used |
| /App/FormSearch | 83,020 | Times the Search dialog was used |
| /App/FormOptions | 4,448 | Times the Options dialog was used |
| /XmlNotepad/ | 208,520 | Visits to the web home page |
| /XmlNotepad/install/ | 78,812 | Visits to the install page |
前四项分别对应上文RecordAppLaunched()、RecordXsltView()、RecordFormSearch()、RecordFormOptions()四个埋点;后两项(/XmlNotepad/与/XmlNotepad/install/)来自官网与安装页的访问统计,属于 Web 端数据,不走客户端AppAnalytics上报链路。
小结
XML Notepad 的分析机制设计遵循"默认询问、明确选择、多层可强制关闭"的原则:客户端仅上报功能级别的匿名计数,会话内去重、失败静默;授权偏好持久化到设置文件(默认位于%APPDATA%\Microsoft\Xml Notepad\XmlNotepad.settings,详见 settings.md);而企业部署可以通过环境变量或模板设置文件在代码层面彻底关闭采集并隐藏相关选项。理解 AppAnalytics.cs、FormMain.cs 与 SettingsLoader.cs 三处实现,即可完整掌握该机制的数据流与控制流。
- 桌面应用
- 开发工具
【免费下载链接】XmlNotepad
XML Notepad provides a simple intuitive User Interface for browsing and editing XML documents.
相关推荐
Resume Matcher数据所有权:用户数据的控制与授权管理
Resume Matcher数据所有权:用户数据的控制与授权管理 引言:本地化部署的数据主权优势 在当今数据隐私日益重要的时代,Resume Matcher作为
AI 应用人工智能大模型后端前端深度解析XmlNotepad更新检查机制:从原理到企业级优化方案
深度解析XmlNotepad更新检查机制:从原理到企业级优化方案 引言:你还在手动检查XML Notepad更新吗? 作为开发者,你是否曾因错过关键更新而导致X
桌面应用开发工具Karakeep(hoarder)自托管实例用户管理实战:密码找回、管理员授权与禁用注册后的用户创建
Karakeep(hoarder)自托管实例用户管理实战:密码找回、管理员授权与禁用注册后的用户创建 Karakeep(原 hoarder)是一款可自托管的"收
后端前端移动开发AI 应用知识管理全文检索MCP 服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考