大家好,目前数据同步的方式有好几种,本文主要是以文件同步的方式同步数据,思路如下:将mobile sql 的sdf格式的数据库在PC上配置好(当然是用代码去操作了)以后,通过OpenNETCF提供的方法,同步到PDA,俗一点说,就是把带有数据的sdf数据库拷贝到PDA上,然后,您PDA上程序就可以对该sdf数据库进行一系列操作了,相反,也可以把PDA上的sdf数据库同步到PC,用PC上的程序对sdf数据库进行操作。 本文说明如何通过一个简单的桌面应用程序充分利用远程 API 执行以下操作:
[注]一下代码均运行于PC端。
1.通过设备复制粘贴文件。
2.移动设备中的文件。
3.删除设备中的文件。
我们需要用到OpenNETCF.Desktop.Communication.DLL 相关dll请到其官方网站下载
下面是对该dll中方法的一些说明
Connect 建立与设备的同步连接。
CopyFileFromDevice 将设备中的文件复制到 PC。
CopyFileOnDevice 将设备某个位置的文件复制到设备的另一新位置。
CopyFileToDevice 将 PC 中的文件复制到设备。
CreateDeviceDirectory 在设备中创建目录。
CreateProcess 启动设备中的应用程序。
DeleteDeviceFile 删除设备中的文件。
DeviceFileExists 检查设备中是否存在文件。
Disconnect 中断与设备的连接。
EnumFiles 提供与 FileName 参数提供的条件相匹配的FileInformation 类数组列表。
GetDeviceCapabilities 检索设备的特定设备信息。
GetDeviceFileAttributes 检索特定设备文件的属性。
GetDeviceFileSize 检索设备文件的大小,以字节为单位。
GetDeviceFileTime 检索设备文件的日期时间。
GetDeviceMemoryStatus 检索设备的内存使用信息。
GetDeviceSystemFolderPath 检索到设备系统文件夹的路径。
GetDeviceSystemInfo 检索设备的系统详细信息。
GetDeviceSystemPowerStatus 检索设备的电源状态。
GetDeviceVersion 检索设备的操作系统版本。
MoveDeviceFile 将现有设备文件移到或重命名到一个新位置。
RemoveDeviceDirectory 删除设备中的目录。
SetDeviceFileAttributes 设置设备中文件的属性。
SetDeviceFileTime 设置设备中文件的日期时间。
为了简化 RAPI 类的使用过程,C# 代码示例中添加了 using 语句,VB.NET 代码示例中添加了 Imports 语句,如下所示:
此外,还声明了一个模块变量 myrapi,该变量用于存储 RAPI 类的实例
Dim WithEvents myrapi As New rapi
连接到设备
桌面应用程序在使用 RAPI 类方法时,第一步是建立与设备的连接。
注意:在桌面应用程序中使用 RAPI 要求在 PC 和设备之间激活 ActiveSync 连接。
本文包含的应用程序示例在 Form_Load 事件中建立与设备的连接。要连接到设备,请使用 RAPI 类的 Connect 方法。如以下代码所示,紧接着检查 RAPI 类的 DevicePresent 属性,以验证连接是否成功。
' 连接到设备。
myrapi.Connect()
Do While Not myrapi.DevicePresent
MessageBox.Show( "请用 ActiveSync将您的PC机和PDA设备连接好 " , " PDA设备连接失败 " )
myrapi.Connect()
Loop
Catch ex As Exception
MessageBox.Show( "试图连接PDA设备时出错 " & ex.Message, " 连接错误 " )
Application.Exit()
End Try
将文件复制到设备或从设备复制文件
将数据移入或移出设备的一种最简单方法是,在 PC 和设备之间复制文本或 XML 文件。使用 RAPI 演示程序的方法。在移动应用程序中,文本和基于 XML 的文件可作为一种简易方式存储应用程序数据或配置数据。
OpenNETCF.Desktop.Communication 命名空间的 RAPI 类提供了两种方法复制文件:CopyFileToDevice 和 CopyFileFromDevice。这两种方法都将源文件视作第一个变量,将目标文件视作第二个变量。
btnCopyPerform 按钮的单击事件过程实现了这两种方法。究竟是调用 CopyFileToDevice 方法还是调用 CopyFileFromDevice 方法,取决于用户在用户界面组合框中选择的指令。
Try
If (txtCopySource.Text = "" ) Or (txtCopyDestination.Text = "" ) Then
MessageBox.Show( "您必须提供目标和源文件的路径 . " , _
" 文件信息丢失 " )
Exit Sub
End If
Select Case cmbCopyDirection.Text
Case ""
MessageBox.Show( "开始复制文件之前必须选择一个路径 . " , _
"没有选择路径 " )
Exit Sub
Case " from desktop to device "
myrapi.CopyFileToDevice(txtCopySource.Text, txtCopyDestination.Text)
Case " from device to desktop "
myrapi.CopyFileFromDevice(txtCopySource.Text, txtCopyDestination.Text)
End Select
MessageBox.Show( " 文件已经拷贝成功. " , " 拷贝成功 " )
' 处理可能发生的所有错误。
Catch ex As Exception
MessageBox.Show( " 拷贝文件时发生如下错误- " & ex.Message, _
" 拷贝出错 " )
End Try
移动设备中的文件
有时,您可能需要移动或重命名设备中的文件。例如,在将新版本文件复制到设备之前,可能要备份配置文件
OpenNETCF.Desktop.Communication 命名空间的 RAPI 类提供了 MoveDeviceFile方法来移动或重命名文件。和 CopyFile 方法一样,该方法也将源文件视作第一个变量,将目标文件视作第二个变量。
Try
If (txtMoveSource.Text = "" ) Or (txtMoveDestination.Text = "" ) Then
MessageBox.Show( " 您必须提供目标和源文件的路径. " , _
" 文件信息丢失 " )
Exit Sub
End If
myrapi.MoveDeviceFile(txtMoveSource.Text, txtMoveDestination.Text)
MessageBox.Show( " 文件移动成功. " , "移动 成功 " )
' 处理可能发生的所有错误。
Catch ex As Exception
MessageBox.Show( "移动文件时发生如下错误: " & ex.Message, _
" 剪切出错 " )
End Try
删除设备中的文件
很多时候,您会发现 RAPI 复制文件方法要与删除文件方法一同使用。例如,您可能要求桌面应用程序对应用程序用于存储设备数据的文件进行复制,然后在成功完成复制任务后,返回并从设备中删除文件,以便移动应用程序再次收集新的数据。
OpenNETCF.Desktop.Communication 命名空间的 RAPI 类提供了 DeleteDeviceFile 方法来删除设备文件。要删除的文件是该方法的第一个变量。
Try
If (txtDeleteFile.Text = "" ) Then
MessageBox.Show( "您必须提供要删除的文件的路径 . " , _
" 没有提供文件路径 " )
Exit Sub
End If
myrapi.DeleteDeviceFile(txtDeleteFile.Text)
MessageBox.Show( " 文件删除成功. " , " 删除成功 " )
' 处理可能发生的所有错误。
Catch ex As Exception
MessageBox.Show( " 删除文件时发生如下错误 " & ex.Message, _
"删除错误 " )
End Try
本文就主要介绍这几个功能,更多内容请查看MSDN相关文档。
欢迎留言交流Mobile开发技术。接受C#.NET VB.NET 两种语言。
对于windows mobile sql 中的sdf文件,很多朋友都会用到。方法也很简单。同PC上操作SQL server,Oracle等都差不多。
下面共享一个操作SDF数据库文件的一个类,供Mobile开发新入门的朋友参考。欢迎留言进行交流。
在用此代码之前,需要 using System.Data.SqlServerCe;
{
public void ConnOpen(SqlCeConnection Conn)
{
if (Conn.State.ToString().Trim().Equals("Open"))
{
Conn.Close();
}
Conn.Open();
}
public void ConnClose(SqlCeConnection Conn)
{
if (Conn.State.ToString().Trim().Equals("Open"))
{
Conn.Close();
}
}
public void ExecuteSql(string sql, SqlCeConnection Conn)
{
SqlCeCommand MyCommand = new SqlCeCommand(sql, Conn);
MyCommand.ExecuteNonQuery();
Conn.Close();
}
public SqlCeDataReader GetDataReader(string strCMD, SqlCeConnection Conn)
{
SqlCeDataReader myReader;
SqlCeCommand mycommand = new SqlCeCommand();
mycommand.CommandText = strCMD;
mycommand.Connection = Conn;
myReader = mycommand.ExecuteReader();
return myReader;
}
}
请看下面的代码(实在懒的写太多的话了^_^)
Private Const IOCTL_HAL_GET_DEVICEID As Int32 = 16842836
Public Function GetSerialNumberFromKernelIoControl() As String
Dim dwOutBytes As Integer
Dim nBuffSize As Integer
Dim strDeviceId As String
nBuffSize = 4096
Dim arrOutBuff(4096) As Byte
Dim res As Boolean
res = KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, 0, arrOutBuff, nBuffSize, dwOutBytes)
If res <> False Then
MsgBox(res.ToString)
MsgBox(dwOutBytes.ToString)
Dim strDeviceInfo As String = ""
Dim i As Integer
Dim strNextChar As String = ""
For i = 1 To dwOutBytes
strNextChar = arrOutBuff(i).ToString
strDeviceInfo = strDeviceInfo + strNextChar
Next
strDeviceId = strDeviceInfo
Return strDeviceId
End If
End Function
再添加一个c#版的
{
[DllImport("coredll.dll")]
private static extern bool KernelIoControl(Int32 IoControlCode, IntPtr
InputBuffer, Int32 InputBufferSize, byte[] OutputBuffer, Int32
OutputBufferSize, ref Int32 BytesReturned);
private static Int32 FILE_DEVICE_HAL = 0x00000101;
private static Int32 FILE_ANY_ACCESS = 0x0;
private static Int32 METHOD_BUFFERED = 0x0;
private static Int32 IOCTL_HAL_GET_DEVICEID =
((FILE_DEVICE_HAL) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((21) << 2) | (METHOD_BUFFERED);
private static string GetDeviceID()
{
byte[] OutputBuffer = new byte[256];
Int32 OutputBufferSize, BytesReturned;
OutputBufferSize = OutputBuffer.Length;
BytesReturned = 0;
// Call KernelIoControl passing the previously defined
// IOCTL_HAL_GET_DEVICEID parameter
// We don't need to pass any input buffers to this call
// so InputBuffer and InputBufferSize are set to their null
// values
// 运行上面定义的函数 KernelIoControl
// 并传递前面已经定义了的静态变量作为参数
// 我们不需要输入任何缓存到这个函数
// 因此InputBuffer和InputBufferSize两个形参传递实参null
bool retVal = KernelIoControl(IOCTL_HAL_GET_DEVICEID,
IntPtr.Zero,
0,
OutputBuffer,
OutputBufferSize,
ref BytesReturned);
// If the request failed, exit the method now
// 如果请求失败,立刻退出方法
if (retVal == false)
{
return null;
}
// Examine the OutputBuffer byte array to find the start of the
// Preset ID and Platform ID, as well as the size of the
// PlatformID.
//检查输出数组缓存去寻找 Platform ID以及PlatformID.
// PresetIDOffset -The number of bytes the preset ID is offset
// from the beginning of the structure
// PlatformIDOffset - The number of bytes the platform ID is
// offset from the beginning of the structure
// PlatformIDSize - The number of bytes used to store the
// platform ID
// Use BitConverter.ToInt32() to convert from byte[] to int
Int32 PresetIDOffset = BitConverter.ToInt32(OutputBuffer, 4);
Int32 PlatformIDOffset = BitConverter.ToInt32(OutputBuffer, 0xc);
Int32 PlatformIDSize = BitConverter.ToInt32(OutputBuffer, 0x10);
//将Preset ID转换成string便于显示
// Convert the Preset ID segments into a string so they can be
// displayed easily.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append
(
String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-",
BitConverter.ToInt32(OutputBuffer, PresetIDOffset),
BitConverter.ToInt16(OutputBuffer, PresetIDOffset + 4),
BitConverter.ToInt16(OutputBuffer, PresetIDOffset + 6),
BitConverter.ToInt16(OutputBuffer, PresetIDOffset + 8))
);
//将Platform ID分解成16进制的数字附加到Preset ID上
//这将形成一个格式化了的Device ID字符串
// Break the Platform ID down into 2-digit hexadecimal numbers
// and append them to the Preset ID. This will result in a
// string-formatted Device ID
for (int i = PlatformIDOffset;
i < PlatformIDOffset + PlatformIDSize;
i++)
{
sb.Append(String.Format("{0:X2}", OutputBuffer[i]));
}
// return the Device ID string
//返回Device ID字符串
return sb.ToString();
}
}