C# 中的 ActiveSync 文件过滤器






2.88/5 (5投票s)
本文介绍如何使用 C# 编写 ActiveSync 文件过滤器。
背景
我一直在开发一个项目,该项目用于在安装了 .NET Compact Framework 的 Pocket PC 上读取和显示 HXS 和 CHM 帮助文件。这个程序的一个旧版本(CHM Reader)曾发布在 Code Project 上。在我的网站上,有一个更新版本的 CHM Reader 程序。在新版本开发过程中,我产生了一个想法。一旦帮助文件被打开和解码,为什么不将这些数据保存到文件中,这样每次打开文件时就不需要进行所有这些处理了。然后,我想到如果这些预处理在 PC 上而不是在 Pocket PC 上进行,因为 PC 拥有额外的处理能力,那会更好。我认为,当用户将帮助文件从 PC 复制到 Pocket PC 时,如果预处理在此期间进行,那将是一个好主意——因此,寻找如何用 C# 编写 Active-Sync 文件过滤器的工作就此开始。
注释
- 我将不解释 Active-Sync 文件过滤器的具体工作原理,因为 MSDN 上已有相关文档。(搜索 Active-Sync File Filter。)
HelpFileFilter
的代码仅作为指南,无法直接编译,因为它没有包含我用来构建文件过滤器的所有库。- 此代码仅在 Active-Sync 3.7.1 上进行了测试。
项目
此项目附带的解决方案文件包含一个基本的测试程序,用于测试 C# 代码和文件过滤器代码。
Active-Sync 文件过滤器项目构建了一个 DLL 类库,该库在文件复制过程中执行所有处理。该 DLL 基本上创建了一个 COM 对象,Active-Sync 管理器会在定义的类型文件要复制到/从 Pocket PC 时加载并调用它。因此,在安装应用程序时,该 DLL 需要安装到 GAC 中。
界面
本质上,Active-Sync 文件过滤器就是使其一切正常工作的 COM 接口,这也是我在使 C# 互操作代码与 COM 定义匹配时遇到最多麻烦的地方。所有接口都在 Interfaces.cs 中定义(这很意外!)我不能完全确定我已经消除了所有 bug,但目前为止似乎可以无错误地运行。
IceFileFilter
是主接口。它有三个方法,其中最重要的是 'NextConvertFile
'。
int NextConvertFile(int nConversion, ref CFF_CONVERTINFO pci,
ref CFF_SOURCEFILE psf, ref CFF_DESTINATIONFILE pdf,
ref bool pbCancel, ref Int32 perr)
nConversion
– 这是一个索引值,决定了当前文件复制调用此函数的次数。(您可以复制多个文件并将其视为一个单独的操作。)pci
– 这是一个包含文件复制信息的结构。(Pocket PC 到 PC 或 PC 到 Pocket PC,一个父应用程序的 hWnd,一个 bYesToAll 标志,以及指向IceFileFilterSite
对象的指针。此对象允许您打开和关闭源文件和目标文件,并报告进度。)psf
– 这是一个包含源文件名的结构。pdf
– 这是一个包含目标文件名 的结构。
当一个文件需要复制时,此方法会以 nConvertsion =0
被调用。然后您可以检测到这一点并执行任何您喜欢的操作来初始化您的代码。当我预处理帮助文件时,就是在 nConversion =0
时加载和处理帮助文件,并创建一些额外的文件。我还创建了一个需要复制的文件列表。然后我返回 RESULT.NOERROR
。这会告诉 Active-Sync 继续复制文件,并且该函数会再次以 nConversion=1
被调用。在这里,我将文件从源位置复制到目标位置。
注意:这些文件位置不在 Pocket PC 上,而是虚拟位置。文件传输是从 Active-Sync 代码内部执行的。
如果所有文件都已复制,我将返回 HRESULT.E_ERROR_NO_MORE_ITEMS
。
其他注意事项
以下是关于接口中包含的其他方法的说明。这些方法要么不会被调用,要么即使被调用也不会对转换过程产生任何影响。
IceFileFilterOptions.SetFilterOptions
- 设置转换选项,但选项被忽略。IceFileFilter.FilterOptions
- 从未被调用。IceFileFilter.FormatMessage
- 从未被调用。
最后的一些细节
还有一些收尾工作。
- 您需要将您的 DLL 声明为强命名 DLL,所以您需要指定
[assembly: AssemblyKeyFile(@"..\..\HelpFileFilter.snk")]
- 您需要使您的类 COM 可见
[ ProgId("MSHelReader.CHMPreProcessor"), Guid("B424CF38-10C0-46ec-A29C-8F78A5990B5F")] Class CMyFileFilter : ICeFileFilter, ICeFileFilterOptions {.... }
- 您需要指定 COM 注册和 COM 注销函数,以便您可以添加/删除将您的文件过滤器映射到 Active-Sync 的注册信息。
- ActiveSync 测试项目是一个小型 C++ 项目,允许您在文件过滤器 COM 对象被调用时创建和使用它们,并测试您的代码。
关于可以读取 HXS 和 CHM 帮助文件的新版本 PPCHelpReader 的详情,可以在 这里找到。