ActiveSync编程总结(四)

Question & Answer

问题1ActiveSync manager如何识别出由来自设备的数据创建出来的一个新桌面端对象?

回答:IReplObjHandler::SetPacket一定创建一个新的HREPLITEM句柄,并把结构REPLSETUP的成员hItem设置成它,传入IReplObjHandler::Setup调用。典型的,ActiveSync provider在调用IReplObjHandler::Setup过程中把指针(HREPLITEM?)存入REPLSETUP。注意读取和写入这个store可以同时发生。另外,在IReplObjHandler::Reset被调用之前,IReplObjHandler::Setup会被调用两次。一个IReplObjHandler::Setup调用也许用于读取,另一个用于写入。因此ActiveSync provider必须保持REPLSETUP指针指向IReplObjHandler::Setup

问题2ActiveSync manager如何表示出由来自桌面的数据创建出的新的设备对象?

回答:设备端IReplObjHandler::SetPacket的实现一定会在REPLSETUP::oidNew中签署新对象的object ID,这个ID被发送到桌面和ActiveSync manager使用桌面对象来维持它的映射

问题3:你如何自动处理冲突和避免冲突处理对话框的显示?

IReplStore::GetConflictInfo能够返回一个指定的错误代码,寻求细节请参考章节“冲突处理”

问题4:设备端的一个改变有可能造成桌面端的一个删除,这是怎么实现的?

IReplObjHandler::SetPacket能够返回一个指定的错误码,寻求细节请参考发送和接收对象一章

问题5ActiveSync manager如何知道桌面store实时的变化呢?

回答:某些情况下,当设备正在连接时,对于用户来说切换到桌面store是可能的。例如:在Stock Protfolio例子中,用户能够用包含了一个不同数据设置的文件来覆盖原有的数据文件。这些情况下,提示用户作一个压缩/交换,因为新的store不再映射到任何设备端的对象。这能够在IReplStore::IsFolderChanged函数中通过返回RERR_STORE_REPLACED来被实现

问题6:对桌面端store的同时读写是可能的吗?

是的,一个ActiveSync provider必须维护俩指针指向不同的REPLSETUP结构,而且,同一时间,只有一个对象能够被读,而另一个对象能够被写。如果有多个读或写动作将会导致问题

问题7:你能够使用transaction来写多个对象吗?(transaction:事务,数据库可以用这个来同时读写一批操作)

是的,如果多个设备对象需要同步到桌面,而且如果桌面应用程序支持事务处理,有时会让人满意的(照顾到性能和可靠性)来在一个事务处理中写多个对象。ActiveSync provider能够通过实现IReplStore::ReportStatus来实现这个。这个事务处理在RSC_BEGIN_BATCH_WRITE开始,在RSC_END_BATCH_WRITE处结束

问题8:你是如何阻止一个对象被标记为改变,在它作为一个同步的结果,被写入到桌面store之后?

当一个设备对象被完全写入到桌面store时,ActiveSync manager调用IReplStore::UpdateItemActive Provider将打开这个对象并(使用IReplStore::IsItemChanged中它使用的,典型的是一个时间戳或一个改变序列号)更新这个给定的HREPLITEM句柄,这阻止了在桌面端对象被标记为改变

问题9 如果一个桌面对象在它被同步之后又一次被快速改变了,该怎么办

当一个对象被发送到设备,ActiveSync manager等待来自设备的确认,这个对象在清除桌面端标记为被改变标志之前,已经被成功同步了。因此,如果设备在写入对象时出现问题,这个对象的同步在下一次同步时会再次尝试。而且,可能一个对象会被再次改变在确定到达桌面之前。这种情况下,ActiveSync管理器需要保持这个对象“脏”的,这在IReplStore::IsItemChanged方法中被实现。上面这个例子中传入这个函数的最后一个参数需要设置为NULLActiveSync provider将会打开当前的对象并且比较时间戳,如果当前对象已经被改变,返回true

问题10。如果由一个ActiveSync provider定义的同步过滤器和当前日期有关,那么当日期改变了过滤器如何被再次应用呢?

回答:一个这类过滤器的典型例子是这样的:同步仅同步三天之内的appointments。如果设备被连接并且日期已经改变,比如凌晨或者用户改变了当前日期和时间,所有的appointment必须在过滤器中被重新评估,无论何时这样的日期改变发生,ActiveSync manager为每个和所有对象使用参数RSC_DATE_CHANGED调用IReplStore::ReportStatus。一个ActiveSync provider典型地会在给定的HREPLITEM中重置一个位描述符,以便当IReplStore::IsItemReplicated迟些时候被调用时,这个法则将会被重新评估...

问题11 你如何关闭和重新启动ActiveSync manager

