从桌面管理手持设备文件






4.75/5 (14投票s)
使用 OpenNetCF RAPI 包装类来管理运行 Windows Mobile 操作系统的掌上设备上的文件。
简介与背景
我最近开发了一个利用 .NET Compact Framework 2.0 的应用程序。我们有一个配套应用程序安装在桌面端,用于管理将最初在掌上设备上创建的文件通过 B2B 服务发送出去。
过去我们遇到过*涉及* Microsoft ActiveSync 的文件损坏问题。我在此澄清,我并非说 ActiveSync 直接对问题负责。我们有一个独特的需求,要求我们执行第二种类型的同步,即本地工作文件夹与掌上设备同步到桌面计算机上的文件之间的同步。
当我想象如何处理这些同步冲突时,我意识到了一件事:*我们实际上不需要同步文件,只需要复制它们!* 由于我们软件的设计方式,掌上设备会创建各种 XML 文件,然后我们的桌面软件会获取这些 XML 文件,有时会修改数据,然后生成它通过 B2B 服务传输的数据文件。
于是我开始思考。如果我直接从掌上设备中拉出文件呢?**执行这项操作对我来说是全新的,关于这个主题的信息很难找到,这也是我写这篇文章的初衷!**
注意:此代码仅在 Windows Mobile 5 设备上进行了测试。
Google、CodeProject 和 OpenNetCF
信不信由你,对于像我这样从未做过的人来说,弄清楚如何在桌面应用程序中*查找*和*管理*掌上设备上的文件并不容易。Google、Google Groups、CodeProject 和无数其他网站都帮不上忙。我能找到的最好的信息是关于管理*已知文件*的文章。我需要能够枚举掌上设备上的整个目录结构。
然后我发现了 OpenNetCF(OpenNetCF[^])。他们有一个开源 DLL,名为 *OpenNETCF.Desktop.Communication.dll*。可以在此处[^]下载。
尽管 *OpenNetCf.Desktop.Communication.dll* 非常实用,但我发现它有点难用。我喜欢看到如何使用对象的示例。我决定围绕这个 DLL 编写一种包装类,简化我需要对掌上设备文件执行的所有任务。这些任务列在以下测试中。
OpenNETCF.Desktop.Communication 程序集
RAPI(远程 API)通过 *OpenNETCF.Desktop.Communication.dll* 允许我们与掌上设备交互。我将简要介绍此程序集中的一些可用方法和属性。
RAPI.DevicePresent
此属性返回一个布尔值,如果设备已连接到您的计算机,则为
true
。RAPI.Connect()
,RAPI.Disconnect()
在与设备交互之前,您必须通过 RAPI 连接到它。完成后,应断开连接。
RAPI rapi = new RAPI(); rapi.Connect(); rapi.Disconnect();
RAPI.EnumFiles
FileList RAPI.EnumFiles(string fileName)
允许我们从掌上设备获取文件和目录。有点令人困惑的是 `string fileName` 部分。以下是可以传递给 `RAPI.EnumFiles` 方法的有效字符串参数:我的文档\\Folder1\\ 这将返回一个项目 `Folder1`,位于 `FileList` 数组中。 我的文档\\Folder1\\* 这将返回 `Folder1` 内的所有文件*和*目录,位于 `FileList` 数组中。 我的文档\\Folder1\\*xml 这将返回 `Folder1` 内的所有*XML*文件,位于 `FileList` 数组中。 我的文档\\Folder1\\123.xml 这将返回一个项目,即 *123.xml*,位于 `FileList` 数组中。
HHFiles.cs
我在这里包含了我的 `HHFiles` 类。以下是该类的一些代码片段。
访问掌上设备上的*我的文档*目录
public FileList MyDocuments
{
get
{
return rapi.EnumFiles("My Documents");
}
}
//Copy file from device to desktop.
public void CopyFileFromDevice(string localFilePath,
string deviceFilePath, bool overwrite)
{
Rapi.CopyFileFromDevice(localFilePath,deviceFilePath,overwrite);
}
示例
HHFiles files = new HHFiles();
files.CopyFileFromDevice(@"c:\test.txt",
@"My Documents\Folder\Somefile.txt,true);
删除掌上设备上的文件
public void DeleteFile(string deviceFilePath)
{
if (Rapi.DeviceFileExists(deviceFilePath))
{
Rapi.DeleteDeviceFile(deviceFilePath);
}
}
递归复制文件,包括目录结构。
//fileMask - file extension. (i.e., "xml", "doc", "xls")
//includSubDirectories - recurse sub folders (true/false)
//overwrite - overwrite if target file exists (true/false)
public void CopyFilesFromDevice(string localStartingDirectory,
string deviceStartingDirectory,
string fileMask,
bool includeSubDirectories,
bool overwrite)
{
CreateLocalStartingDirectory(localStartingDirectory);
FileList deviceDirectory = GetFileList(deviceStartingDirectory);
if (deviceDirectory == null || deviceDirectory.Count != 1)
{
throw new System.IO.FileNotFoundException("Invalid Device Directory",
deviceStartingDirectory);
}
FileList directoryList = GetFileList(deviceStartingDirectory + "\\*");
foreach (FileInformation dirInfo in directoryList)
{
if (dirInfo.FileAttributes == (int) FileAttributes.Directory )
{
if (!includeSubDirectories) continue;
string newDeviceDirectory =
deviceStartingDirectory + "\\" + dirInfo.FileName;
string newLocalDirectory =
localStartingDirectory + "\\" + dirInfo.FileName;
CopyFilesFromDevice(newLocalDirectory,
newDeviceDirectory,fileMask,includeSubDirectories,overwrite);
}
else
{
if (!MatchesFileMask(dirInfo.FileName, fileMask)) continue;
string newDeviceFile =
deviceStartingDirectory + "\\" + dirInfo.FileName;
string newLocalFile =
localStartingDirectory + "\\" + dirInfo.FileName;
CopyFileFromDevice(newLocalFile,newDeviceFile,overwrite);
}
}
}
示例
HHFiles files = new HHFiles();
files.CopyFilesFromDevice(@"c:\temp", @"My Documents\Work","xml",true,true);
结论
嗯,我写文章已经有一段时间了。希望您觉得这很有用。我花了很长时间才弄清楚如何处理掌上设备上的文件,而这个类极大地简化了工作。如果有什么不清楚的地方,或者您有任何疑问,我将经常回来查看,所以请随时提问。