我参加了盛大组织的“Bambook程序达人赛”,是通过博客园报名的。目前提交了两件参赛作品。
在参赛作品中需要实现“注册到云梯”的功能,如下图所示:
这是一个通用的功能,可以封装为一个类,以便各个参赛的 C# 程序调用。
根据盛大官方的 SDK 文档,要注册应用程序到云梯,有两种方法:
- 使用 RegApp.exe。
- 编辑云梯安装目录下的 bbapps.xml 文件。
我决定采用第二种方法,即编辑云梯安装目录下的 bbapps.xml 文件。
之所以不采用第一种方法,其中一个原因是第一种方法需要随程序一起发布 RegApp.exe。
好了,下面就是核心的 BambookAppsXml.cs 源程序文件:
01: using System; 02: using System.Xml; 03: using System.IO; 04: using Microsoft.Win32; 05: 06: namespace Skyiv.Common 07: { 08: /// <summary> 09: /// 盛大云梯软件的应用程序扩展的配置文件 10: /// </summary> 11: public sealed class BambookAppsXml 12: { 13: static readonly string XmlFileName = "bbapps.xml"; 14: static readonly string ElementApp = "app"; 15: static readonly string ElementId = "id"; 16: static readonly string ElementExec = "exec"; 17: 18: XmlDocument doc; 19: 20: /// <summary> 21: /// 注册应用程序到云梯 22: /// </summary> 23: /// <param name="guid">应用程序标识</param> 24: /// <param name="executeFileFullName">应用程序全路径名</param> 25: public void InsertOrUpdate(Guid guid, string executeFileFullName) 26: { 27: if (guid == Guid.Empty) throw new Exception("程序标识不能为空"); 28: var path = GetCloudLibraryInstallPath(); 29: if (path == null) throw new Exception("云梯软件尚未安装,请先下载并安装云梯。"); 30: var fileName = Path.Combine(path, XmlFileName); 31: doc = new XmlDocument(); 32: doc.Load(fileName); 33: var id = guid.ToString("N"); 34: var elem = FindElementId(id); 35: if (elem == null) doc.DocumentElement.AppendChild(elem = CreateElementId(id)); 36: InsertOrUpdateElementExec(elem, executeFileFullName); 37: doc.Save(fileName); 38: } 39: 40: XmlElement FindElementId(string id) 41: { 42: foreach (var node in doc.DocumentElement.ChildNodes) 43: { 44: var elem = node as XmlElement; 45: if (elem == null) continue; 46: foreach (var node2 in elem.ChildNodes) 47: { 48: var elem2 = node2 as XmlElement; 49: if (elem2 == null) continue; 50: if (elem2.Name != ElementId) continue; 51: if (elem2.InnerText == id) return elem; 52: } 53: } 54: return null; 55: } 56: 57: XmlElement CreateElementId(string id) 58: { 59: var elem = doc.CreateElement(ElementApp); 60: var elemId = doc.CreateElement(ElementId); 61: elemId.InnerText = id; 62: elem.AppendChild(elemId); 63: return elem; 64: } 65: 66: void InsertOrUpdateElementExec(XmlElement elem, string value) 67: { 68: foreach (var node2 in elem.ChildNodes) 69: { 70: var elem2 = node2 as XmlElement; 71: if (elem2 == null) continue; 72: if (elem2.Name != ElementExec) continue; 73: elem2.InnerText = value; 74: return; 75: } 76: var elemExec = doc.CreateElement(ElementExec); 77: elemExec.InnerText = value; 78: elem.AppendChild(elemExec); 79: } 80: 81: /// <summary> 82: /// 获取云梯软件的安装目录 83: /// </summary> 84: /// <returns>云梯软件的安装目录</returns> 85: string GetCloudLibraryInstallPath() 86: { 87: return Path.GetDirectoryName(Registry.GetValue( 88: @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Bambook", 89: "AutoRunExec", null) as string); 90: } 91: } 92: }
这个 BambookAppsXml 类的主要功能是通过编辑盛大云梯软件安装目录下的 bbapps.xml 文件来将应用程序注册到云梯。
上述程序中第 85 到第 95 行的 GetCloudLibraryInstallPath 方法通过读取注册表的以下键值:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Bambook\AutoRunExec
来获得云梯软件的安装目录。
云梯软件安装目录下的 bbapps.xml 文件格式如下所示:
01: <bbapps> 02: <app> 03: <id>1aba95ad66ec70263a79fa260394e170</id> 04: <exec>E:\Bambook\Air\TVGuide\TVGuide.exe</exec> 05: </app> 06: <app> 07: <id>88a915cc3658c7130910da4e312436f3</id> 08: <exec>E:\work\PowerWord2Snb\PowerWord2Snb.exe</exec> 09: </app> 10: </bbapps>
然后上述程序就通过 System.Xml 命名空间的下的 XmlDocument 类以及相关的类来编辑这个 XML 文件,从而达到将应用程序注册到云梯的目的。
在 AboutDiaglog 类的“注册到云梯”按钮的事件处理程序中调用 BambookAppsXml 类的 InsertOrUpdate 方法来注册应用程序到云梯,如下所示:
01: private void btnRegisterApp_Click(object sender, EventArgs e) 02: { 03: try 04: { 05: new BambookAppsXml().InsertOrUpdate(assembly.Guid, assembly.ExecuteFileFullName); 06: MessageBox.Show("完成", "注册到云梯", MessageBoxButtons.OK, MessageBoxIcon.Information); 07: } 08: catch (Exception ex) 09: { 10: MessageBox.Show(ex.Message, "注册到云梯", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 11: } 12: }
这个 AboutDialog 类的其余部分的源程序代码请参见 通用的“关于本软件”对话框 一文。
最后,就是“锦书背单词”这个应用程序的 AssemblyInfo.cs 源程序文件了:
01: using System.Reflection; 02: using System.Runtime.InteropServices; 03: 04: [assembly: AssemblyTitle("锦书背单词")] 05: [assembly: AssemblyDescription("将金山词霸导出的生词本,制作成snb格式的电子书。")] 06: [assembly: AssemblyCompany("Skyiv Studio")] 07: [assembly: AssemblyProduct("PowerWord2Snb")] 08: [assembly: AssemblyCopyright("Copyright © 2010")] 09: 10: // 注意,这不是 Visual Studio 2010 自动生成的 Guid。 11: // 这是从盛大官网获得的 Guid,用于注册到云梯。 12: [assembly: Guid("88a915cc-3658-c713-0910-da4e312436f3")] 13: 14: [assembly: AssemblyVersion("1.4")]
这里要注意的是 GuidAttribute 不能使用 Visual Studio 2010 自动生成的 Guid,要从盛大官网获取。