运行:syncmgr.exe/quit,优雅地关闭ActiveSync manager。运行“syncmgr.exe/show”重新启动ActiveSync manager并且让ActiveSync状态窗口可见。运行“syncmgr.exe”简单地启动ActiveSync manager,但不显示ActiveSync状态窗口

问题12:为什么选项按钮,在ActiveSync选项对话框中,对于断开连接的设备失效?

回答:一个普通的错误将会让IReplStore::GetStoreInfo返回任何错误码,当IReplStore::Initialize没被调用的情况下。正确的实现会返回NOERRORSTOREINFO的每个成员中,除非Store ID被设置,一个ActiveSync provider典型地会在IReplStore::Initialize中设置一个标记位,并且在IReplStore::GetStoreInfo中检查它

问题13:如果ActiveSync provider支持实时通知,为什么objects不在ActiveSync状态窗口中接着就显示变化或删除?

你也许已经实现了IReplStore::IsFolderChanged来设置*pfChangedFALSE,你需要设置它为*pfChangedIReplStore::IsFOlderChanged第一次被调用的时候,参考章节“列举对象”来获得更多细节

问题14:如果ActiveSync provider不支持实时通知,对象的变化和删除是如何被探测到的?

变化和删除是在 列举所有存储中的对象时并且检查每个来看是否它被改变 被探测到的,这个检查过程将在同步开始之前就启动 或者它可以在每个指定时间间隙执行一次。这个间隙在STOREINFO::uTimerRes中被设置为毫秒级别,这个过程使用和应用程序相同的资源?并且不会在应用程序忙的时候被启动。一个ActiveSync provider能够设置STOREINFO::uTimerRes-1,那么无论何时当ActiveSync状态窗口被激活,例如:当用户点击状态窗口时,他就合理地假定使用这些数据的应用程序不忙,并且ActiveSync管理器能够调用这个列举动作(看来就是说 manager通过两种方法:非实时状态下靠列举和实时状态下靠通知)

问题15.一个对象在设备端被删除,并且用户删除了对应的桌面端对象,为什么对象保持了显示的最新状态?

一定有一种非正常的状态:当一个设备连接时,ActiveSync manager不能探测到删除。ActiveSync provider将实现IREplStore::IsValidObject来检查通过给定的句柄来表示的对象,如果这个对象不再存在了,返回RERR_OBJECT_DELETED,它也可以返回RERR_CORRUPT来显示一个错误的根本不代表任何对象的句柄

问题16.IReplStore::RemoveDuplicates被调用,那么ActiveSync provider会删除一些桌面端的store中的对象。它是如何询问ActiveSync manager来重新启动同步动作来发现那个探测的呢?

IReplStore::RemoveDuplicates中返回RERR_RESTART导致ActiveSync manager再次去启动同步处理,返回任何其他错误码会导致ActiveSync manager在下一个同步动作完成后去调用IReplStore::RemoveDuplicates

问题17,你如何阻止ActiveSync管理者来展示标准的“初始化了%s,同步服务没有成功,错误:%x,错误消息对话框的

问题18 你是如何标记,当读取一个对象时的最后(或仅有的)的包的

返回RWRN_LAST_PACKETIReplObjHandler::GetPacket

问题19 一个ActiveSync provider是怎样知道同步动作的启动和结束的?

IReplStore::ReportStatus带着RSC_BEGIN_SYNC被调用,当同步结束时它会被使用RSC_END_SYNC参数调用

问题20 当一个设备上的对象在被写入或者删除的时候失败时,你如何获取一个错误代码

IReplStore::ReportStatus使用RSC_WRITE_OBJ_FAILED参数被调用,在一个对象写入设备失败时;...

问题21 一个ActiveSync provider如何知道是否它需要处理一个连接的还是选中的设备?(注意设备的两种状态:连接和选中)

IReplStore::Initialize被调用时,uFlags被设置为ISF_SELECTED_DEVICE如果并且只有设备没有连接(那表示,用户选择了一个非连接的设备profile在移动设备文件夹中的),如果这个标记没有被设置,设备必须被连接。一个ActiveSync provider也能够调用IReplNotify::QueryDeviceQDC_CON_DEVICE_KEY,&hKey),如果这个调用成功,那就是一个连接的设备,否则就是不连接的

问题22 你如何获取那些注册表值(在这些值中存储了一个ActiveSync provider的选项)

调用IReplNotify::QueryDevice(QDC_CON_DEVICE_KEY,&hKey)用于一个连接的设备或者调用IReplNotify::QueryDevice(QDC_SEL_DEVICE_KEY,&hKey)用于一个选中的或者非连接的设备

问题23 你如何获取一个设备名

调用IReplNotify::QueryDevice(QDC_CON_DEVICE,&devInfo)用于一个连接的设备,或者调用IReplNotify::QUeryDevice(QDC_SEL_DEVICE,&devInfo)用于一个选中或者非连接的设备DEVINFO::szName是这个设备的名称

问题24 桌面ActiveSync provider需要做什么来支持多个设备的同步...

问题25 设备ActiveSync provider需要做什么来支持两个桌面计算机的同步?

设备ActiveSync provider需要把uPartnetBit传入InitObjType并且使用它来设置或重置一个同步对象的dirty

问题26 IReplStore的参考计数没有到达0,那么 provider不能被释放,为什么?

问题27 IReplObjHandler::SetPacket中,桌面ActiveSync provider如何知道是否它是一个新对象或者不是?

IReplObjHandler::Setup调用时RSF_NEW_OBJECT将会被设置在REPLSETUP::dwFlags

问题29 IReplObjHandler::SetPacket中,设备ActiveSyncgognzheruhe知道一个对象是否是新的?

它可以调用CeGetOidInfoREPLSETUP::oid参数,如果是新的设备对象会导致失败

问题30 在桌面端的IReplObjHandler::SetPacket被调用时,一个不同的对象也许改变或者创建了,你怎么告诉ActiveSync管理者去再次同步,因此这个对象将被发现?

作为一个例子,当一个新的使用生日的连接被写入到桌面store,一个重现的约会也许自动创建了,如果ActiveSync provider支持实时通知,这个变化将会被自动发现。否则,ActiveSync provider需要调用

IReplNotify::OnItemNotify使用storeProgID和改变了或者刚创建的对象类型。HREPLITEM能够被传递一个NULL

问题31,当设备端ActiveSync provider将被结束时,它如何通知ActiveSync manager后来再试呢?

如果ActiveSync provider不能立刻结束它自己,当InitObjType(NULL,NULL,0)被调用,他能够返回

False,ActiveSync manager将尝试在两秒钟内去结束 provider,它将保持最多15分钟之内。这对于某种ActiveSync provider来说很有必要,它们必须标记并等待一个工作者线程的结束

问题32 ActiveSync provider支持多个对象类型的同步,如何让IReplStore::Initialize知道哪种类型被激活了,因此它就不必浪费时间去让对象类型失效了

在调用IReplStore::Initialize之前,ActiveSync用参数RSC_OBJ_TYPE_ENABLED调用IReplStore::ReportStatus,...

问题33 在安装ActiveSync模块的程序中,如何关闭ActiveSync manager,让他不再加载模块?

当你安装程序要去安装或更新ActiveSync模块的时候,需要先关闭ActiveSync manager来让他释放掉已经存在于内存中的ActiveSync模块,然后你才能覆盖你需要更新的模块。你能通过运行“syncmgr.exe/quit”关闭ActiveSync manager,你通过“syncmgr.exe /quit,你可以通过运行“syncmgr.exe /show”来重新启动ActiveSync manager,以带着窗口的方式。或者使用sysncmgr.exe启动一个不带状态窗口的ActiveSync manager,详细参考附录中的“syncmgr.exe允许的命令行参数”

问题34 CE文件ActiveSync provider支持挂载的卷标吗?比如闪存?

目前不支持

附录

微软ActiveSync服务 provider列表

微软winCE服务2.1版提供了一系列的ActiveSync provider

provider名称  桌面provider   桌面provider基地址  设备 provider   支持的对象类型

Outlook同步   outstore.dll       0x22000000           pegobj.dll          Appointment

                                                                                                Contacts

                                                                                                 Inbox

                                                                                                 Task

Schedule+同步  scdstore.dll    0x20000000           pegobj.dll          Appointment

                                                                                                 Contackts

                                                                                                 Task

WinCE文件同步cefstore.dll   0x23000000            cefobj.dll          File

移动通道同步   aafstore.dll   0x24000000            aafobj.dll           Channel

Syncmgr.exe的合法命令行参数

syncmgr.exe是一个ActiveSync manager的执行体,它包含了一系列参数,你能够传入这个程序不止一个参数,你甚至在它已经运行的情况下携带参数运行syncmgr.exe。下面是参数列表

参数                                             含义

/quit                   当设备连接处于激活状态时关闭ActiveSync manager,这对于调试很重要,因为所有的ActiveSync模块都将被卸载,你不需要物理上断开设备

/show               

/synconcon        在需要的时候启动ActiveSync manager,并检查“连接中的同步”设置,如果该设置开启了,在同设备连接的时候立即启动同步,没有这个参数...

/syncmgr           启动ActiveSync时显示选项对话框

/syncnow         启动ActiveSync并立刻同步数据

你可能感兴趣的:(编程,manager,object,null,WinCE,文件同步)